feat: live stack-state injection via agent harness hook (#304) - #306

Merged
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook
Aug 22, 2026
Merged

feat: live stack-state injection via agent harness hook (#304)#306
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook

Conversation

@aarontrowbridge

@aarontrowbridgeaarontrowbridge commented Aug 9, 2026

Copy link
Copy Markdown
Member

Implements #304.

Adds a second opencode plugin (amicode_context.ts) implementing experimental.chat.system.transform that reads live state on every prompt build and injects it as the final system[] entry.

Scope (expanded 2026-08-21): the original WIP moved solver mode + routing off the boot-time file splice. This update finishes the job — the fleet line and the user-memory sections (profile, recent problems, reference demos, mount stack, memory index) also move to the live hook. Motivation: the boot-time splices were the "Amicode forgets the fleet" bug class — a hand-maintained server bundle (the canonical launchd server's staging dir) or a stale re-prep served yesterday's memory index and yesterday's solver mode to every new session (observed: 10-entry index frozen at Aug 16 vs 18 live; cloud-HP solver instructions served after the user switched back to Piccolo).

Key changes:

  • opencode-plugin/stack_state.ts — standalone state readers + markdown builders (node-builtins only for Bun runtime): solver mode, routing, active problem, live runs (original WIP) + NEW lean fleet line (~/.amico/ops/fleet/fleet.json role, fleet-status.json devices/freshness with stale/unreadable degradation, on-demand pointers — absent fleet.json renders nothing) + NEW marker-only Armonia mount discovery (smol-toml-free port of mount_store semantics: kind ranks, duplicate-id skip, kind-rank ordering) and the five user-memory sections read live from the personal vault, section text byte-identical to the retired substrate/user_splice.ts builders. No mounts.toml manifest support (smol-toml unavailable in Bun; no manifest exists in practice — documented in-module).
  • opencode-plugin/amicode_context.ts — the plugin, single export, one hook (unchanged)
  • src/opencode_config.ts — solver/routing AND the user-memory/mount/memory-index splices removed from prepareOpencodeProject (the latter previously the only injector); buildOpencodeConfigContent accepts extraPluginPaths (original WIP)
  • src/extension.ts — boot + solver-switch register the context plugin; solver-switch projectDir asymmetry fixed (original WIP)
  • packages/extension/AGENTS.md — single broadened recovery pointer (template tail) covering solver mode, routing, fleet, and the vault files; replaces the WIP's programmatic append (was duplicated)
  • Deletedsubstrate/user_splice.ts + the now-dead vault_store index readers (KNOWLEDGE/DEMOS/MEMORY) — the plugin owns that text now, pinned golden in test/stack_state.test.ts (14 cases: fleet rendering + degradation, mount discovery incl. duplicate/marker-less skips, section text parity with the retired builders, caps 50/30/50, splice-parity section order, hermetic env-seam composition). solverModeSection/routingSection deliberately stay as the original WIP's parity oracles (test-only) — noted asymmetry, reviewer's call whether to fold them into stack_state pins too.
  • test/packaging.test.ts — pins amicode_context.ts + stack_state.ts as must-ship vsix assets.

Hook support verified against the deployed fork binary: experimental.chat.system.transform is typed (packages/plugin/src/index.ts:291), triggered (agent/agent.ts:381), and the frozen canonical server binary contains the hook string. Silent no-op remains the failure mode if a binary lacks it — which is why the recovery pointer exists.

Deployment sequencing (the canonical launchd server serves a hand-staged bundle):

  1. Merge + release a vsix carrying the plugin files (the server config's existing amicode_context.ts reference — dead since it was added — goes live the moment the newest installed vsix ships it).
  2. Restart the canonical server (it resolves __EXT__ to the newest vsix at boot).
  3. Strip the now-duplicated static sections (About this user / recent problems / reference demos / mount stack / memory index) from the staged ~/.amico/server/opencode-project-staging/opencode-project/AGENTS.md — until then they render twice (harmless, just noisy).

Verification: tsc --noEmit clean; full extension suite 1186 passed / 5 skipped / 100 files.

Summary by CodeRabbit

  • New Features

    • Added live context injection for solver status, routing, fleet information, active work, profile data, and relevant memory.
    • Context updates automatically during startup and solver-mode restarts.
    • Added support for discovering and prioritizing available data sources.
  • Bug Fixes

    • Missing, malformed, or unavailable data is handled gracefully without interrupting prompt generation.
    • Prevented stale context from being embedded in persistent project instructions.
  • Tests

    • Expanded coverage for context composition, data discovery, ordering, limits, and graceful degradation.
    • Updated packaging and integration checks for the new context functionality.

@aarontrowbridgeaarontrowbridge linked an issue Aug 9, 2026 that may be closed by this pull request
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a91ada6 to a37166aCompareAugust 20, 2026 08:48
@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22e859f7-5049-4d1c-8401-dc55e00e9fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 324a5ec and 8d39f63.

📒 Files selected for processing (12)
  • packages/extension/AGENTS.md
  • packages/extension/opencode-plugin/amicode_context.ts
  • packages/extension/opencode-plugin/stack_state.ts
  • packages/extension/src/extension.ts
  • packages/extension/src/opencode_config.ts
  • packages/extension/src/substrate/user_splice.ts
  • packages/extension/src/substrate/vault_store.ts
  • packages/extension/test/packaging.test.ts
  • packages/extension/test/scores/prep_integration.test.ts
  • packages/extension/test/stack_state.test.ts
  • packages/extension/test/substrate/user_splice.test.ts
  • packages/extension/test/substrate/vault_store.test.ts

📝 Walkthrough

Walkthrough

The extension now injects live solver, fleet, problem, routing, and personal-vault context into OpenCode prompts. Startup no longer splices this data into AGENTS.md. New stack-state readers, plugin wiring, packaging checks, and tests support the change.

Changes

Live context injection

Layer / File(s)Summary
Stack-state collection and rendering
packages/extension/opencode-plugin/stack_state.ts, packages/extension/test/stack_state.test.ts
The new builder reads operational state and vault data, discovers mounts, renders ordered markdown sections, applies content caps, and handles missing or malformed files.
OpenCode plugin wiring
packages/extension/opencode-plugin/amicode_context.ts, packages/extension/src/opencode_config.ts, packages/extension/src/extension.ts, packages/extension/AGENTS.md, packages/extension/test/packaging.test.ts
The plugin appends live context during system-prompt transformation. Initial and restart configurations register the plugin, and packaged assets include its runtime files.
Startup splice removal and migration coverage
packages/extension/src/substrate/vault_store.ts, packages/extension/src/opencode_config.ts, packages/extension/test/scores/prep_integration.test.ts
Startup writes only compiled AGENTS.md content. Obsolete user-memory readers and splice helpers are removed. Integration tests verify live injection and recovery-pointer behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers:rchari1

Sequence Diagram(s)

sequenceDiagram
participant Extension
participant OpenCode
participant AmicodeContext
participant LocalState
participant PersonalVault
Extension->>OpenCode: register Amico context plugin
OpenCode->>AmicodeContext: transform system prompt
AmicodeContext->>LocalState: read live solver and fleet state
AmicodeContext->>PersonalVault: read profile, problems, demos, mounts, and memory
AmicodeContext-->>OpenCode: append generated context
``
</details>
<!-- walkthrough_end -->
<!-- finishing_touch_checkbox_start -->
<details>
<summary>✨ Finishing Touches</summary>
<details>
<summary>📝 Generate docstrings</summary>
- [ ] <!-- {"checkboxId":"7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId":"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch
</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>
- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `304-feat-live-stack-state-injection-via-agent-harness-hook`
</details>
</details>
<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->
---
<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>
<!-- tips_end -->
Loading

Adds a second opencode plugin (amicode_context.ts) implementing
experimental.chat.system.transform that reads solver mode, routing,
active problem, and live runs on every prompt build and injects them
as the final system[] entry.
- opencode-plugin/stack_state.ts — standalone state readers + builders
- opencode-plugin/amicode_context.ts — system.transform hook plugin
- src/opencode_config — removed solver/routing from file splice;
buildOpencodeConfigContent accepts extraPluginPaths param
- src/extension.ts — registers context plugin in boot + solver-switch;
fixes mkdtemp asymmetry in solver-switch re-prep
- AGENTS.md — one-line recovery pointer appended
Closes#304.
Extends the amicode_context plugin's system.transform injection so the
sections that went stale as boot-time file splices are read LIVE from
disk on every prompt build:
- stack_state.ts: lean fleet line (role from fleet.json, devices +
freshness from fleet-status.json, on-demand pointers) — absent
fleet.json renders nothing; marker-only Armonia mount discovery
(smol-toml-free port of mount_store semantics: kind ranks, duplicate
skip, kind-rank order) + the user-memory sections (profile, recent
problems, reference demos, mount stack, memory index) read from the
personal vault, section text byte-identical to the retired
substrate/user_splice.ts builders (pinned golden in
test/stack_state.test.ts, 14 cases incl. caps + splice-parity order)
- opencode_config.ts: the boot-time user-memory/mount/memory splices
are REMOVED (they were the staleness bug: hand-maintained server
bundles and re-prepped project dirs served yesterday's memory index);
the template AGENTS.md carries the single broadened recovery pointer
(replaces the programmatic append — was duplicated)
- user_splice.ts + vault_store's now-dead index readers deleted;
solverModeSection/routingSection stay as the WIP's parity oracles
- packaging.test.ts pins amicode_context.ts + stack_state.ts as
must-ship vsix assets (the server config's dead reference goes live
the moment a vsix carries them)
Closes the 'Amicode forgets the fleet' class: a distiller write, a
solver switch, or a vault sync reaches the next message without a
re-prep or server restart.
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a37166a to 8d39f63CompareAugust 21, 2026 13:26
@aarontrowbridge
aarontrowbridge marked this pull request as ready for review August 22, 2026 21:30
@aarontrowbridge
aarontrowbridge merged commit f0f5887 into mainAug 22, 2026
7 of 8 checks passed
@aarontrowbridge
aarontrowbridge deleted the 304-feat-live-stack-state-injection-via-agent-harness-hook branch August 22, 2026 21:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: live stack-state injection via agent harness hook

1 participant

@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: live stack-state injection via agent harness hook (#304) - #306

Merged
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook
Aug 22, 2026
Merged

feat: live stack-state injection via agent harness hook (#304)#306
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook

Conversation

@aarontrowbridge

@aarontrowbridgeaarontrowbridge commented Aug 9, 2026

Copy link
Copy Markdown
Member

Implements #304.

Adds a second opencode plugin (amicode_context.ts) implementing experimental.chat.system.transform that reads live state on every prompt build and injects it as the final system[] entry.

Scope (expanded 2026-08-21): the original WIP moved solver mode + routing off the boot-time file splice. This update finishes the job — the fleet line and the user-memory sections (profile, recent problems, reference demos, mount stack, memory index) also move to the live hook. Motivation: the boot-time splices were the "Amicode forgets the fleet" bug class — a hand-maintained server bundle (the canonical launchd server's staging dir) or a stale re-prep served yesterday's memory index and yesterday's solver mode to every new session (observed: 10-entry index frozen at Aug 16 vs 18 live; cloud-HP solver instructions served after the user switched back to Piccolo).

Key changes:

  • opencode-plugin/stack_state.ts — standalone state readers + markdown builders (node-builtins only for Bun runtime): solver mode, routing, active problem, live runs (original WIP) + NEW lean fleet line (~/.amico/ops/fleet/fleet.json role, fleet-status.json devices/freshness with stale/unreadable degradation, on-demand pointers — absent fleet.json renders nothing) + NEW marker-only Armonia mount discovery (smol-toml-free port of mount_store semantics: kind ranks, duplicate-id skip, kind-rank ordering) and the five user-memory sections read live from the personal vault, section text byte-identical to the retired substrate/user_splice.ts builders. No mounts.toml manifest support (smol-toml unavailable in Bun; no manifest exists in practice — documented in-module).
  • opencode-plugin/amicode_context.ts — the plugin, single export, one hook (unchanged)
  • src/opencode_config.ts — solver/routing AND the user-memory/mount/memory-index splices removed from prepareOpencodeProject (the latter previously the only injector); buildOpencodeConfigContent accepts extraPluginPaths (original WIP)
  • src/extension.ts — boot + solver-switch register the context plugin; solver-switch projectDir asymmetry fixed (original WIP)
  • packages/extension/AGENTS.md — single broadened recovery pointer (template tail) covering solver mode, routing, fleet, and the vault files; replaces the WIP's programmatic append (was duplicated)
  • Deletedsubstrate/user_splice.ts + the now-dead vault_store index readers (KNOWLEDGE/DEMOS/MEMORY) — the plugin owns that text now, pinned golden in test/stack_state.test.ts (14 cases: fleet rendering + degradation, mount discovery incl. duplicate/marker-less skips, section text parity with the retired builders, caps 50/30/50, splice-parity section order, hermetic env-seam composition). solverModeSection/routingSection deliberately stay as the original WIP's parity oracles (test-only) — noted asymmetry, reviewer's call whether to fold them into stack_state pins too.
  • test/packaging.test.ts — pins amicode_context.ts + stack_state.ts as must-ship vsix assets.

Hook support verified against the deployed fork binary: experimental.chat.system.transform is typed (packages/plugin/src/index.ts:291), triggered (agent/agent.ts:381), and the frozen canonical server binary contains the hook string. Silent no-op remains the failure mode if a binary lacks it — which is why the recovery pointer exists.

Deployment sequencing (the canonical launchd server serves a hand-staged bundle):

  1. Merge + release a vsix carrying the plugin files (the server config's existing amicode_context.ts reference — dead since it was added — goes live the moment the newest installed vsix ships it).
  2. Restart the canonical server (it resolves __EXT__ to the newest vsix at boot).
  3. Strip the now-duplicated static sections (About this user / recent problems / reference demos / mount stack / memory index) from the staged ~/.amico/server/opencode-project-staging/opencode-project/AGENTS.md — until then they render twice (harmless, just noisy).

Verification: tsc --noEmit clean; full extension suite 1186 passed / 5 skipped / 100 files.

Summary by CodeRabbit

  • New Features

    • Added live context injection for solver status, routing, fleet information, active work, profile data, and relevant memory.
    • Context updates automatically during startup and solver-mode restarts.
    • Added support for discovering and prioritizing available data sources.
  • Bug Fixes

    • Missing, malformed, or unavailable data is handled gracefully without interrupting prompt generation.
    • Prevented stale context from being embedded in persistent project instructions.
  • Tests

    • Expanded coverage for context composition, data discovery, ordering, limits, and graceful degradation.
    • Updated packaging and integration checks for the new context functionality.

@aarontrowbridgeaarontrowbridge linked an issue Aug 9, 2026 that may be closed by this pull request
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a91ada6 to a37166aCompareAugust 20, 2026 08:48
@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22e859f7-5049-4d1c-8401-dc55e00e9fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 324a5ec and 8d39f63.

📒 Files selected for processing (12)
  • packages/extension/AGENTS.md
  • packages/extension/opencode-plugin/amicode_context.ts
  • packages/extension/opencode-plugin/stack_state.ts
  • packages/extension/src/extension.ts
  • packages/extension/src/opencode_config.ts
  • packages/extension/src/substrate/user_splice.ts
  • packages/extension/src/substrate/vault_store.ts
  • packages/extension/test/packaging.test.ts
  • packages/extension/test/scores/prep_integration.test.ts
  • packages/extension/test/stack_state.test.ts
  • packages/extension/test/substrate/user_splice.test.ts
  • packages/extension/test/substrate/vault_store.test.ts

📝 Walkthrough

Walkthrough

The extension now injects live solver, fleet, problem, routing, and personal-vault context into OpenCode prompts. Startup no longer splices this data into AGENTS.md. New stack-state readers, plugin wiring, packaging checks, and tests support the change.

Changes

Live context injection

Layer / File(s)Summary
Stack-state collection and rendering
packages/extension/opencode-plugin/stack_state.ts, packages/extension/test/stack_state.test.ts
The new builder reads operational state and vault data, discovers mounts, renders ordered markdown sections, applies content caps, and handles missing or malformed files.
OpenCode plugin wiring
packages/extension/opencode-plugin/amicode_context.ts, packages/extension/src/opencode_config.ts, packages/extension/src/extension.ts, packages/extension/AGENTS.md, packages/extension/test/packaging.test.ts
The plugin appends live context during system-prompt transformation. Initial and restart configurations register the plugin, and packaged assets include its runtime files.
Startup splice removal and migration coverage
packages/extension/src/substrate/vault_store.ts, packages/extension/src/opencode_config.ts, packages/extension/test/scores/prep_integration.test.ts
Startup writes only compiled AGENTS.md content. Obsolete user-memory readers and splice helpers are removed. Integration tests verify live injection and recovery-pointer behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers:rchari1

Sequence Diagram(s)

sequenceDiagram
participant Extension
participant OpenCode
participant AmicodeContext
participant LocalState
participant PersonalVault
Extension->>OpenCode: register Amico context plugin
OpenCode->>AmicodeContext: transform system prompt
AmicodeContext->>LocalState: read live solver and fleet state
AmicodeContext->>PersonalVault: read profile, problems, demos, mounts, and memory
AmicodeContext-->>OpenCode: append generated context
``
</details>
<!-- walkthrough_end -->
<!-- finishing_touch_checkbox_start -->
<details>
<summary>✨ Finishing Touches</summary>
<details>
<summary>📝 Generate docstrings</summary>
- [ ] <!-- {"checkboxId":"7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId":"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch
</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>
- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `304-feat-live-stack-state-injection-via-agent-harness-hook`
</details>
</details>
<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->
---
<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>
<!-- tips_end -->
Loading

Adds a second opencode plugin (amicode_context.ts) implementing
experimental.chat.system.transform that reads solver mode, routing,
active problem, and live runs on every prompt build and injects them
as the final system[] entry.
- opencode-plugin/stack_state.ts — standalone state readers + builders
- opencode-plugin/amicode_context.ts — system.transform hook plugin
- src/opencode_config — removed solver/routing from file splice;
buildOpencodeConfigContent accepts extraPluginPaths param
- src/extension.ts — registers context plugin in boot + solver-switch;
fixes mkdtemp asymmetry in solver-switch re-prep
- AGENTS.md — one-line recovery pointer appended
Closes#304.
Extends the amicode_context plugin's system.transform injection so the
sections that went stale as boot-time file splices are read LIVE from
disk on every prompt build:
- stack_state.ts: lean fleet line (role from fleet.json, devices +
freshness from fleet-status.json, on-demand pointers) — absent
fleet.json renders nothing; marker-only Armonia mount discovery
(smol-toml-free port of mount_store semantics: kind ranks, duplicate
skip, kind-rank order) + the user-memory sections (profile, recent
problems, reference demos, mount stack, memory index) read from the
personal vault, section text byte-identical to the retired
substrate/user_splice.ts builders (pinned golden in
test/stack_state.test.ts, 14 cases incl. caps + splice-parity order)
- opencode_config.ts: the boot-time user-memory/mount/memory splices
are REMOVED (they were the staleness bug: hand-maintained server
bundles and re-prepped project dirs served yesterday's memory index);
the template AGENTS.md carries the single broadened recovery pointer
(replaces the programmatic append — was duplicated)
- user_splice.ts + vault_store's now-dead index readers deleted;
solverModeSection/routingSection stay as the WIP's parity oracles
- packaging.test.ts pins amicode_context.ts + stack_state.ts as
must-ship vsix assets (the server config's dead reference goes live
the moment a vsix carries them)
Closes the 'Amicode forgets the fleet' class: a distiller write, a
solver switch, or a vault sync reaches the next message without a
re-prep or server restart.
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a37166a to 8d39f63CompareAugust 21, 2026 13:26
@aarontrowbridge
aarontrowbridge marked this pull request as ready for review August 22, 2026 21:30
@aarontrowbridge
aarontrowbridge merged commit f0f5887 into mainAug 22, 2026
7 of 8 checks passed
@aarontrowbridge
aarontrowbridge deleted the 304-feat-live-stack-state-injection-via-agent-harness-hook branch August 22, 2026 21:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: live stack-state injection via agent harness hook

1 participant

@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: live stack-state injection via agent harness hook (#304) - #306

Merged
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook
Aug 22, 2026
Merged

feat: live stack-state injection via agent harness hook (#304)#306
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook

Conversation

@aarontrowbridge

@aarontrowbridgeaarontrowbridge commented Aug 9, 2026

Copy link
Copy Markdown
Member

Implements #304.

Adds a second opencode plugin (amicode_context.ts) implementing experimental.chat.system.transform that reads live state on every prompt build and injects it as the final system[] entry.

Scope (expanded 2026-08-21): the original WIP moved solver mode + routing off the boot-time file splice. This update finishes the job — the fleet line and the user-memory sections (profile, recent problems, reference demos, mount stack, memory index) also move to the live hook. Motivation: the boot-time splices were the "Amicode forgets the fleet" bug class — a hand-maintained server bundle (the canonical launchd server's staging dir) or a stale re-prep served yesterday's memory index and yesterday's solver mode to every new session (observed: 10-entry index frozen at Aug 16 vs 18 live; cloud-HP solver instructions served after the user switched back to Piccolo).

Key changes:

  • opencode-plugin/stack_state.ts — standalone state readers + markdown builders (node-builtins only for Bun runtime): solver mode, routing, active problem, live runs (original WIP) + NEW lean fleet line (~/.amico/ops/fleet/fleet.json role, fleet-status.json devices/freshness with stale/unreadable degradation, on-demand pointers — absent fleet.json renders nothing) + NEW marker-only Armonia mount discovery (smol-toml-free port of mount_store semantics: kind ranks, duplicate-id skip, kind-rank ordering) and the five user-memory sections read live from the personal vault, section text byte-identical to the retired substrate/user_splice.ts builders. No mounts.toml manifest support (smol-toml unavailable in Bun; no manifest exists in practice — documented in-module).
  • opencode-plugin/amicode_context.ts — the plugin, single export, one hook (unchanged)
  • src/opencode_config.ts — solver/routing AND the user-memory/mount/memory-index splices removed from prepareOpencodeProject (the latter previously the only injector); buildOpencodeConfigContent accepts extraPluginPaths (original WIP)
  • src/extension.ts — boot + solver-switch register the context plugin; solver-switch projectDir asymmetry fixed (original WIP)
  • packages/extension/AGENTS.md — single broadened recovery pointer (template tail) covering solver mode, routing, fleet, and the vault files; replaces the WIP's programmatic append (was duplicated)
  • Deletedsubstrate/user_splice.ts + the now-dead vault_store index readers (KNOWLEDGE/DEMOS/MEMORY) — the plugin owns that text now, pinned golden in test/stack_state.test.ts (14 cases: fleet rendering + degradation, mount discovery incl. duplicate/marker-less skips, section text parity with the retired builders, caps 50/30/50, splice-parity section order, hermetic env-seam composition). solverModeSection/routingSection deliberately stay as the original WIP's parity oracles (test-only) — noted asymmetry, reviewer's call whether to fold them into stack_state pins too.
  • test/packaging.test.ts — pins amicode_context.ts + stack_state.ts as must-ship vsix assets.

Hook support verified against the deployed fork binary: experimental.chat.system.transform is typed (packages/plugin/src/index.ts:291), triggered (agent/agent.ts:381), and the frozen canonical server binary contains the hook string. Silent no-op remains the failure mode if a binary lacks it — which is why the recovery pointer exists.

Deployment sequencing (the canonical launchd server serves a hand-staged bundle):

  1. Merge + release a vsix carrying the plugin files (the server config's existing amicode_context.ts reference — dead since it was added — goes live the moment the newest installed vsix ships it).
  2. Restart the canonical server (it resolves __EXT__ to the newest vsix at boot).
  3. Strip the now-duplicated static sections (About this user / recent problems / reference demos / mount stack / memory index) from the staged ~/.amico/server/opencode-project-staging/opencode-project/AGENTS.md — until then they render twice (harmless, just noisy).

Verification: tsc --noEmit clean; full extension suite 1186 passed / 5 skipped / 100 files.

Summary by CodeRabbit

  • New Features

    • Added live context injection for solver status, routing, fleet information, active work, profile data, and relevant memory.
    • Context updates automatically during startup and solver-mode restarts.
    • Added support for discovering and prioritizing available data sources.
  • Bug Fixes

    • Missing, malformed, or unavailable data is handled gracefully without interrupting prompt generation.
    • Prevented stale context from being embedded in persistent project instructions.
  • Tests

    • Expanded coverage for context composition, data discovery, ordering, limits, and graceful degradation.
    • Updated packaging and integration checks for the new context functionality.

@aarontrowbridgeaarontrowbridge linked an issue Aug 9, 2026 that may be closed by this pull request
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a91ada6 to a37166aCompareAugust 20, 2026 08:48
@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22e859f7-5049-4d1c-8401-dc55e00e9fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 324a5ec and 8d39f63.

📒 Files selected for processing (12)
  • packages/extension/AGENTS.md
  • packages/extension/opencode-plugin/amicode_context.ts
  • packages/extension/opencode-plugin/stack_state.ts
  • packages/extension/src/extension.ts
  • packages/extension/src/opencode_config.ts
  • packages/extension/src/substrate/user_splice.ts
  • packages/extension/src/substrate/vault_store.ts
  • packages/extension/test/packaging.test.ts
  • packages/extension/test/scores/prep_integration.test.ts
  • packages/extension/test/stack_state.test.ts
  • packages/extension/test/substrate/user_splice.test.ts
  • packages/extension/test/substrate/vault_store.test.ts

📝 Walkthrough

Walkthrough

The extension now injects live solver, fleet, problem, routing, and personal-vault context into OpenCode prompts. Startup no longer splices this data into AGENTS.md. New stack-state readers, plugin wiring, packaging checks, and tests support the change.

Changes

Live context injection

Layer / File(s)Summary
Stack-state collection and rendering
packages/extension/opencode-plugin/stack_state.ts, packages/extension/test/stack_state.test.ts
The new builder reads operational state and vault data, discovers mounts, renders ordered markdown sections, applies content caps, and handles missing or malformed files.
OpenCode plugin wiring
packages/extension/opencode-plugin/amicode_context.ts, packages/extension/src/opencode_config.ts, packages/extension/src/extension.ts, packages/extension/AGENTS.md, packages/extension/test/packaging.test.ts
The plugin appends live context during system-prompt transformation. Initial and restart configurations register the plugin, and packaged assets include its runtime files.
Startup splice removal and migration coverage
packages/extension/src/substrate/vault_store.ts, packages/extension/src/opencode_config.ts, packages/extension/test/scores/prep_integration.test.ts
Startup writes only compiled AGENTS.md content. Obsolete user-memory readers and splice helpers are removed. Integration tests verify live injection and recovery-pointer behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers:rchari1

Sequence Diagram(s)

sequenceDiagram
participant Extension
participant OpenCode
participant AmicodeContext
participant LocalState
participant PersonalVault
Extension->>OpenCode: register Amico context plugin
OpenCode->>AmicodeContext: transform system prompt
AmicodeContext->>LocalState: read live solver and fleet state
AmicodeContext->>PersonalVault: read profile, problems, demos, mounts, and memory
AmicodeContext-->>OpenCode: append generated context
``
</details>
<!-- walkthrough_end -->
<!-- finishing_touch_checkbox_start -->
<details>
<summary>✨ Finishing Touches</summary>
<details>
<summary>📝 Generate docstrings</summary>
- [ ] <!-- {"checkboxId":"7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId":"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch
</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>
- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `304-feat-live-stack-state-injection-via-agent-harness-hook`
</details>
</details>
<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->
---
<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>
<!-- tips_end -->
Loading

Adds a second opencode plugin (amicode_context.ts) implementing
experimental.chat.system.transform that reads solver mode, routing,
active problem, and live runs on every prompt build and injects them
as the final system[] entry.
- opencode-plugin/stack_state.ts — standalone state readers + builders
- opencode-plugin/amicode_context.ts — system.transform hook plugin
- src/opencode_config — removed solver/routing from file splice;
buildOpencodeConfigContent accepts extraPluginPaths param
- src/extension.ts — registers context plugin in boot + solver-switch;
fixes mkdtemp asymmetry in solver-switch re-prep
- AGENTS.md — one-line recovery pointer appended
Closes#304.
Extends the amicode_context plugin's system.transform injection so the
sections that went stale as boot-time file splices are read LIVE from
disk on every prompt build:
- stack_state.ts: lean fleet line (role from fleet.json, devices +
freshness from fleet-status.json, on-demand pointers) — absent
fleet.json renders nothing; marker-only Armonia mount discovery
(smol-toml-free port of mount_store semantics: kind ranks, duplicate
skip, kind-rank order) + the user-memory sections (profile, recent
problems, reference demos, mount stack, memory index) read from the
personal vault, section text byte-identical to the retired
substrate/user_splice.ts builders (pinned golden in
test/stack_state.test.ts, 14 cases incl. caps + splice-parity order)
- opencode_config.ts: the boot-time user-memory/mount/memory splices
are REMOVED (they were the staleness bug: hand-maintained server
bundles and re-prepped project dirs served yesterday's memory index);
the template AGENTS.md carries the single broadened recovery pointer
(replaces the programmatic append — was duplicated)
- user_splice.ts + vault_store's now-dead index readers deleted;
solverModeSection/routingSection stay as the WIP's parity oracles
- packaging.test.ts pins amicode_context.ts + stack_state.ts as
must-ship vsix assets (the server config's dead reference goes live
the moment a vsix carries them)
Closes the 'Amicode forgets the fleet' class: a distiller write, a
solver switch, or a vault sync reaches the next message without a
re-prep or server restart.
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a37166a to 8d39f63CompareAugust 21, 2026 13:26
@aarontrowbridge
aarontrowbridge marked this pull request as ready for review August 22, 2026 21:30
@aarontrowbridge
aarontrowbridge merged commit f0f5887 into mainAug 22, 2026
7 of 8 checks passed
@aarontrowbridge
aarontrowbridge deleted the 304-feat-live-stack-state-injection-via-agent-harness-hook branch August 22, 2026 21:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: live stack-state injection via agent harness hook

1 participant

@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: live stack-state injection via agent harness hook (#304) - #306

Merged
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook
Aug 22, 2026
Merged

feat: live stack-state injection via agent harness hook (#304)#306
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook

Conversation

@aarontrowbridge

@aarontrowbridgeaarontrowbridge commented Aug 9, 2026

Copy link
Copy Markdown
Member

Implements #304.

Adds a second opencode plugin (amicode_context.ts) implementing experimental.chat.system.transform that reads live state on every prompt build and injects it as the final system[] entry.

Scope (expanded 2026-08-21): the original WIP moved solver mode + routing off the boot-time file splice. This update finishes the job — the fleet line and the user-memory sections (profile, recent problems, reference demos, mount stack, memory index) also move to the live hook. Motivation: the boot-time splices were the "Amicode forgets the fleet" bug class — a hand-maintained server bundle (the canonical launchd server's staging dir) or a stale re-prep served yesterday's memory index and yesterday's solver mode to every new session (observed: 10-entry index frozen at Aug 16 vs 18 live; cloud-HP solver instructions served after the user switched back to Piccolo).

Key changes:

  • opencode-plugin/stack_state.ts — standalone state readers + markdown builders (node-builtins only for Bun runtime): solver mode, routing, active problem, live runs (original WIP) + NEW lean fleet line (~/.amico/ops/fleet/fleet.json role, fleet-status.json devices/freshness with stale/unreadable degradation, on-demand pointers — absent fleet.json renders nothing) + NEW marker-only Armonia mount discovery (smol-toml-free port of mount_store semantics: kind ranks, duplicate-id skip, kind-rank ordering) and the five user-memory sections read live from the personal vault, section text byte-identical to the retired substrate/user_splice.ts builders. No mounts.toml manifest support (smol-toml unavailable in Bun; no manifest exists in practice — documented in-module).
  • opencode-plugin/amicode_context.ts — the plugin, single export, one hook (unchanged)
  • src/opencode_config.ts — solver/routing AND the user-memory/mount/memory-index splices removed from prepareOpencodeProject (the latter previously the only injector); buildOpencodeConfigContent accepts extraPluginPaths (original WIP)
  • src/extension.ts — boot + solver-switch register the context plugin; solver-switch projectDir asymmetry fixed (original WIP)
  • packages/extension/AGENTS.md — single broadened recovery pointer (template tail) covering solver mode, routing, fleet, and the vault files; replaces the WIP's programmatic append (was duplicated)
  • Deletedsubstrate/user_splice.ts + the now-dead vault_store index readers (KNOWLEDGE/DEMOS/MEMORY) — the plugin owns that text now, pinned golden in test/stack_state.test.ts (14 cases: fleet rendering + degradation, mount discovery incl. duplicate/marker-less skips, section text parity with the retired builders, caps 50/30/50, splice-parity section order, hermetic env-seam composition). solverModeSection/routingSection deliberately stay as the original WIP's parity oracles (test-only) — noted asymmetry, reviewer's call whether to fold them into stack_state pins too.
  • test/packaging.test.ts — pins amicode_context.ts + stack_state.ts as must-ship vsix assets.

Hook support verified against the deployed fork binary: experimental.chat.system.transform is typed (packages/plugin/src/index.ts:291), triggered (agent/agent.ts:381), and the frozen canonical server binary contains the hook string. Silent no-op remains the failure mode if a binary lacks it — which is why the recovery pointer exists.

Deployment sequencing (the canonical launchd server serves a hand-staged bundle):

  1. Merge + release a vsix carrying the plugin files (the server config's existing amicode_context.ts reference — dead since it was added — goes live the moment the newest installed vsix ships it).
  2. Restart the canonical server (it resolves __EXT__ to the newest vsix at boot).
  3. Strip the now-duplicated static sections (About this user / recent problems / reference demos / mount stack / memory index) from the staged ~/.amico/server/opencode-project-staging/opencode-project/AGENTS.md — until then they render twice (harmless, just noisy).

Verification: tsc --noEmit clean; full extension suite 1186 passed / 5 skipped / 100 files.

Summary by CodeRabbit

  • New Features

    • Added live context injection for solver status, routing, fleet information, active work, profile data, and relevant memory.
    • Context updates automatically during startup and solver-mode restarts.
    • Added support for discovering and prioritizing available data sources.
  • Bug Fixes

    • Missing, malformed, or unavailable data is handled gracefully without interrupting prompt generation.
    • Prevented stale context from being embedded in persistent project instructions.
  • Tests

    • Expanded coverage for context composition, data discovery, ordering, limits, and graceful degradation.
    • Updated packaging and integration checks for the new context functionality.

@aarontrowbridgeaarontrowbridge linked an issue Aug 9, 2026 that may be closed by this pull request
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a91ada6 to a37166aCompareAugust 20, 2026 08:48
@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22e859f7-5049-4d1c-8401-dc55e00e9fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 324a5ec and 8d39f63.

📒 Files selected for processing (12)
  • packages/extension/AGENTS.md
  • packages/extension/opencode-plugin/amicode_context.ts
  • packages/extension/opencode-plugin/stack_state.ts
  • packages/extension/src/extension.ts
  • packages/extension/src/opencode_config.ts
  • packages/extension/src/substrate/user_splice.ts
  • packages/extension/src/substrate/vault_store.ts
  • packages/extension/test/packaging.test.ts
  • packages/extension/test/scores/prep_integration.test.ts
  • packages/extension/test/stack_state.test.ts
  • packages/extension/test/substrate/user_splice.test.ts
  • packages/extension/test/substrate/vault_store.test.ts

📝 Walkthrough

Walkthrough

The extension now injects live solver, fleet, problem, routing, and personal-vault context into OpenCode prompts. Startup no longer splices this data into AGENTS.md. New stack-state readers, plugin wiring, packaging checks, and tests support the change.

Changes

Live context injection

Layer / File(s)Summary
Stack-state collection and rendering
packages/extension/opencode-plugin/stack_state.ts, packages/extension/test/stack_state.test.ts
The new builder reads operational state and vault data, discovers mounts, renders ordered markdown sections, applies content caps, and handles missing or malformed files.
OpenCode plugin wiring
packages/extension/opencode-plugin/amicode_context.ts, packages/extension/src/opencode_config.ts, packages/extension/src/extension.ts, packages/extension/AGENTS.md, packages/extension/test/packaging.test.ts
The plugin appends live context during system-prompt transformation. Initial and restart configurations register the plugin, and packaged assets include its runtime files.
Startup splice removal and migration coverage
packages/extension/src/substrate/vault_store.ts, packages/extension/src/opencode_config.ts, packages/extension/test/scores/prep_integration.test.ts
Startup writes only compiled AGENTS.md content. Obsolete user-memory readers and splice helpers are removed. Integration tests verify live injection and recovery-pointer behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers:rchari1

Sequence Diagram(s)

sequenceDiagram
participant Extension
participant OpenCode
participant AmicodeContext
participant LocalState
participant PersonalVault
Extension->>OpenCode: register Amico context plugin
OpenCode->>AmicodeContext: transform system prompt
AmicodeContext->>LocalState: read live solver and fleet state
AmicodeContext->>PersonalVault: read profile, problems, demos, mounts, and memory
AmicodeContext-->>OpenCode: append generated context
``
</details>
<!-- walkthrough_end -->
<!-- finishing_touch_checkbox_start -->
<details>
<summary>✨ Finishing Touches</summary>
<details>
<summary>📝 Generate docstrings</summary>
- [ ] <!-- {"checkboxId":"7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId":"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch
</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>
- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `304-feat-live-stack-state-injection-via-agent-harness-hook`
</details>
</details>
<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->
---
<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>
<!-- tips_end -->
Loading

Adds a second opencode plugin (amicode_context.ts) implementing
experimental.chat.system.transform that reads solver mode, routing,
active problem, and live runs on every prompt build and injects them
as the final system[] entry.
- opencode-plugin/stack_state.ts — standalone state readers + builders
- opencode-plugin/amicode_context.ts — system.transform hook plugin
- src/opencode_config — removed solver/routing from file splice;
buildOpencodeConfigContent accepts extraPluginPaths param
- src/extension.ts — registers context plugin in boot + solver-switch;
fixes mkdtemp asymmetry in solver-switch re-prep
- AGENTS.md — one-line recovery pointer appended
Closes#304.
Extends the amicode_context plugin's system.transform injection so the
sections that went stale as boot-time file splices are read LIVE from
disk on every prompt build:
- stack_state.ts: lean fleet line (role from fleet.json, devices +
freshness from fleet-status.json, on-demand pointers) — absent
fleet.json renders nothing; marker-only Armonia mount discovery
(smol-toml-free port of mount_store semantics: kind ranks, duplicate
skip, kind-rank order) + the user-memory sections (profile, recent
problems, reference demos, mount stack, memory index) read from the
personal vault, section text byte-identical to the retired
substrate/user_splice.ts builders (pinned golden in
test/stack_state.test.ts, 14 cases incl. caps + splice-parity order)
- opencode_config.ts: the boot-time user-memory/mount/memory splices
are REMOVED (they were the staleness bug: hand-maintained server
bundles and re-prepped project dirs served yesterday's memory index);
the template AGENTS.md carries the single broadened recovery pointer
(replaces the programmatic append — was duplicated)
- user_splice.ts + vault_store's now-dead index readers deleted;
solverModeSection/routingSection stay as the WIP's parity oracles
- packaging.test.ts pins amicode_context.ts + stack_state.ts as
must-ship vsix assets (the server config's dead reference goes live
the moment a vsix carries them)
Closes the 'Amicode forgets the fleet' class: a distiller write, a
solver switch, or a vault sync reaches the next message without a
re-prep or server restart.
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a37166a to 8d39f63CompareAugust 21, 2026 13:26
@aarontrowbridge
aarontrowbridge marked this pull request as ready for review August 22, 2026 21:30
@aarontrowbridge
aarontrowbridge merged commit f0f5887 into mainAug 22, 2026
7 of 8 checks passed
@aarontrowbridge
aarontrowbridge deleted the 304-feat-live-stack-state-injection-via-agent-harness-hook branch August 22, 2026 21:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: live stack-state injection via agent harness hook

1 participant

@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: live stack-state injection via agent harness hook (#304) - #306

Merged
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook
Aug 22, 2026
Merged

feat: live stack-state injection via agent harness hook (#304)#306
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook

Conversation

@aarontrowbridge

@aarontrowbridgeaarontrowbridge commented Aug 9, 2026

Copy link
Copy Markdown
Member

Implements #304.

Adds a second opencode plugin (amicode_context.ts) implementing experimental.chat.system.transform that reads live state on every prompt build and injects it as the final system[] entry.

Scope (expanded 2026-08-21): the original WIP moved solver mode + routing off the boot-time file splice. This update finishes the job — the fleet line and the user-memory sections (profile, recent problems, reference demos, mount stack, memory index) also move to the live hook. Motivation: the boot-time splices were the "Amicode forgets the fleet" bug class — a hand-maintained server bundle (the canonical launchd server's staging dir) or a stale re-prep served yesterday's memory index and yesterday's solver mode to every new session (observed: 10-entry index frozen at Aug 16 vs 18 live; cloud-HP solver instructions served after the user switched back to Piccolo).

Key changes:

  • opencode-plugin/stack_state.ts — standalone state readers + markdown builders (node-builtins only for Bun runtime): solver mode, routing, active problem, live runs (original WIP) + NEW lean fleet line (~/.amico/ops/fleet/fleet.json role, fleet-status.json devices/freshness with stale/unreadable degradation, on-demand pointers — absent fleet.json renders nothing) + NEW marker-only Armonia mount discovery (smol-toml-free port of mount_store semantics: kind ranks, duplicate-id skip, kind-rank ordering) and the five user-memory sections read live from the personal vault, section text byte-identical to the retired substrate/user_splice.ts builders. No mounts.toml manifest support (smol-toml unavailable in Bun; no manifest exists in practice — documented in-module).
  • opencode-plugin/amicode_context.ts — the plugin, single export, one hook (unchanged)
  • src/opencode_config.ts — solver/routing AND the user-memory/mount/memory-index splices removed from prepareOpencodeProject (the latter previously the only injector); buildOpencodeConfigContent accepts extraPluginPaths (original WIP)
  • src/extension.ts — boot + solver-switch register the context plugin; solver-switch projectDir asymmetry fixed (original WIP)
  • packages/extension/AGENTS.md — single broadened recovery pointer (template tail) covering solver mode, routing, fleet, and the vault files; replaces the WIP's programmatic append (was duplicated)
  • Deletedsubstrate/user_splice.ts + the now-dead vault_store index readers (KNOWLEDGE/DEMOS/MEMORY) — the plugin owns that text now, pinned golden in test/stack_state.test.ts (14 cases: fleet rendering + degradation, mount discovery incl. duplicate/marker-less skips, section text parity with the retired builders, caps 50/30/50, splice-parity section order, hermetic env-seam composition). solverModeSection/routingSection deliberately stay as the original WIP's parity oracles (test-only) — noted asymmetry, reviewer's call whether to fold them into stack_state pins too.
  • test/packaging.test.ts — pins amicode_context.ts + stack_state.ts as must-ship vsix assets.

Hook support verified against the deployed fork binary: experimental.chat.system.transform is typed (packages/plugin/src/index.ts:291), triggered (agent/agent.ts:381), and the frozen canonical server binary contains the hook string. Silent no-op remains the failure mode if a binary lacks it — which is why the recovery pointer exists.

Deployment sequencing (the canonical launchd server serves a hand-staged bundle):

  1. Merge + release a vsix carrying the plugin files (the server config's existing amicode_context.ts reference — dead since it was added — goes live the moment the newest installed vsix ships it).
  2. Restart the canonical server (it resolves __EXT__ to the newest vsix at boot).
  3. Strip the now-duplicated static sections (About this user / recent problems / reference demos / mount stack / memory index) from the staged ~/.amico/server/opencode-project-staging/opencode-project/AGENTS.md — until then they render twice (harmless, just noisy).

Verification: tsc --noEmit clean; full extension suite 1186 passed / 5 skipped / 100 files.

Summary by CodeRabbit

  • New Features

    • Added live context injection for solver status, routing, fleet information, active work, profile data, and relevant memory.
    • Context updates automatically during startup and solver-mode restarts.
    • Added support for discovering and prioritizing available data sources.
  • Bug Fixes

    • Missing, malformed, or unavailable data is handled gracefully without interrupting prompt generation.
    • Prevented stale context from being embedded in persistent project instructions.
  • Tests

    • Expanded coverage for context composition, data discovery, ordering, limits, and graceful degradation.
    • Updated packaging and integration checks for the new context functionality.

@aarontrowbridgeaarontrowbridge linked an issue Aug 9, 2026 that may be closed by this pull request
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a91ada6 to a37166aCompareAugust 20, 2026 08:48
@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22e859f7-5049-4d1c-8401-dc55e00e9fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 324a5ec and 8d39f63.

📒 Files selected for processing (12)
  • packages/extension/AGENTS.md
  • packages/extension/opencode-plugin/amicode_context.ts
  • packages/extension/opencode-plugin/stack_state.ts
  • packages/extension/src/extension.ts
  • packages/extension/src/opencode_config.ts
  • packages/extension/src/substrate/user_splice.ts
  • packages/extension/src/substrate/vault_store.ts
  • packages/extension/test/packaging.test.ts
  • packages/extension/test/scores/prep_integration.test.ts
  • packages/extension/test/stack_state.test.ts
  • packages/extension/test/substrate/user_splice.test.ts
  • packages/extension/test/substrate/vault_store.test.ts

📝 Walkthrough

Walkthrough

The extension now injects live solver, fleet, problem, routing, and personal-vault context into OpenCode prompts. Startup no longer splices this data into AGENTS.md. New stack-state readers, plugin wiring, packaging checks, and tests support the change.

Changes

Live context injection

Layer / File(s)Summary
Stack-state collection and rendering
packages/extension/opencode-plugin/stack_state.ts, packages/extension/test/stack_state.test.ts
The new builder reads operational state and vault data, discovers mounts, renders ordered markdown sections, applies content caps, and handles missing or malformed files.
OpenCode plugin wiring
packages/extension/opencode-plugin/amicode_context.ts, packages/extension/src/opencode_config.ts, packages/extension/src/extension.ts, packages/extension/AGENTS.md, packages/extension/test/packaging.test.ts
The plugin appends live context during system-prompt transformation. Initial and restart configurations register the plugin, and packaged assets include its runtime files.
Startup splice removal and migration coverage
packages/extension/src/substrate/vault_store.ts, packages/extension/src/opencode_config.ts, packages/extension/test/scores/prep_integration.test.ts
Startup writes only compiled AGENTS.md content. Obsolete user-memory readers and splice helpers are removed. Integration tests verify live injection and recovery-pointer behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers:rchari1

Sequence Diagram(s)

sequenceDiagram
participant Extension
participant OpenCode
participant AmicodeContext
participant LocalState
participant PersonalVault
Extension->>OpenCode: register Amico context plugin
OpenCode->>AmicodeContext: transform system prompt
AmicodeContext->>LocalState: read live solver and fleet state
AmicodeContext->>PersonalVault: read profile, problems, demos, mounts, and memory
AmicodeContext-->>OpenCode: append generated context
``
</details>
<!-- walkthrough_end -->
<!-- finishing_touch_checkbox_start -->
<details>
<summary>✨ Finishing Touches</summary>
<details>
<summary>📝 Generate docstrings</summary>
- [ ] <!-- {"checkboxId":"7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId":"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch
</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>
- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `304-feat-live-stack-state-injection-via-agent-harness-hook`
</details>
</details>
<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->
---
<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>
<!-- tips_end -->
Loading

Adds a second opencode plugin (amicode_context.ts) implementing
experimental.chat.system.transform that reads solver mode, routing,
active problem, and live runs on every prompt build and injects them
as the final system[] entry.
- opencode-plugin/stack_state.ts — standalone state readers + builders
- opencode-plugin/amicode_context.ts — system.transform hook plugin
- src/opencode_config — removed solver/routing from file splice;
buildOpencodeConfigContent accepts extraPluginPaths param
- src/extension.ts — registers context plugin in boot + solver-switch;
fixes mkdtemp asymmetry in solver-switch re-prep
- AGENTS.md — one-line recovery pointer appended
Closes#304.
Extends the amicode_context plugin's system.transform injection so the
sections that went stale as boot-time file splices are read LIVE from
disk on every prompt build:
- stack_state.ts: lean fleet line (role from fleet.json, devices +
freshness from fleet-status.json, on-demand pointers) — absent
fleet.json renders nothing; marker-only Armonia mount discovery
(smol-toml-free port of mount_store semantics: kind ranks, duplicate
skip, kind-rank order) + the user-memory sections (profile, recent
problems, reference demos, mount stack, memory index) read from the
personal vault, section text byte-identical to the retired
substrate/user_splice.ts builders (pinned golden in
test/stack_state.test.ts, 14 cases incl. caps + splice-parity order)
- opencode_config.ts: the boot-time user-memory/mount/memory splices
are REMOVED (they were the staleness bug: hand-maintained server
bundles and re-prepped project dirs served yesterday's memory index);
the template AGENTS.md carries the single broadened recovery pointer
(replaces the programmatic append — was duplicated)
- user_splice.ts + vault_store's now-dead index readers deleted;
solverModeSection/routingSection stay as the WIP's parity oracles
- packaging.test.ts pins amicode_context.ts + stack_state.ts as
must-ship vsix assets (the server config's dead reference goes live
the moment a vsix carries them)
Closes the 'Amicode forgets the fleet' class: a distiller write, a
solver switch, or a vault sync reaches the next message without a
re-prep or server restart.
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a37166a to 8d39f63CompareAugust 21, 2026 13:26
@aarontrowbridge
aarontrowbridge marked this pull request as ready for review August 22, 2026 21:30
@aarontrowbridge
aarontrowbridge merged commit f0f5887 into mainAug 22, 2026
7 of 8 checks passed
@aarontrowbridge
aarontrowbridge deleted the 304-feat-live-stack-state-injection-via-agent-harness-hook branch August 22, 2026 21:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: live stack-state injection via agent harness hook

1 participant

@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: live stack-state injection via agent harness hook (#304) - #306

Merged
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook
Aug 22, 2026
Merged

feat: live stack-state injection via agent harness hook (#304)#306
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook

Conversation

@aarontrowbridge

@aarontrowbridgeaarontrowbridge commented Aug 9, 2026

Copy link
Copy Markdown
Member

Implements #304.

Adds a second opencode plugin (amicode_context.ts) implementing experimental.chat.system.transform that reads live state on every prompt build and injects it as the final system[] entry.

Scope (expanded 2026-08-21): the original WIP moved solver mode + routing off the boot-time file splice. This update finishes the job — the fleet line and the user-memory sections (profile, recent problems, reference demos, mount stack, memory index) also move to the live hook. Motivation: the boot-time splices were the "Amicode forgets the fleet" bug class — a hand-maintained server bundle (the canonical launchd server's staging dir) or a stale re-prep served yesterday's memory index and yesterday's solver mode to every new session (observed: 10-entry index frozen at Aug 16 vs 18 live; cloud-HP solver instructions served after the user switched back to Piccolo).

Key changes:

  • opencode-plugin/stack_state.ts — standalone state readers + markdown builders (node-builtins only for Bun runtime): solver mode, routing, active problem, live runs (original WIP) + NEW lean fleet line (~/.amico/ops/fleet/fleet.json role, fleet-status.json devices/freshness with stale/unreadable degradation, on-demand pointers — absent fleet.json renders nothing) + NEW marker-only Armonia mount discovery (smol-toml-free port of mount_store semantics: kind ranks, duplicate-id skip, kind-rank ordering) and the five user-memory sections read live from the personal vault, section text byte-identical to the retired substrate/user_splice.ts builders. No mounts.toml manifest support (smol-toml unavailable in Bun; no manifest exists in practice — documented in-module).
  • opencode-plugin/amicode_context.ts — the plugin, single export, one hook (unchanged)
  • src/opencode_config.ts — solver/routing AND the user-memory/mount/memory-index splices removed from prepareOpencodeProject (the latter previously the only injector); buildOpencodeConfigContent accepts extraPluginPaths (original WIP)
  • src/extension.ts — boot + solver-switch register the context plugin; solver-switch projectDir asymmetry fixed (original WIP)
  • packages/extension/AGENTS.md — single broadened recovery pointer (template tail) covering solver mode, routing, fleet, and the vault files; replaces the WIP's programmatic append (was duplicated)
  • Deletedsubstrate/user_splice.ts + the now-dead vault_store index readers (KNOWLEDGE/DEMOS/MEMORY) — the plugin owns that text now, pinned golden in test/stack_state.test.ts (14 cases: fleet rendering + degradation, mount discovery incl. duplicate/marker-less skips, section text parity with the retired builders, caps 50/30/50, splice-parity section order, hermetic env-seam composition). solverModeSection/routingSection deliberately stay as the original WIP's parity oracles (test-only) — noted asymmetry, reviewer's call whether to fold them into stack_state pins too.
  • test/packaging.test.ts — pins amicode_context.ts + stack_state.ts as must-ship vsix assets.

Hook support verified against the deployed fork binary: experimental.chat.system.transform is typed (packages/plugin/src/index.ts:291), triggered (agent/agent.ts:381), and the frozen canonical server binary contains the hook string. Silent no-op remains the failure mode if a binary lacks it — which is why the recovery pointer exists.

Deployment sequencing (the canonical launchd server serves a hand-staged bundle):

  1. Merge + release a vsix carrying the plugin files (the server config's existing amicode_context.ts reference — dead since it was added — goes live the moment the newest installed vsix ships it).
  2. Restart the canonical server (it resolves __EXT__ to the newest vsix at boot).
  3. Strip the now-duplicated static sections (About this user / recent problems / reference demos / mount stack / memory index) from the staged ~/.amico/server/opencode-project-staging/opencode-project/AGENTS.md — until then they render twice (harmless, just noisy).

Verification: tsc --noEmit clean; full extension suite 1186 passed / 5 skipped / 100 files.

Summary by CodeRabbit

  • New Features

    • Added live context injection for solver status, routing, fleet information, active work, profile data, and relevant memory.
    • Context updates automatically during startup and solver-mode restarts.
    • Added support for discovering and prioritizing available data sources.
  • Bug Fixes

    • Missing, malformed, or unavailable data is handled gracefully without interrupting prompt generation.
    • Prevented stale context from being embedded in persistent project instructions.
  • Tests

    • Expanded coverage for context composition, data discovery, ordering, limits, and graceful degradation.
    • Updated packaging and integration checks for the new context functionality.

@aarontrowbridgeaarontrowbridge linked an issue Aug 9, 2026 that may be closed by this pull request
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a91ada6 to a37166aCompareAugust 20, 2026 08:48
@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22e859f7-5049-4d1c-8401-dc55e00e9fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 324a5ec and 8d39f63.

📒 Files selected for processing (12)
  • packages/extension/AGENTS.md
  • packages/extension/opencode-plugin/amicode_context.ts
  • packages/extension/opencode-plugin/stack_state.ts
  • packages/extension/src/extension.ts
  • packages/extension/src/opencode_config.ts
  • packages/extension/src/substrate/user_splice.ts
  • packages/extension/src/substrate/vault_store.ts
  • packages/extension/test/packaging.test.ts
  • packages/extension/test/scores/prep_integration.test.ts
  • packages/extension/test/stack_state.test.ts
  • packages/extension/test/substrate/user_splice.test.ts
  • packages/extension/test/substrate/vault_store.test.ts

📝 Walkthrough

Walkthrough

The extension now injects live solver, fleet, problem, routing, and personal-vault context into OpenCode prompts. Startup no longer splices this data into AGENTS.md. New stack-state readers, plugin wiring, packaging checks, and tests support the change.

Changes

Live context injection

Layer / File(s)Summary
Stack-state collection and rendering
packages/extension/opencode-plugin/stack_state.ts, packages/extension/test/stack_state.test.ts
The new builder reads operational state and vault data, discovers mounts, renders ordered markdown sections, applies content caps, and handles missing or malformed files.
OpenCode plugin wiring
packages/extension/opencode-plugin/amicode_context.ts, packages/extension/src/opencode_config.ts, packages/extension/src/extension.ts, packages/extension/AGENTS.md, packages/extension/test/packaging.test.ts
The plugin appends live context during system-prompt transformation. Initial and restart configurations register the plugin, and packaged assets include its runtime files.
Startup splice removal and migration coverage
packages/extension/src/substrate/vault_store.ts, packages/extension/src/opencode_config.ts, packages/extension/test/scores/prep_integration.test.ts
Startup writes only compiled AGENTS.md content. Obsolete user-memory readers and splice helpers are removed. Integration tests verify live injection and recovery-pointer behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers:rchari1

Sequence Diagram(s)

sequenceDiagram
participant Extension
participant OpenCode
participant AmicodeContext
participant LocalState
participant PersonalVault
Extension->>OpenCode: register Amico context plugin
OpenCode->>AmicodeContext: transform system prompt
AmicodeContext->>LocalState: read live solver and fleet state
AmicodeContext->>PersonalVault: read profile, problems, demos, mounts, and memory
AmicodeContext-->>OpenCode: append generated context
``
</details>
<!-- walkthrough_end -->
<!-- finishing_touch_checkbox_start -->
<details>
<summary>✨ Finishing Touches</summary>
<details>
<summary>📝 Generate docstrings</summary>
- [ ] <!-- {"checkboxId":"7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId":"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch
</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>
- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `304-feat-live-stack-state-injection-via-agent-harness-hook`
</details>
</details>
<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->
---
<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>
<!-- tips_end -->
Loading

Adds a second opencode plugin (amicode_context.ts) implementing
experimental.chat.system.transform that reads solver mode, routing,
active problem, and live runs on every prompt build and injects them
as the final system[] entry.
- opencode-plugin/stack_state.ts — standalone state readers + builders
- opencode-plugin/amicode_context.ts — system.transform hook plugin
- src/opencode_config — removed solver/routing from file splice;
buildOpencodeConfigContent accepts extraPluginPaths param
- src/extension.ts — registers context plugin in boot + solver-switch;
fixes mkdtemp asymmetry in solver-switch re-prep
- AGENTS.md — one-line recovery pointer appended
Closes#304.
Extends the amicode_context plugin's system.transform injection so the
sections that went stale as boot-time file splices are read LIVE from
disk on every prompt build:
- stack_state.ts: lean fleet line (role from fleet.json, devices +
freshness from fleet-status.json, on-demand pointers) — absent
fleet.json renders nothing; marker-only Armonia mount discovery
(smol-toml-free port of mount_store semantics: kind ranks, duplicate
skip, kind-rank order) + the user-memory sections (profile, recent
problems, reference demos, mount stack, memory index) read from the
personal vault, section text byte-identical to the retired
substrate/user_splice.ts builders (pinned golden in
test/stack_state.test.ts, 14 cases incl. caps + splice-parity order)
- opencode_config.ts: the boot-time user-memory/mount/memory splices
are REMOVED (they were the staleness bug: hand-maintained server
bundles and re-prepped project dirs served yesterday's memory index);
the template AGENTS.md carries the single broadened recovery pointer
(replaces the programmatic append — was duplicated)
- user_splice.ts + vault_store's now-dead index readers deleted;
solverModeSection/routingSection stay as the WIP's parity oracles
- packaging.test.ts pins amicode_context.ts + stack_state.ts as
must-ship vsix assets (the server config's dead reference goes live
the moment a vsix carries them)
Closes the 'Amicode forgets the fleet' class: a distiller write, a
solver switch, or a vault sync reaches the next message without a
re-prep or server restart.
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a37166a to 8d39f63CompareAugust 21, 2026 13:26
@aarontrowbridge
aarontrowbridge marked this pull request as ready for review August 22, 2026 21:30
@aarontrowbridge
aarontrowbridge merged commit f0f5887 into mainAug 22, 2026
7 of 8 checks passed
@aarontrowbridge
aarontrowbridge deleted the 304-feat-live-stack-state-injection-via-agent-harness-hook branch August 22, 2026 21:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: live stack-state injection via agent harness hook

1 participant

@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: live stack-state injection via agent harness hook (#304) - #306

Merged
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook
Aug 22, 2026
Merged

feat: live stack-state injection via agent harness hook (#304)#306
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook

Conversation

@aarontrowbridge

@aarontrowbridgeaarontrowbridge commented Aug 9, 2026

Copy link
Copy Markdown
Member

Implements #304.

Adds a second opencode plugin (amicode_context.ts) implementing experimental.chat.system.transform that reads live state on every prompt build and injects it as the final system[] entry.

Scope (expanded 2026-08-21): the original WIP moved solver mode + routing off the boot-time file splice. This update finishes the job — the fleet line and the user-memory sections (profile, recent problems, reference demos, mount stack, memory index) also move to the live hook. Motivation: the boot-time splices were the "Amicode forgets the fleet" bug class — a hand-maintained server bundle (the canonical launchd server's staging dir) or a stale re-prep served yesterday's memory index and yesterday's solver mode to every new session (observed: 10-entry index frozen at Aug 16 vs 18 live; cloud-HP solver instructions served after the user switched back to Piccolo).

Key changes:

  • opencode-plugin/stack_state.ts — standalone state readers + markdown builders (node-builtins only for Bun runtime): solver mode, routing, active problem, live runs (original WIP) + NEW lean fleet line (~/.amico/ops/fleet/fleet.json role, fleet-status.json devices/freshness with stale/unreadable degradation, on-demand pointers — absent fleet.json renders nothing) + NEW marker-only Armonia mount discovery (smol-toml-free port of mount_store semantics: kind ranks, duplicate-id skip, kind-rank ordering) and the five user-memory sections read live from the personal vault, section text byte-identical to the retired substrate/user_splice.ts builders. No mounts.toml manifest support (smol-toml unavailable in Bun; no manifest exists in practice — documented in-module).
  • opencode-plugin/amicode_context.ts — the plugin, single export, one hook (unchanged)
  • src/opencode_config.ts — solver/routing AND the user-memory/mount/memory-index splices removed from prepareOpencodeProject (the latter previously the only injector); buildOpencodeConfigContent accepts extraPluginPaths (original WIP)
  • src/extension.ts — boot + solver-switch register the context plugin; solver-switch projectDir asymmetry fixed (original WIP)
  • packages/extension/AGENTS.md — single broadened recovery pointer (template tail) covering solver mode, routing, fleet, and the vault files; replaces the WIP's programmatic append (was duplicated)
  • Deletedsubstrate/user_splice.ts + the now-dead vault_store index readers (KNOWLEDGE/DEMOS/MEMORY) — the plugin owns that text now, pinned golden in test/stack_state.test.ts (14 cases: fleet rendering + degradation, mount discovery incl. duplicate/marker-less skips, section text parity with the retired builders, caps 50/30/50, splice-parity section order, hermetic env-seam composition). solverModeSection/routingSection deliberately stay as the original WIP's parity oracles (test-only) — noted asymmetry, reviewer's call whether to fold them into stack_state pins too.
  • test/packaging.test.ts — pins amicode_context.ts + stack_state.ts as must-ship vsix assets.

Hook support verified against the deployed fork binary: experimental.chat.system.transform is typed (packages/plugin/src/index.ts:291), triggered (agent/agent.ts:381), and the frozen canonical server binary contains the hook string. Silent no-op remains the failure mode if a binary lacks it — which is why the recovery pointer exists.

Deployment sequencing (the canonical launchd server serves a hand-staged bundle):

  1. Merge + release a vsix carrying the plugin files (the server config's existing amicode_context.ts reference — dead since it was added — goes live the moment the newest installed vsix ships it).
  2. Restart the canonical server (it resolves __EXT__ to the newest vsix at boot).
  3. Strip the now-duplicated static sections (About this user / recent problems / reference demos / mount stack / memory index) from the staged ~/.amico/server/opencode-project-staging/opencode-project/AGENTS.md — until then they render twice (harmless, just noisy).

Verification: tsc --noEmit clean; full extension suite 1186 passed / 5 skipped / 100 files.

Summary by CodeRabbit

  • New Features

    • Added live context injection for solver status, routing, fleet information, active work, profile data, and relevant memory.
    • Context updates automatically during startup and solver-mode restarts.
    • Added support for discovering and prioritizing available data sources.
  • Bug Fixes

    • Missing, malformed, or unavailable data is handled gracefully without interrupting prompt generation.
    • Prevented stale context from being embedded in persistent project instructions.
  • Tests

    • Expanded coverage for context composition, data discovery, ordering, limits, and graceful degradation.
    • Updated packaging and integration checks for the new context functionality.

@aarontrowbridgeaarontrowbridge linked an issue Aug 9, 2026 that may be closed by this pull request
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a91ada6 to a37166aCompareAugust 20, 2026 08:48
@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22e859f7-5049-4d1c-8401-dc55e00e9fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 324a5ec and 8d39f63.

📒 Files selected for processing (12)
  • packages/extension/AGENTS.md
  • packages/extension/opencode-plugin/amicode_context.ts
  • packages/extension/opencode-plugin/stack_state.ts
  • packages/extension/src/extension.ts
  • packages/extension/src/opencode_config.ts
  • packages/extension/src/substrate/user_splice.ts
  • packages/extension/src/substrate/vault_store.ts
  • packages/extension/test/packaging.test.ts
  • packages/extension/test/scores/prep_integration.test.ts
  • packages/extension/test/stack_state.test.ts
  • packages/extension/test/substrate/user_splice.test.ts
  • packages/extension/test/substrate/vault_store.test.ts

📝 Walkthrough

Walkthrough

The extension now injects live solver, fleet, problem, routing, and personal-vault context into OpenCode prompts. Startup no longer splices this data into AGENTS.md. New stack-state readers, plugin wiring, packaging checks, and tests support the change.

Changes

Live context injection

Layer / File(s)Summary
Stack-state collection and rendering
packages/extension/opencode-plugin/stack_state.ts, packages/extension/test/stack_state.test.ts
The new builder reads operational state and vault data, discovers mounts, renders ordered markdown sections, applies content caps, and handles missing or malformed files.
OpenCode plugin wiring
packages/extension/opencode-plugin/amicode_context.ts, packages/extension/src/opencode_config.ts, packages/extension/src/extension.ts, packages/extension/AGENTS.md, packages/extension/test/packaging.test.ts
The plugin appends live context during system-prompt transformation. Initial and restart configurations register the plugin, and packaged assets include its runtime files.
Startup splice removal and migration coverage
packages/extension/src/substrate/vault_store.ts, packages/extension/src/opencode_config.ts, packages/extension/test/scores/prep_integration.test.ts
Startup writes only compiled AGENTS.md content. Obsolete user-memory readers and splice helpers are removed. Integration tests verify live injection and recovery-pointer behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers:rchari1

Sequence Diagram(s)

sequenceDiagram
participant Extension
participant OpenCode
participant AmicodeContext
participant LocalState
participant PersonalVault
Extension->>OpenCode: register Amico context plugin
OpenCode->>AmicodeContext: transform system prompt
AmicodeContext->>LocalState: read live solver and fleet state
AmicodeContext->>PersonalVault: read profile, problems, demos, mounts, and memory
AmicodeContext-->>OpenCode: append generated context
``
</details>
<!-- walkthrough_end -->
<!-- finishing_touch_checkbox_start -->
<details>
<summary>✨ Finishing Touches</summary>
<details>
<summary>📝 Generate docstrings</summary>
- [ ] <!-- {"checkboxId":"7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId":"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch
</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>
- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `304-feat-live-stack-state-injection-via-agent-harness-hook`
</details>
</details>
<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->
---
<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>
<!-- tips_end -->
Loading

Adds a second opencode plugin (amicode_context.ts) implementing
experimental.chat.system.transform that reads solver mode, routing,
active problem, and live runs on every prompt build and injects them
as the final system[] entry.
- opencode-plugin/stack_state.ts — standalone state readers + builders
- opencode-plugin/amicode_context.ts — system.transform hook plugin
- src/opencode_config — removed solver/routing from file splice;
buildOpencodeConfigContent accepts extraPluginPaths param
- src/extension.ts — registers context plugin in boot + solver-switch;
fixes mkdtemp asymmetry in solver-switch re-prep
- AGENTS.md — one-line recovery pointer appended
Closes#304.
Extends the amicode_context plugin's system.transform injection so the
sections that went stale as boot-time file splices are read LIVE from
disk on every prompt build:
- stack_state.ts: lean fleet line (role from fleet.json, devices +
freshness from fleet-status.json, on-demand pointers) — absent
fleet.json renders nothing; marker-only Armonia mount discovery
(smol-toml-free port of mount_store semantics: kind ranks, duplicate
skip, kind-rank order) + the user-memory sections (profile, recent
problems, reference demos, mount stack, memory index) read from the
personal vault, section text byte-identical to the retired
substrate/user_splice.ts builders (pinned golden in
test/stack_state.test.ts, 14 cases incl. caps + splice-parity order)
- opencode_config.ts: the boot-time user-memory/mount/memory splices
are REMOVED (they were the staleness bug: hand-maintained server
bundles and re-prepped project dirs served yesterday's memory index);
the template AGENTS.md carries the single broadened recovery pointer
(replaces the programmatic append — was duplicated)
- user_splice.ts + vault_store's now-dead index readers deleted;
solverModeSection/routingSection stay as the WIP's parity oracles
- packaging.test.ts pins amicode_context.ts + stack_state.ts as
must-ship vsix assets (the server config's dead reference goes live
the moment a vsix carries them)
Closes the 'Amicode forgets the fleet' class: a distiller write, a
solver switch, or a vault sync reaches the next message without a
re-prep or server restart.
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a37166a to 8d39f63CompareAugust 21, 2026 13:26
@aarontrowbridge
aarontrowbridge marked this pull request as ready for review August 22, 2026 21:30
@aarontrowbridge
aarontrowbridge merged commit f0f5887 into mainAug 22, 2026
7 of 8 checks passed
@aarontrowbridge
aarontrowbridge deleted the 304-feat-live-stack-state-injection-via-agent-harness-hook branch August 22, 2026 21:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: live stack-state injection via agent harness hook

1 participant

@aarontrowbridge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: live stack-state injection via agent harness hook (#304) - #306

Merged
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook
Aug 22, 2026
Merged

feat: live stack-state injection via agent harness hook (#304)#306
aarontrowbridge merged 2 commits into
mainfrom
304-feat-live-stack-state-injection-via-agent-harness-hook

Conversation

@aarontrowbridge

@aarontrowbridgeaarontrowbridge commented Aug 9, 2026

Copy link
Copy Markdown
Member

Implements #304.

Adds a second opencode plugin (amicode_context.ts) implementing experimental.chat.system.transform that reads live state on every prompt build and injects it as the final system[] entry.

Scope (expanded 2026-08-21): the original WIP moved solver mode + routing off the boot-time file splice. This update finishes the job — the fleet line and the user-memory sections (profile, recent problems, reference demos, mount stack, memory index) also move to the live hook. Motivation: the boot-time splices were the "Amicode forgets the fleet" bug class — a hand-maintained server bundle (the canonical launchd server's staging dir) or a stale re-prep served yesterday's memory index and yesterday's solver mode to every new session (observed: 10-entry index frozen at Aug 16 vs 18 live; cloud-HP solver instructions served after the user switched back to Piccolo).

Key changes:

  • opencode-plugin/stack_state.ts — standalone state readers + markdown builders (node-builtins only for Bun runtime): solver mode, routing, active problem, live runs (original WIP) + NEW lean fleet line (~/.amico/ops/fleet/fleet.json role, fleet-status.json devices/freshness with stale/unreadable degradation, on-demand pointers — absent fleet.json renders nothing) + NEW marker-only Armonia mount discovery (smol-toml-free port of mount_store semantics: kind ranks, duplicate-id skip, kind-rank ordering) and the five user-memory sections read live from the personal vault, section text byte-identical to the retired substrate/user_splice.ts builders. No mounts.toml manifest support (smol-toml unavailable in Bun; no manifest exists in practice — documented in-module).
  • opencode-plugin/amicode_context.ts — the plugin, single export, one hook (unchanged)
  • src/opencode_config.ts — solver/routing AND the user-memory/mount/memory-index splices removed from prepareOpencodeProject (the latter previously the only injector); buildOpencodeConfigContent accepts extraPluginPaths (original WIP)
  • src/extension.ts — boot + solver-switch register the context plugin; solver-switch projectDir asymmetry fixed (original WIP)
  • packages/extension/AGENTS.md — single broadened recovery pointer (template tail) covering solver mode, routing, fleet, and the vault files; replaces the WIP's programmatic append (was duplicated)
  • Deletedsubstrate/user_splice.ts + the now-dead vault_store index readers (KNOWLEDGE/DEMOS/MEMORY) — the plugin owns that text now, pinned golden in test/stack_state.test.ts (14 cases: fleet rendering + degradation, mount discovery incl. duplicate/marker-less skips, section text parity with the retired builders, caps 50/30/50, splice-parity section order, hermetic env-seam composition). solverModeSection/routingSection deliberately stay as the original WIP's parity oracles (test-only) — noted asymmetry, reviewer's call whether to fold them into stack_state pins too.
  • test/packaging.test.ts — pins amicode_context.ts + stack_state.ts as must-ship vsix assets.

Hook support verified against the deployed fork binary: experimental.chat.system.transform is typed (packages/plugin/src/index.ts:291), triggered (agent/agent.ts:381), and the frozen canonical server binary contains the hook string. Silent no-op remains the failure mode if a binary lacks it — which is why the recovery pointer exists.

Deployment sequencing (the canonical launchd server serves a hand-staged bundle):

  1. Merge + release a vsix carrying the plugin files (the server config's existing amicode_context.ts reference — dead since it was added — goes live the moment the newest installed vsix ships it).
  2. Restart the canonical server (it resolves __EXT__ to the newest vsix at boot).
  3. Strip the now-duplicated static sections (About this user / recent problems / reference demos / mount stack / memory index) from the staged ~/.amico/server/opencode-project-staging/opencode-project/AGENTS.md — until then they render twice (harmless, just noisy).

Verification: tsc --noEmit clean; full extension suite 1186 passed / 5 skipped / 100 files.

Summary by CodeRabbit

  • New Features

    • Added live context injection for solver status, routing, fleet information, active work, profile data, and relevant memory.
    • Context updates automatically during startup and solver-mode restarts.
    • Added support for discovering and prioritizing available data sources.
  • Bug Fixes

    • Missing, malformed, or unavailable data is handled gracefully without interrupting prompt generation.
    • Prevented stale context from being embedded in persistent project instructions.
  • Tests

    • Expanded coverage for context composition, data discovery, ordering, limits, and graceful degradation.
    • Updated packaging and integration checks for the new context functionality.

@aarontrowbridgeaarontrowbridge linked an issue Aug 9, 2026 that may be closed by this pull request
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a91ada6 to a37166aCompareAugust 20, 2026 08:48
@coderabbitai

coderabbitaiBot commented Aug 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 22e859f7-5049-4d1c-8401-dc55e00e9fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 324a5ec and 8d39f63.

📒 Files selected for processing (12)
  • packages/extension/AGENTS.md
  • packages/extension/opencode-plugin/amicode_context.ts
  • packages/extension/opencode-plugin/stack_state.ts
  • packages/extension/src/extension.ts
  • packages/extension/src/opencode_config.ts
  • packages/extension/src/substrate/user_splice.ts
  • packages/extension/src/substrate/vault_store.ts
  • packages/extension/test/packaging.test.ts
  • packages/extension/test/scores/prep_integration.test.ts
  • packages/extension/test/stack_state.test.ts
  • packages/extension/test/substrate/user_splice.test.ts
  • packages/extension/test/substrate/vault_store.test.ts

📝 Walkthrough

Walkthrough

The extension now injects live solver, fleet, problem, routing, and personal-vault context into OpenCode prompts. Startup no longer splices this data into AGENTS.md. New stack-state readers, plugin wiring, packaging checks, and tests support the change.

Changes

Live context injection

Layer / File(s)Summary
Stack-state collection and rendering
packages/extension/opencode-plugin/stack_state.ts, packages/extension/test/stack_state.test.ts
The new builder reads operational state and vault data, discovers mounts, renders ordered markdown sections, applies content caps, and handles missing or malformed files.
OpenCode plugin wiring
packages/extension/opencode-plugin/amicode_context.ts, packages/extension/src/opencode_config.ts, packages/extension/src/extension.ts, packages/extension/AGENTS.md, packages/extension/test/packaging.test.ts
The plugin appends live context during system-prompt transformation. Initial and restart configurations register the plugin, and packaged assets include its runtime files.
Startup splice removal and migration coverage
packages/extension/src/substrate/vault_store.ts, packages/extension/src/opencode_config.ts, packages/extension/test/scores/prep_integration.test.ts
Startup writes only compiled AGENTS.md content. Obsolete user-memory readers and splice helpers are removed. Integration tests verify live injection and recovery-pointer behavior.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers:rchari1

Sequence Diagram(s)

sequenceDiagram
participant Extension
participant OpenCode
participant AmicodeContext
participant LocalState
participant PersonalVault
Extension->>OpenCode: register Amico context plugin
OpenCode->>AmicodeContext: transform system prompt
AmicodeContext->>LocalState: read live solver and fleet state
AmicodeContext->>PersonalVault: read profile, problems, demos, mounts, and memory
AmicodeContext-->>OpenCode: append generated context
``
</details>
<!-- walkthrough_end -->
<!-- finishing_touch_checkbox_start -->
<details>
<summary>✨ Finishing Touches</summary>
<details>
<summary>📝 Generate docstrings</summary>
- [ ] <!-- {"checkboxId":"7962f53c-55bc-4827-bfbf-6a18da830691"} --> Create stacked PR
- [ ] <!-- {"checkboxId":"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98"} --> Commit on current branch
</details>
<details>
<summary>🧪 Generate unit tests (beta)</summary>
- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Create PR with unit tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} --> Commit unit tests in branch `304-feat-live-stack-state-injection-via-agent-harness-hook`
</details>
</details>
<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->
---
<sub>Comment `@coderabbitai help` to get the list of available commands.</sub>
<!-- tips_end -->
Loading

Adds a second opencode plugin (amicode_context.ts) implementing
experimental.chat.system.transform that reads solver mode, routing,
active problem, and live runs on every prompt build and injects them
as the final system[] entry.
- opencode-plugin/stack_state.ts — standalone state readers + builders
- opencode-plugin/amicode_context.ts — system.transform hook plugin
- src/opencode_config — removed solver/routing from file splice;
buildOpencodeConfigContent accepts extraPluginPaths param
- src/extension.ts — registers context plugin in boot + solver-switch;
fixes mkdtemp asymmetry in solver-switch re-prep
- AGENTS.md — one-line recovery pointer appended
Closes#304.
Extends the amicode_context plugin's system.transform injection so the
sections that went stale as boot-time file splices are read LIVE from
disk on every prompt build:
- stack_state.ts: lean fleet line (role from fleet.json, devices +
freshness from fleet-status.json, on-demand pointers) — absent
fleet.json renders nothing; marker-only Armonia mount discovery
(smol-toml-free port of mount_store semantics: kind ranks, duplicate
skip, kind-rank order) + the user-memory sections (profile, recent
problems, reference demos, mount stack, memory index) read from the
personal vault, section text byte-identical to the retired
substrate/user_splice.ts builders (pinned golden in
test/stack_state.test.ts, 14 cases incl. caps + splice-parity order)
- opencode_config.ts: the boot-time user-memory/mount/memory splices
are REMOVED (they were the staleness bug: hand-maintained server
bundles and re-prepped project dirs served yesterday's memory index);
the template AGENTS.md carries the single broadened recovery pointer
(replaces the programmatic append — was duplicated)
- user_splice.ts + vault_store's now-dead index readers deleted;
solverModeSection/routingSection stay as the WIP's parity oracles
- packaging.test.ts pins amicode_context.ts + stack_state.ts as
must-ship vsix assets (the server config's dead reference goes live
the moment a vsix carries them)
Closes the 'Amicode forgets the fleet' class: a distiller write, a
solver switch, or a vault sync reaches the next message without a
re-prep or server restart.
@aarontrowbridge
aarontrowbridgeforce-pushed the 304-feat-live-stack-state-injection-via-agent-harness-hook branch from a37166a to 8d39f63CompareAugust 21, 2026 13:26
@aarontrowbridge
aarontrowbridge marked this pull request as ready for review August 22, 2026 21:30
@aarontrowbridge
aarontrowbridge merged commit f0f5887 into mainAug 22, 2026
7 of 8 checks passed
@aarontrowbridge
aarontrowbridge deleted the 304-feat-live-stack-state-injection-via-agent-harness-hook branch August 22, 2026 21:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: live stack-state injection via agent harness hook

1 participant

@aarontrowbridge