Context Manager + Agent Prompt UI #8

Open
opened 2026-04-21 06:38:28 +00:00 by despiegk · 3 comments
Owner

Coding Spec — Context Manager + Agent Prompt UI

Objective

Build a coding-agent interface with 2 tabs:

  1. Context Manager
  2. Agents

The system lets users:

  • browse known repositories
  • select files/directories
  • include only interesting source/text files
  • save those selections as named contexts
  • attach one or more contexts to an agent prompt
  • execute prompts through hero_proc
  • initially support only Claude

1. Core Concepts

1.1 Context

A Context is a reusable saved selection of files from one or more repositories.

A context contains:

  • name
  • selected paths
  • allowed extensions
  • generated file list
  • timestamps

A context is editable and reusable.


1.2 Agent Prompt Session

An Agent Prompt Session is a chat-like workspace for interacting with an agent.

A session contains:

  • name/title
  • selected agent
  • attached contexts
  • prompt history
  • execution history
  • job references from hero_proc

2. Main UI Structure

Tab 1 — Context Manager

Used to create, edit, inspect, copy, and save contexts.

Tab 2 — Agents

Used to create prompt sessions, attach contexts, write prompts, and execute via hero_proc.


3. Context Manager

3.1 Purpose

The Context Manager allows the user to:

  • browse repos already known in the system
  • expand directories
  • multi-select files and folders
  • only include allowed file extensions
  • preview included files
  • copy rendered context
  • save the selection as a named context
  • reopen later and modify it

3.2 Repository Tree

The tree starts at known repositories.

Tree levels

  1. Repository
  2. Directory
  3. File

Example:

  • hero_router

    • src
    • docs
    • README.md
  • hero_proc

    • src
    • specs
    • Cargo.toml

3.3 Selection Model

File selection

A file can be selected only if its extension is allowed.

Directory selection

Selecting a directory recursively includes all allowed files underneath it.

Multi-select

User can select:

  • multiple repositories
  • multiple directories
  • multiple files

Selection states

Each node supports:

  • unselected
  • selected
  • partial

Partial means some children are selected.


4. Allowed Extensions Model

4.1 Rule

We do not maintain ignore logic.

We use a strict allowlist.

Only files with these extensions are interesting.

4.2 Base allowed extensions

.py
.rs
.md
.txt
.ts
.js
.hero
.hs
.oschema
.toml
.json
.yaml

Optional to also support .yml later, but base spec uses the list above.


4.3 Inclusion logic

ALLOWED_EXTENSIONS = {
  ".py", ".rs", ".md", ".txt", ".ts", ".js",
  ".hero", ".hs", ".oschema", ".toml", ".json", ".yaml"
}

function is_allowed(path):
    return extension(path) in ALLOWED_EXTENSIONS

Directory traversal

function collect_allowed_files(dir):
    result = []
    for child in dir.children:
        if child.is_dir:
            result += collect_allowed_files(child)
        else if child.is_file and is_allowed(child.path):
            result.append(child.path)
    return result

5. Tree UI Behavior

5.1 Display rules

Preferred behavior:

  • show repositories and directories normally
  • show only allowed files in the tree

Alternative:

  • show all files but grey out non-allowed ones

Preferred implementation is simpler:

  • hide non-allowed files

5.2 Lazy loading

Directory children should load lazily to keep UI fast.


5.3 Search/filter

Tree should support quick filtering by:

  • repo name
  • directory name
  • file name

Search only affects visibility, not saved selection state.


6. Context Builder Panel

Alongside the tree, show a live summary panel.

6.1 Summary data

Show:

  • context name
  • selected repositories
  • selected directories
  • selected files
  • total included files
  • estimated total size
  • optional estimated token count

6.2 File preview list

Show a flat preview list of included files.

Each row:

  • repo name
  • relative path
  • extension
  • size

Actions:

  • remove from selection
  • open preview later if needed

7. Saved Contexts

7.1 Create context

User makes a selection, enters a name, saves it.

Required fields:

  • id
  • name
  • selected_paths
  • allowed_extensions
  • created_at
  • updated_at

Optional:

  • description

7.2 Saved context model

{
  "id": "ctx_001",
  "name": "hero proc + router",
  "description": "proc jobs and router rpc flow",
  "selected_paths": [
    "hero_proc/src",
    "hero_proc/README.md",
    "hero_router/src"
  ],
  "allowed_extensions": [
    ".py",
    ".rs",
    ".md",
    ".txt",
    ".ts",
    ".js",
    ".hero",
    ".hs",
    ".oschema",
    ".toml",
    ".json",
    ".yaml"
  ],
  "created_at": "2026-04-21T10:00:00Z",
  "updated_at": "2026-04-21T10:12:00Z"
}

7.3 Reopen/edit

A saved context can be reopened.

When reopened:

  • tree selection is restored
  • user can add/remove files/directories
  • user can rename the context
  • user can save changes

7.4 Saved contexts list

The UI must show all contexts.

Each row/card shows:

  • name
  • description optional
  • number of included files
  • updated timestamp

Actions:

  • open
  • rename
  • duplicate
  • delete
  • copy rendered context

8. Context Rendering

8.1 Purpose

A context must be renderable into a prompt-ready text bundle for Claude.


8.2 Output format

Recommended format:

# Context: hero proc + router

## File: hero_proc/src/main.rs
```rs
...

File: hero_router/src/lib.rs

...

Alternative simpler format:

```text
===== BEGIN FILE hero_proc/src/main.rs =====
...
===== END FILE hero_proc/src/main.rs =====

Main requirement:

  • stable
  • readable
  • easy to paste into Claude

8.3 Ordering

Files should be rendered in stable deterministic order:

  1. repo name
  2. relative path alphabetical

8.4 Copy action

User clicks Copy Context.

This copies the full rendered context bundle to clipboard.


9. Agents Tab

9.1 Purpose

The Agents tab is where users write prompts and execute them against Claude using saved contexts.


9.2 Layout

Left sidebar

List of prompt sessions

Main panel

Chat/prompt history

Right sidebar or top section

Attached contexts + execution status


10. Agent Prompt Sessions

10.1 Session model

A session stores:

  • id
  • name
  • agent_id
  • attached_context_ids
  • messages
  • created_at
  • updated_at

10.2 Message types

Messages can be:

  • user prompt
  • composed execution payload summary
  • agent output
  • execution status
  • error

10.3 Session actions

User can:

  • create new session
  • rename session
  • reopen session
  • delete session
  • duplicate session

11. Claude Agent Integration

11.1 Initial scope

Only one agent is supported initially:

  • claude

11.2 Execution backend

Claude is executed through your existing shell-based runner setup and managed by hero_proc.

The UI should not directly execute Claude.
It should create a hero_proc job.


11.3 Runner profiles

Future-ready support for runner variants:

  • A0
  • A1
  • A2

Initial implementation may:

  • hardcode one default Claude runner
  • or allow choosing a configured profile

12. Attaching Contexts to Prompts

12.1 Rules

A prompt session can attach:

  • zero contexts
  • one context
  • multiple contexts

12.2 Actions

User can:

  • add context
  • remove context
  • reorder contexts
  • inspect included files per context

12.3 Execution composition

Final execution input is composed as:

  1. attached contexts rendered in order
  2. user prompt text

Optionally later:
3. prior session history


13. Prompt Composer

13.1 Required UI elements

  • multiline text input
  • attached context chips/list
  • execute button
  • optional runner/profile selector
  • optional clear/reset action

13.2 Basic flow

  1. user selects or creates a prompt session
  2. user attaches one or more contexts
  3. user types prompt
  4. user presses execute
  5. hero_proc job is created
  6. output appears in session history

14. hero_proc Integration

14.1 Role

hero_proc is the job manager for all executions.

It is responsible for:

  • queueing
  • starting jobs
  • tracking job state
  • collecting output
  • exposing logs/status

14.2 Execution request

When user clicks execute, UI creates a job request containing:

  • session id
  • agent id = claude
  • runner profile if any
  • attached context ids
  • rendered prompt payload
  • metadata

14.3 Job states

Use standard states:

  • queued
  • running
  • succeeded
  • failed
  • cancelled

14.4 Job metadata

Recommended metadata:

{
  "session_id": "sess_001",
  "agent_id": "claude",
  "runner_profile": "A0",
  "attached_context_ids": ["ctx_001", "ctx_002"],
  "title": "Explain hero_proc scheduling flow"
}

15. Recommended Data Models

15.1 Context

{
  "id": "ctx_001",
  "name": "hero proc core",
  "description": "main proc files",
  "selected_paths": [
    "hero_proc/src",
    "hero_proc/README.md"
  ],
  "allowed_extensions": [
    ".py",
    ".rs",
    ".md",
    ".txt",
    ".ts",
    ".js",
    ".hero",
    ".hs",
    ".oschema",
    ".toml",
    ".json",
    ".yaml"
  ],
  "created_at": "2026-04-21T10:00:00Z",
  "updated_at": "2026-04-21T10:05:00Z"
}

15.2 Prompt session

{
  "id": "sess_001",
  "name": "proc refactor ideas",
  "agent_id": "claude",
  "attached_context_ids": ["ctx_001"],
  "messages": [],
  "created_at": "2026-04-21T10:10:00Z",
  "updated_at": "2026-04-21T10:10:00Z"
}

15.3 Execution record

{
  "id": "exec_001",
  "session_id": "sess_001",
  "agent_id": "claude",
  "context_ids": ["ctx_001"],
  "job_id": "hero_proc_job_123",
  "status": "running",
  "created_at": "2026-04-21T10:12:00Z"
}

16. Backend Requirements

16.1 Repository source

The system already knows repositories.
The Context Manager must read from that source of truth.


16.2 Filesystem API requirements

Need backend endpoints/services for:

  • list repositories
  • list tree children for a path
  • compute allowed files for selection
  • load file contents
  • save context
  • update context
  • delete context
  • list contexts
  • render context
  • create prompt session
  • list prompt sessions
  • update prompt session
  • execute session via hero_proc
  • stream/poll execution output

17. Minimal API Surface

Context APIs

  • listRepos()
  • listTree(path)
  • saveContext(input)
  • updateContext(id, input)
  • deleteContext(id)
  • listContexts()
  • getContext(id)
  • renderContext(id)

Prompt/session APIs

  • listSessions()
  • createSession(input)
  • updateSession(id, input)
  • deleteSession(id)
  • attachContext(sessionId, contextId)
  • detachContext(sessionId, contextId)

Execution APIs

  • executeSession(sessionId, prompt, runnerProfile?)
  • getExecution(jobId)
  • getExecutionLogs(jobId)

18. UX Requirements

Context Manager must feel:

  • fast
  • deterministic
  • simple
  • file-selection-first

Agents tab must feel:

  • like a chat
  • but with structured reusable context attachment

19. Non-goals for initial version

Do not add yet:

  • semantic search
  • automatic summarization
  • git diff awareness
  • branch comparison
  • token optimization logic
  • non-Claude agents
  • complex ignore rules
  • inline code editing
  • automatic context generation by AI

20. MVP Scope

Context Manager MVP

  • list repos
  • tree view
  • allowlist-based file filtering
  • multi-select directories/files
  • save named contexts
  • reopen/edit contexts
  • copy rendered context

Agents MVP

  • list/create prompt sessions
  • attach one or more contexts
  • write prompt
  • execute with Claude
  • execution through hero_proc
  • show result in session history

21. Short Implementation Summary

Tab 1: Context Manager

“Select useful files from repos, save as named reusable context.”

Tab 2: Agents

“Create a prompt session, attach one or more saved contexts, send to Claude via hero_proc.”

Filtering model

“Only include files with these extensions: .py .rs .md .txt .ts .js .hero .hs .oschema .toml .json .yaml.”


22. One-line product definition

A Repo Prompt-style context builder and Claude execution UI, backed by hero_proc, with reusable named contexts built from selected repository files.

If you want, I can turn this into a much more implementation-ready Rust/OpenRPC spec next.

use skills

  • /hero_proc_sdk
  • /hero_proc_sdk_jobs_use
# Coding Spec — Context Manager + Agent Prompt UI ## Objective Build a coding-agent interface with **2 tabs**: 1. **Context Manager** 2. **Agents** The system lets users: * browse known repositories * select files/directories * include only interesting source/text files * save those selections as named **contexts** * attach one or more contexts to an agent prompt * execute prompts through **hero_proc** * initially support only **Claude** --- # 1. Core Concepts ## 1.1 Context A **Context** is a reusable saved selection of files from one or more repositories. A context contains: * name * selected paths * allowed extensions * generated file list * timestamps A context is editable and reusable. --- ## 1.2 Agent Prompt Session An **Agent Prompt Session** is a chat-like workspace for interacting with an agent. A session contains: * name/title * selected agent * attached contexts * prompt history * execution history * job references from hero_proc --- # 2. Main UI Structure ## Tab 1 — Context Manager Used to create, edit, inspect, copy, and save contexts. ## Tab 2 — Agents Used to create prompt sessions, attach contexts, write prompts, and execute via hero_proc. --- # 3. Context Manager ## 3.1 Purpose The Context Manager allows the user to: * browse repos already known in the system * expand directories * multi-select files and folders * only include allowed file extensions * preview included files * copy rendered context * save the selection as a named context * reopen later and modify it --- ## 3.2 Repository Tree The tree starts at known repositories. ### Tree levels 1. Repository 2. Directory 3. File Example: * hero_router * src * docs * README.md * hero_proc * src * specs * Cargo.toml --- ## 3.3 Selection Model ### File selection A file can be selected only if its extension is allowed. ### Directory selection Selecting a directory recursively includes all allowed files underneath it. ### Multi-select User can select: * multiple repositories * multiple directories * multiple files ### Selection states Each node supports: * unselected * selected * partial Partial means some children are selected. --- # 4. Allowed Extensions Model ## 4.1 Rule We do **not** maintain ignore logic. We use a strict **allowlist**. Only files with these extensions are interesting. ## 4.2 Base allowed extensions ```text .py .rs .md .txt .ts .js .hero .hs .oschema .toml .json .yaml ``` Optional to also support `.yml` later, but base spec uses the list above. --- ## 4.3 Inclusion logic ```pseudo ALLOWED_EXTENSIONS = { ".py", ".rs", ".md", ".txt", ".ts", ".js", ".hero", ".hs", ".oschema", ".toml", ".json", ".yaml" } function is_allowed(path): return extension(path) in ALLOWED_EXTENSIONS ``` ### Directory traversal ```pseudo function collect_allowed_files(dir): result = [] for child in dir.children: if child.is_dir: result += collect_allowed_files(child) else if child.is_file and is_allowed(child.path): result.append(child.path) return result ``` --- # 5. Tree UI Behavior ## 5.1 Display rules Preferred behavior: * show repositories and directories normally * show only allowed files in the tree Alternative: * show all files but grey out non-allowed ones Preferred implementation is simpler: * **hide non-allowed files** --- ## 5.2 Lazy loading Directory children should load lazily to keep UI fast. --- ## 5.3 Search/filter Tree should support quick filtering by: * repo name * directory name * file name Search only affects visibility, not saved selection state. --- # 6. Context Builder Panel Alongside the tree, show a live summary panel. ## 6.1 Summary data Show: * context name * selected repositories * selected directories * selected files * total included files * estimated total size * optional estimated token count --- ## 6.2 File preview list Show a flat preview list of included files. Each row: * repo name * relative path * extension * size Actions: * remove from selection * open preview later if needed --- # 7. Saved Contexts ## 7.1 Create context User makes a selection, enters a name, saves it. Required fields: * `id` * `name` * `selected_paths` * `allowed_extensions` * `created_at` * `updated_at` Optional: * `description` --- ## 7.2 Saved context model ```json { "id": "ctx_001", "name": "hero proc + router", "description": "proc jobs and router rpc flow", "selected_paths": [ "hero_proc/src", "hero_proc/README.md", "hero_router/src" ], "allowed_extensions": [ ".py", ".rs", ".md", ".txt", ".ts", ".js", ".hero", ".hs", ".oschema", ".toml", ".json", ".yaml" ], "created_at": "2026-04-21T10:00:00Z", "updated_at": "2026-04-21T10:12:00Z" } ``` --- ## 7.3 Reopen/edit A saved context can be reopened. When reopened: * tree selection is restored * user can add/remove files/directories * user can rename the context * user can save changes --- ## 7.4 Saved contexts list The UI must show all contexts. Each row/card shows: * name * description optional * number of included files * updated timestamp Actions: * open * rename * duplicate * delete * copy rendered context --- # 8. Context Rendering ## 8.1 Purpose A context must be renderable into a prompt-ready text bundle for Claude. --- ## 8.2 Output format Recommended format: ````text # Context: hero proc + router ## File: hero_proc/src/main.rs ```rs ... ```` ## File: hero_router/src/lib.rs ```rs ... ``` ```` Alternative simpler format: ```text ===== BEGIN FILE hero_proc/src/main.rs ===== ... ===== END FILE hero_proc/src/main.rs ===== ```` Main requirement: * stable * readable * easy to paste into Claude --- ## 8.3 Ordering Files should be rendered in stable deterministic order: 1. repo name 2. relative path alphabetical --- ## 8.4 Copy action User clicks **Copy Context**. This copies the full rendered context bundle to clipboard. --- # 9. Agents Tab ## 9.1 Purpose The Agents tab is where users write prompts and execute them against Claude using saved contexts. --- ## 9.2 Layout ## Left sidebar List of prompt sessions ## Main panel Chat/prompt history ## Right sidebar or top section Attached contexts + execution status --- # 10. Agent Prompt Sessions ## 10.1 Session model A session stores: * `id` * `name` * `agent_id` * `attached_context_ids` * `messages` * `created_at` * `updated_at` --- ## 10.2 Message types Messages can be: * user prompt * composed execution payload summary * agent output * execution status * error --- ## 10.3 Session actions User can: * create new session * rename session * reopen session * delete session * duplicate session --- # 11. Claude Agent Integration ## 11.1 Initial scope Only one agent is supported initially: * `claude` --- ## 11.2 Execution backend Claude is executed through your existing shell-based runner setup and managed by **hero_proc**. The UI should not directly execute Claude. It should create a hero_proc job. --- ## 11.3 Runner profiles Future-ready support for runner variants: * A0 * A1 * A2 Initial implementation may: * hardcode one default Claude runner * or allow choosing a configured profile --- # 12. Attaching Contexts to Prompts ## 12.1 Rules A prompt session can attach: * zero contexts * one context * multiple contexts --- ## 12.2 Actions User can: * add context * remove context * reorder contexts * inspect included files per context --- ## 12.3 Execution composition Final execution input is composed as: 1. attached contexts rendered in order 2. user prompt text Optionally later: 3. prior session history --- # 13. Prompt Composer ## 13.1 Required UI elements * multiline text input * attached context chips/list * execute button * optional runner/profile selector * optional clear/reset action --- ## 13.2 Basic flow 1. user selects or creates a prompt session 2. user attaches one or more contexts 3. user types prompt 4. user presses execute 5. hero_proc job is created 6. output appears in session history --- # 14. hero_proc Integration ## 14.1 Role hero_proc is the job manager for all executions. It is responsible for: * queueing * starting jobs * tracking job state * collecting output * exposing logs/status --- ## 14.2 Execution request When user clicks execute, UI creates a job request containing: * session id * agent id = claude * runner profile if any * attached context ids * rendered prompt payload * metadata --- ## 14.3 Job states Use standard states: * queued * running * succeeded * failed * cancelled --- ## 14.4 Job metadata Recommended metadata: ```json { "session_id": "sess_001", "agent_id": "claude", "runner_profile": "A0", "attached_context_ids": ["ctx_001", "ctx_002"], "title": "Explain hero_proc scheduling flow" } ``` --- # 15. Recommended Data Models ## 15.1 Context ```json { "id": "ctx_001", "name": "hero proc core", "description": "main proc files", "selected_paths": [ "hero_proc/src", "hero_proc/README.md" ], "allowed_extensions": [ ".py", ".rs", ".md", ".txt", ".ts", ".js", ".hero", ".hs", ".oschema", ".toml", ".json", ".yaml" ], "created_at": "2026-04-21T10:00:00Z", "updated_at": "2026-04-21T10:05:00Z" } ``` ## 15.2 Prompt session ```json { "id": "sess_001", "name": "proc refactor ideas", "agent_id": "claude", "attached_context_ids": ["ctx_001"], "messages": [], "created_at": "2026-04-21T10:10:00Z", "updated_at": "2026-04-21T10:10:00Z" } ``` ## 15.3 Execution record ```json { "id": "exec_001", "session_id": "sess_001", "agent_id": "claude", "context_ids": ["ctx_001"], "job_id": "hero_proc_job_123", "status": "running", "created_at": "2026-04-21T10:12:00Z" } ``` --- # 16. Backend Requirements ## 16.1 Repository source The system already knows repositories. The Context Manager must read from that source of truth. --- ## 16.2 Filesystem API requirements Need backend endpoints/services for: * list repositories * list tree children for a path * compute allowed files for selection * load file contents * save context * update context * delete context * list contexts * render context * create prompt session * list prompt sessions * update prompt session * execute session via hero_proc * stream/poll execution output --- # 17. Minimal API Surface ## Context APIs * `listRepos()` * `listTree(path)` * `saveContext(input)` * `updateContext(id, input)` * `deleteContext(id)` * `listContexts()` * `getContext(id)` * `renderContext(id)` ## Prompt/session APIs * `listSessions()` * `createSession(input)` * `updateSession(id, input)` * `deleteSession(id)` * `attachContext(sessionId, contextId)` * `detachContext(sessionId, contextId)` ## Execution APIs * `executeSession(sessionId, prompt, runnerProfile?)` * `getExecution(jobId)` * `getExecutionLogs(jobId)` --- # 18. UX Requirements ## Context Manager must feel: * fast * deterministic * simple * file-selection-first ## Agents tab must feel: * like a chat * but with structured reusable context attachment --- # 19. Non-goals for initial version Do not add yet: * semantic search * automatic summarization * git diff awareness * branch comparison * token optimization logic * non-Claude agents * complex ignore rules * inline code editing * automatic context generation by AI --- # 20. MVP Scope ## Context Manager MVP * list repos * tree view * allowlist-based file filtering * multi-select directories/files * save named contexts * reopen/edit contexts * copy rendered context ## Agents MVP * list/create prompt sessions * attach one or more contexts * write prompt * execute with Claude * execution through hero_proc * show result in session history --- # 21. Short Implementation Summary ## Tab 1: Context Manager “Select useful files from repos, save as named reusable context.” ## Tab 2: Agents “Create a prompt session, attach one or more saved contexts, send to Claude via hero_proc.” ## Filtering model “Only include files with these extensions: `.py .rs .md .txt .ts .js .hero .hs .oschema .toml .json .yaml`.” --- # 22. One-line product definition A **Repo Prompt-style context builder and Claude execution UI**, backed by **hero_proc**, with reusable named contexts built from selected repository files. If you want, I can turn this into a much more **implementation-ready Rust/OpenRPC spec** next. ## use skills - /hero_proc_sdk - /hero_proc_sdk_jobs_use
Author
Owner

Implementation Spec for Issue #8

Objective

Add a Context Manager + Agents UI to the existing hero_code admin dashboard that lets users (a) browse repositories already known under CODEROOT, select files and directories with extension allowlist filtering, and save reusable named Contexts, and (b) create Agent Prompt Sessions, attach one or more contexts, write a prompt, and execute it through hero_proc as a tagged Claude agentic job (via the nu interpreter + a 2 -i ... recipe). Only Claude is supported for v1.

Requirements

  • Reuse the existing stack: Axum + Askama + static/js/*.js in crates/hero_code_ui, JSON-RPC 2.0 via /rpc routed to hero_code_server (do not introduce Dioxus or any new framework — the dashboard is a vanilla-JS Bootstrap SPA with tab panes in index.html).
  • Two new top-level tabs ("Contexts", "Agents") wired into the existing nav-tabs-custom bar and .app-content tab-pane pattern.
  • Repo list comes from existing code.list RPC (walks CODEROOT). A new code.tree RPC lazily lists directory children, filtered by the allowlist.
  • Allowlist extensions: .py .rs .md .txt .ts .js .hero .hs .oschema .toml .json .yaml — strict positive filtering (hidden dotfiles and target/, node_modules/, .git/ are also skipped).
  • Contexts: persistent, editable, duplicatable, deletable, with render-to-text (prompt bundle) support.
  • Sessions: persistent, hold ordered attached context ids + chat-style message log + execution records.
  • Execution: builds the prompt bundle, posts a tagged nu job to hero_proc via hero_proc_sdk (a 2 -i "<bundle + prompt>"), records the returned job_id, and polls job.* on hero_proc for status/logs.
  • Persistence: SQLite, next to hero_code.db (new hero_code_agents.db) — matches the existing hero_code_lib::db pattern (WAL, rusqlite, schema in model.rs, API in factory.rs). Do not use Redis or the filesystem — the repo already ships SQLite for jobs/logs.
  • All new RPC methods dispatched from crates/hero_code_server/src/rpc/mod.rs and documented in openrpc.json.

Files to Modify/Create

hero_code_lib (new persistence)

  • crates/hero_code_lib/src/db/contexts/mod.rs — module wiring.
  • crates/hero_code_lib/src/db/contexts/model.rsContext struct, CRUD functions, schema init.
  • crates/hero_code_lib/src/db/sessions/mod.rs — module wiring.
  • crates/hero_code_lib/src/db/sessions/model.rsPromptSession, ChatMessage, ExecutionRecord structs + CRUD + schema init.
  • crates/hero_code_lib/src/db/factory.rs — MODIFY: open a second SQLite file (hero_code_agents.db) next to the main DB; add pub contexts: ContextsApi and pub sessions: SessionsApi fields on HeroRunnerDb.
  • crates/hero_code_lib/src/db/mod.rs — MODIFY: pub mod contexts; pub mod sessions;.

hero_code_server (RPC + Claude job launcher)

  • crates/hero_code_server/Cargo.toml — MODIFY: add hero_proc_sdk = { workspace = true }.
  • crates/hero_code_server/src/rpc/tree.rs — new: code.tree (lazy, allowlist-filtered dir listing).
  • crates/hero_code_server/src/rpc/context.rs — new: context.list, context.get, context.save, context.update, context.delete, context.render.
  • crates/hero_code_server/src/rpc/session.rs — new: session.list, session.create, session.update, session.delete, session.attach_context, session.detach_context, session.add_message.
  • crates/hero_code_server/src/rpc/agent.rs — new: agent.execute (builds Claude nu job via hero_proc_sdk, records ExecutionRecord), agent.execution_get, agent.execution_logs.
  • crates/hero_code_server/src/rpc/mod.rs — MODIFY: register new methods.
  • crates/hero_code_server/openrpc.json — MODIFY: add new method definitions + component schemas.
  • crates/hero_code_server/src/web.rs — MODIFY: add new methods to positional_to_named mapping (optional — all new calls can mandate named params from JS to sidestep this).
  • crates/hero_code_server/src/types/mod.rs & responses.rs — MODIFY if needed to re-export new domain types.

hero_code_ui (dashboard tabs)

  • crates/hero_code_ui/templates/index.html — MODIFY: add two <a class="nav-link" data-tab="..."> entries and two new <div class="tab-pane" id="tab-contexts"> / id="tab-agents"> panes.
  • crates/hero_code_ui/static/js/contexts.js — new: Context Manager logic (repo picker → tree → selection → builder → save/list/edit/render/copy).
  • crates/hero_code_ui/static/js/agents.js — new: session list, chat view, attach contexts, execute, poll logs.
  • crates/hero_code_ui/static/js/dashboard.js — MODIFY: extend the tab-switch handler to call contextsInit() / agentsInit() on first activation (mirrors codeInit()).
  • crates/hero_code_ui/static/css/dashboard.css — MODIFY: minor additions for the tree, builder panel, and chat bubble layout (no new <style> blocks in templates).

Implementation Plan

Step 1: Data models + persistence

Files: crates/hero_code_lib/src/db/contexts/{mod,model}.rs, crates/hero_code_lib/src/db/sessions/{mod,model}.rs, crates/hero_code_lib/src/db/factory.rs, crates/hero_code_lib/src/db/mod.rs.

  • Define in contexts/model.rs:
    pub struct Context {
        pub id: u32,
        pub name: String,
        pub description: Option<String>,
        pub selected_paths: Vec<String>,
        pub allowed_extensions: Vec<String>,
        pub created_at: u64,
        pub updated_at: u64,
    }
    
    with init_schema, insert, update, get, list, delete. Store selected_paths and allowed_extensions as JSON TEXT columns.
  • Define in sessions/model.rs:
    pub struct PromptSession {
        pub id: u32,
        pub name: String,
        pub agent_id: String,
        pub attached_context_ids: Vec<u32>,
        pub created_at: u64,
        pub updated_at: u64,
    }
    pub struct ChatMessage {
        pub id: u32,
        pub session_id: u32,
        pub role: String,
        pub content: String,
        pub created_at: u64,
        pub execution_id: Option<u32>,
    }
    pub struct ExecutionRecord {
        pub id: u32,
        pub session_id: u32,
        pub agent_id: String,
        pub context_ids: Vec<u32>,
        pub runner_profile: String,
        pub hero_proc_job_id: i64,
        pub status: String,
        pub created_at: u64,
        pub finished_at: Option<u64>,
    }
    
    with init_schema, CRUD, plus list_messages(session_id), list_executions(session_id), update_execution_status(id, status, finished_at).
  • In factory.rs: open a second SQLite connection at parent/hero_code_agents.db, run schema init for both new tables, expose pub contexts: ContextsApi, pub sessions: SessionsApi.
  • Add unit tests mirroring the existing test_namespaced_jobs_api style.

Dependencies: none.

Step 2: Context RPC + directory tree RPC

Files: crates/hero_code_server/src/rpc/tree.rs, crates/hero_code_server/src/rpc/context.rs, crates/hero_code_server/src/rpc/mod.rs.

  • tree.rscode.tree(params: { path: string }) returns { entries: [{name, path, kind: "dir"|"file", size?}] } for one directory level, skipping hidden entries, target/, node_modules/, .git/, and files whose extension is not on the allowlist. Path must resolve under CODEROOT.
  • context.rs:
    • context.list{ contexts: [...] }.
    • context.get(id) → full Context.
    • context.save({ name, description?, selected_paths[], allowed_extensions? }) → created Context.
    • context.update({ id, ... }).
    • context.delete({ id }).
    • context.render({ id }){ text, file_count, byte_count }. Expansion logic:
      1. For each selected path, if file and ext allowed → include; if dir → walk recursively, allowlist-only; dedupe.
      2. Determine repo prefix from CODEROOT/<org>/<repo>/....
      3. Sort stably by (repo, relative_path).
      4. Emit:
        # Context: <name>
        
        ## File: <repo>/<relative_path>
        ```<ext>
        <file contents>
        ```
        
      5. Skip files bigger than 512 KB with a warning line.
  • Wire in rpc/mod.rs dispatch.

Dependencies: Step 1.

Step 3: Session + execution RPC (Claude via hero_proc)

Files: crates/hero_code_server/src/rpc/session.rs, crates/hero_code_server/src/rpc/agent.rs, crates/hero_code_server/src/rpc/mod.rs, crates/hero_code_server/Cargo.toml.

  • Add hero_proc_sdk = { workspace = true } in hero_code_server/Cargo.toml.
  • session.rs — CRUD + attach/detach/add_message against db.sessions.
  • agent.rs:
    • agent.execute({ session_id, prompt, runner_profile? }):
      1. Load session + every attached context; call the render helper.
      2. Concatenate: render(ctx1)\n\n...\n\nrender(ctxN)\n\n# User Prompt\n\n<prompt>.
      3. Persist a ChatMessage {role:"user", content: prompt}.
      4. Write the rendered bundle to $HOME/hero/var/agents/<session_id>/<ts>.txt.
      5. Build a nu ActionSpec per hero_proc_sdk_jobs_use:
        • interpreter nu, tags hero_code + agent + claude, 10-min timeout, no_retry.
        • script: use <HERO_AGENT_NU_PATH> *; let p = open "<bundle_path>"; a 2 -i $p.
      6. Submit via hero_proc_sdk::hero_proc_factory().await?.job_create(...).
      7. Record an ExecutionRecord with hero_proc_job_id, status="pending".
      8. Return { execution_id, job_id, status }.
    • agent.execution_get({ execution_id }) → fetch local record, live-poll hero_proc job.get, append the final agent message when the job terminates, return merged view.
    • agent.execution_logs({ execution_id, lines? }) → proxy to hero_proc job.logs.
  • Wire in rpc/mod.rs.

Dependencies: Step 1, Step 2.

Step 4: OpenRPC spec updates

Files: crates/hero_code_server/openrpc.json.

  • Add method entries + $ref component schemas for Context, PromptSession, ChatMessage, ExecutionRecord, and all new method params/results.

Dependencies: Step 3.

Step 5: UI — Contexts tab

Files: crates/hero_code_ui/templates/index.html, crates/hero_code_ui/static/js/contexts.js, crates/hero_code_ui/static/js/dashboard.js, crates/hero_code_ui/static/css/dashboard.css.

  • index.html:
    • Add tab: <a class="nav-link" data-tab="contexts" href="#/contexts"><i class="bi bi-folder-symlink"></i> Contexts</a>.
    • Three-column pane (#tab-contexts):
      • Left: saved contexts list + "+ New".
      • Center: repo picker + tree (lazy-expand via code.tree), tri-state checkboxes, search filter.
      • Right: Builder panel — name, description, included-files count, estimated size, included-files list with per-row remove action, Save / Duplicate / Delete, "Copy rendered".
  • contexts.js:
    • contextsInit() loads contexts + repos.
    • contextsExpandDir(path) calls code.tree.
    • Multi-select state keyed by absolute path + directory-flag.
    • contextsSave(), contextsLoad(id), contextsRender(id)navigator.clipboard.writeText(text).
  • dashboard.js: add contexts to the tab switch callback map.
  • dashboard.css: tree + tri-state checkbox styles using existing --accent-* CSS vars.

Dependencies: Step 2.

Step 6: UI — Agents tab

Files: crates/hero_code_ui/templates/index.html, crates/hero_code_ui/static/js/agents.js, crates/hero_code_ui/static/js/dashboard.js, crates/hero_code_ui/static/css/dashboard.css.

  • index.html:
    • Tab: <a class="nav-link" data-tab="agents" href="#/agents"><i class="bi bi-robot"></i> Agents</a>.
    • Three-column pane (#tab-agents): left = sessions list + "+ New"; center = chat + prompt textarea + "Run"; right = attached contexts (up/down reorder + "Add context" dropdown) + live execution status panel with log tail.
  • agents.js:
    • agentsInit() loads session.list.
    • agentsSelectSession(id) renders messages, attached contexts, resumes polling of any in-flight execution.
    • agentsRun() calls agent.execute, polls agent.execution_get every 1s and agent.execution_logs every 500ms until terminal.
  • dashboard.js: register agents in the tab callback map.
  • dashboard.css: chat bubbles + log tail <pre> styling.

Dependencies: Step 3, Step 5.

Step 7: Tests + smoke

Files: unit tests inline in new modules.

  • Unit tests: Context/PromptSession CRUD; context.render exact format (fence, stable sort, allowlist filter).
  • Unit test for the nu-script builder in agent.rs (no real hero_proc — assert the script string and tags).
  • Manual smoke: start hero_code --start, open the UI, create a repo-scoped context, save it, create a session, attach, execute "say hello", verify the job appears in hero_proc_ui with tag hero_code+agent+claude and the agent stdout lands back in the chat.

Dependencies: Steps 1–6.

Acceptance Criteria

  • Two new tabs "Contexts" and "Agents" are visible in the dashboard and survive page reloads via the hash router.
  • Under "Contexts": existing CODEROOT repos appear; clicking a directory lazily expands via code.tree; only allowlisted files are shown.
  • Tri-state selection works: partial when some children are selected, full when all are, clearing a parent clears descendants.
  • Saving a context persists it (SQLite, survives restart); Duplicate creates a new record with suffix " (copy)"; Delete removes it.
  • "Copy rendered" emits the exact markdown format from the issue.
  • Under "Agents": a session can be created, have >=1 context attached, a prompt typed, and "Run" clicked.
  • Running a prompt creates a hero_proc job tagged hero_code + agent + claude, returns a job_id, and that job appears in hero_proc_ui at #jobs/<id>.
  • The execution status updates from pending -> running -> succeeded/failed by polling agent.execution_get; live log tail appears while running.
  • On job termination, the agent's stdout is persisted as a role:"agent" ChatMessage and displayed in the chat history.
  • All new endpoints are listed in openrpc.json and reachable via POST /rpc.
  • cargo check -p hero_code_lib -p hero_code_server -p hero_code_ui passes with no new warnings; existing tests still green.

Notes

Persistence choice. SQLite via rusqlite — the workspace already ships it for hero_code_lib::db. A second DB file (hero_code_agents.db) next to hero_code.db reuses the factory idiom and avoids introducing sled, hero_db, or filesystem JSON. Redis (code_db) is only a cache/metadata store and is not a good fit for structured, queryable entities like contexts/sessions.

UI framework choice. The repo is vanilla JS + Bootstrap + Askama (see templates/index.html, static/js/*.js, existing tabs: Forge, IDE, Jobs, Logs, Docs, Admin, Perf, Stats). Adding Contexts and Agents tabs follows the same recipe as the existing code_manage.js. No new UI framework.

RPC routing. hero_code_ui no longer proxies /rpc — the router sends /rpc directly to hero_code_server's Unix socket. New methods only need to be implemented in hero_code_server/src/rpc/*.

hero_proc integration. The hero_code CLI already uses hero_proc_sdk to register its own service. The same SDK is reused inside agent.rs to submit Claude jobs, following the hero_proc_sdk_jobs_use recipe verbatim. The agent.nu path is read from HERO_AGENT_NU_PATH with a sensible default.

Prompt size handling. A rendered bundle can easily exceed 1 MB and break shell quoting. The bundle is written to $HOME/hero/var/agents/<session_id>/<ts>.txt and the nu script reads it with open <path>. Bundles remain on disk for post-mortem inspection.

Scope cut for v1 (this PR). Dropped from the MVP: token-count estimation (only file-count + byte-count), non-Claude agents, runner-profile selection (hardcode "A0"), drag-drop reorder for attached contexts (up/down buttons instead), inline message editing.

Follow-ups (explicitly deferred, not steps):

  • Token counting via a real tokenizer.
  • Runner profiles A0/A1/A2 with different Claude models.
  • Context tree virtualization for very large monorepos.
  • SSE streaming from hero_proc for zero-latency agent tokens.
  • Semantic search / git-diff-aware contexts.
  • Export/import contexts as JSON.
## Implementation Spec for Issue #8 ### Objective Add a Context Manager + Agents UI to the existing `hero_code` admin dashboard that lets users (a) browse repositories already known under `CODEROOT`, select files and directories with extension allowlist filtering, and save reusable named **Contexts**, and (b) create Agent **Prompt Sessions**, attach one or more contexts, write a prompt, and execute it through **hero_proc** as a tagged Claude agentic job (via the `nu` interpreter + `a 2 -i ...` recipe). Only Claude is supported for v1. ### Requirements - Reuse the existing stack: Axum + Askama + `static/js/*.js` in `crates/hero_code_ui`, JSON-RPC 2.0 via `/rpc` routed to `hero_code_server` (do **not** introduce Dioxus or any new framework — the dashboard is a vanilla-JS Bootstrap SPA with tab panes in `index.html`). - Two new top-level tabs ("Contexts", "Agents") wired into the existing `nav-tabs-custom` bar and `.app-content` tab-pane pattern. - Repo list comes from existing `code.list` RPC (walks `CODEROOT`). A new `code.tree` RPC lazily lists directory children, filtered by the allowlist. - Allowlist extensions: `.py .rs .md .txt .ts .js .hero .hs .oschema .toml .json .yaml` — strict positive filtering (hidden dotfiles and `target/`, `node_modules/`, `.git/` are also skipped). - Contexts: persistent, editable, duplicatable, deletable, with render-to-text (prompt bundle) support. - Sessions: persistent, hold ordered attached context ids + chat-style message log + execution records. - Execution: builds the prompt bundle, posts a tagged nu job to hero_proc via `hero_proc_sdk` (`a 2 -i "<bundle + prompt>"`), records the returned `job_id`, and polls `job.*` on hero_proc for status/logs. - Persistence: SQLite, next to `hero_code.db` (new `hero_code_agents.db`) — matches the existing `hero_code_lib::db` pattern (WAL, `rusqlite`, schema in `model.rs`, API in `factory.rs`). Do **not** use Redis or the filesystem — the repo already ships SQLite for jobs/logs. - All new RPC methods dispatched from `crates/hero_code_server/src/rpc/mod.rs` and documented in `openrpc.json`. ### Files to Modify/Create **hero_code_lib (new persistence)** - `crates/hero_code_lib/src/db/contexts/mod.rs` — module wiring. - `crates/hero_code_lib/src/db/contexts/model.rs` — `Context` struct, CRUD functions, schema init. - `crates/hero_code_lib/src/db/sessions/mod.rs` — module wiring. - `crates/hero_code_lib/src/db/sessions/model.rs` — `PromptSession`, `ChatMessage`, `ExecutionRecord` structs + CRUD + schema init. - `crates/hero_code_lib/src/db/factory.rs` — MODIFY: open a second SQLite file (`hero_code_agents.db`) next to the main DB; add `pub contexts: ContextsApi` and `pub sessions: SessionsApi` fields on `HeroRunnerDb`. - `crates/hero_code_lib/src/db/mod.rs` — MODIFY: `pub mod contexts; pub mod sessions;`. **hero_code_server (RPC + Claude job launcher)** - `crates/hero_code_server/Cargo.toml` — MODIFY: add `hero_proc_sdk = { workspace = true }`. - `crates/hero_code_server/src/rpc/tree.rs` — new: `code.tree` (lazy, allowlist-filtered dir listing). - `crates/hero_code_server/src/rpc/context.rs` — new: `context.list`, `context.get`, `context.save`, `context.update`, `context.delete`, `context.render`. - `crates/hero_code_server/src/rpc/session.rs` — new: `session.list`, `session.create`, `session.update`, `session.delete`, `session.attach_context`, `session.detach_context`, `session.add_message`. - `crates/hero_code_server/src/rpc/agent.rs` — new: `agent.execute` (builds Claude nu job via `hero_proc_sdk`, records `ExecutionRecord`), `agent.execution_get`, `agent.execution_logs`. - `crates/hero_code_server/src/rpc/mod.rs` — MODIFY: register new methods. - `crates/hero_code_server/openrpc.json` — MODIFY: add new method definitions + component schemas. - `crates/hero_code_server/src/web.rs` — MODIFY: add new methods to `positional_to_named` mapping (optional — all new calls can mandate named params from JS to sidestep this). - `crates/hero_code_server/src/types/mod.rs` & `responses.rs` — MODIFY if needed to re-export new domain types. **hero_code_ui (dashboard tabs)** - `crates/hero_code_ui/templates/index.html` — MODIFY: add two `<a class="nav-link" data-tab="...">` entries and two new `<div class="tab-pane" id="tab-contexts">` / `id="tab-agents">` panes. - `crates/hero_code_ui/static/js/contexts.js` — new: Context Manager logic (repo picker → tree → selection → builder → save/list/edit/render/copy). - `crates/hero_code_ui/static/js/agents.js` — new: session list, chat view, attach contexts, execute, poll logs. - `crates/hero_code_ui/static/js/dashboard.js` — MODIFY: extend the tab-switch handler to call `contextsInit()` / `agentsInit()` on first activation (mirrors `codeInit()`). - `crates/hero_code_ui/static/css/dashboard.css` — MODIFY: minor additions for the tree, builder panel, and chat bubble layout (no new `<style>` blocks in templates). ### Implementation Plan #### Step 1: Data models + persistence Files: `crates/hero_code_lib/src/db/contexts/{mod,model}.rs`, `crates/hero_code_lib/src/db/sessions/{mod,model}.rs`, `crates/hero_code_lib/src/db/factory.rs`, `crates/hero_code_lib/src/db/mod.rs`. - Define in `contexts/model.rs`: ```rust pub struct Context { pub id: u32, pub name: String, pub description: Option<String>, pub selected_paths: Vec<String>, pub allowed_extensions: Vec<String>, pub created_at: u64, pub updated_at: u64, } ``` with `init_schema`, `insert`, `update`, `get`, `list`, `delete`. Store `selected_paths` and `allowed_extensions` as JSON TEXT columns. - Define in `sessions/model.rs`: ```rust pub struct PromptSession { pub id: u32, pub name: String, pub agent_id: String, pub attached_context_ids: Vec<u32>, pub created_at: u64, pub updated_at: u64, } pub struct ChatMessage { pub id: u32, pub session_id: u32, pub role: String, pub content: String, pub created_at: u64, pub execution_id: Option<u32>, } pub struct ExecutionRecord { pub id: u32, pub session_id: u32, pub agent_id: String, pub context_ids: Vec<u32>, pub runner_profile: String, pub hero_proc_job_id: i64, pub status: String, pub created_at: u64, pub finished_at: Option<u64>, } ``` with `init_schema`, CRUD, plus `list_messages(session_id)`, `list_executions(session_id)`, `update_execution_status(id, status, finished_at)`. - In `factory.rs`: open a second SQLite connection at `parent/hero_code_agents.db`, run schema init for both new tables, expose `pub contexts: ContextsApi`, `pub sessions: SessionsApi`. - Add unit tests mirroring the existing `test_namespaced_jobs_api` style. Dependencies: none. #### Step 2: Context RPC + directory tree RPC Files: `crates/hero_code_server/src/rpc/tree.rs`, `crates/hero_code_server/src/rpc/context.rs`, `crates/hero_code_server/src/rpc/mod.rs`. - `tree.rs` — `code.tree(params: { path: string })` returns `{ entries: [{name, path, kind: "dir"|"file", size?}] }` for one directory level, skipping hidden entries, `target/`, `node_modules/`, `.git/`, and files whose extension is not on the allowlist. Path must resolve under `CODEROOT`. - `context.rs`: - `context.list` → `{ contexts: [...] }`. - `context.get(id)` → full Context. - `context.save({ name, description?, selected_paths[], allowed_extensions? })` → created Context. - `context.update({ id, ... })`. - `context.delete({ id })`. - `context.render({ id })` → `{ text, file_count, byte_count }`. Expansion logic: 1. For each selected path, if file and ext allowed → include; if dir → walk recursively, allowlist-only; dedupe. 2. Determine `repo` prefix from `CODEROOT/<org>/<repo>/...`. 3. Sort stably by `(repo, relative_path)`. 4. Emit: ```` # Context: <name> ## File: <repo>/<relative_path> ```<ext> <file contents> ``` ```` 5. Skip files bigger than 512 KB with a warning line. - Wire in `rpc/mod.rs` dispatch. Dependencies: Step 1. #### Step 3: Session + execution RPC (Claude via hero_proc) Files: `crates/hero_code_server/src/rpc/session.rs`, `crates/hero_code_server/src/rpc/agent.rs`, `crates/hero_code_server/src/rpc/mod.rs`, `crates/hero_code_server/Cargo.toml`. - Add `hero_proc_sdk = { workspace = true }` in `hero_code_server/Cargo.toml`. - `session.rs` — CRUD + attach/detach/add_message against `db.sessions`. - `agent.rs`: - `agent.execute({ session_id, prompt, runner_profile? })`: 1. Load session + every attached context; call the render helper. 2. Concatenate: `render(ctx1)\n\n...\n\nrender(ctxN)\n\n# User Prompt\n\n<prompt>`. 3. Persist a `ChatMessage {role:"user", content: prompt}`. 4. Write the rendered bundle to `$HOME/hero/var/agents/<session_id>/<ts>.txt`. 5. Build a nu `ActionSpec` per `hero_proc_sdk_jobs_use`: - interpreter `nu`, tags `hero_code + agent + claude`, 10-min timeout, `no_retry`. - script: `use <HERO_AGENT_NU_PATH> *; let p = open "<bundle_path>"; a 2 -i $p`. 6. Submit via `hero_proc_sdk::hero_proc_factory().await?.job_create(...)`. 7. Record an `ExecutionRecord` with `hero_proc_job_id`, `status="pending"`. 8. Return `{ execution_id, job_id, status }`. - `agent.execution_get({ execution_id })` → fetch local record, live-poll hero_proc `job.get`, append the final agent message when the job terminates, return merged view. - `agent.execution_logs({ execution_id, lines? })` → proxy to hero_proc `job.logs`. - Wire in `rpc/mod.rs`. Dependencies: Step 1, Step 2. #### Step 4: OpenRPC spec updates Files: `crates/hero_code_server/openrpc.json`. - Add method entries + `$ref` component schemas for `Context`, `PromptSession`, `ChatMessage`, `ExecutionRecord`, and all new method params/results. Dependencies: Step 3. #### Step 5: UI — Contexts tab Files: `crates/hero_code_ui/templates/index.html`, `crates/hero_code_ui/static/js/contexts.js`, `crates/hero_code_ui/static/js/dashboard.js`, `crates/hero_code_ui/static/css/dashboard.css`. - `index.html`: - Add tab: `<a class="nav-link" data-tab="contexts" href="#/contexts"><i class="bi bi-folder-symlink"></i> Contexts</a>`. - Three-column pane (`#tab-contexts`): - Left: saved contexts list + "+ New". - Center: repo picker + tree (lazy-expand via `code.tree`), tri-state checkboxes, search filter. - Right: Builder panel — name, description, included-files count, estimated size, included-files list with per-row remove action, Save / Duplicate / Delete, "Copy rendered". - `contexts.js`: - `contextsInit()` loads contexts + repos. - `contextsExpandDir(path)` calls `code.tree`. - Multi-select state keyed by absolute path + directory-flag. - `contextsSave()`, `contextsLoad(id)`, `contextsRender(id)` → `navigator.clipboard.writeText(text)`. - `dashboard.js`: add `contexts` to the tab switch callback map. - `dashboard.css`: tree + tri-state checkbox styles using existing `--accent-*` CSS vars. Dependencies: Step 2. #### Step 6: UI — Agents tab Files: `crates/hero_code_ui/templates/index.html`, `crates/hero_code_ui/static/js/agents.js`, `crates/hero_code_ui/static/js/dashboard.js`, `crates/hero_code_ui/static/css/dashboard.css`. - `index.html`: - Tab: `<a class="nav-link" data-tab="agents" href="#/agents"><i class="bi bi-robot"></i> Agents</a>`. - Three-column pane (`#tab-agents`): left = sessions list + "+ New"; center = chat + prompt textarea + "Run"; right = attached contexts (up/down reorder + "Add context" dropdown) + live execution status panel with log tail. - `agents.js`: - `agentsInit()` loads `session.list`. - `agentsSelectSession(id)` renders messages, attached contexts, resumes polling of any in-flight execution. - `agentsRun()` calls `agent.execute`, polls `agent.execution_get` every 1s and `agent.execution_logs` every 500ms until terminal. - `dashboard.js`: register `agents` in the tab callback map. - `dashboard.css`: chat bubbles + log tail `<pre>` styling. Dependencies: Step 3, Step 5. #### Step 7: Tests + smoke Files: unit tests inline in new modules. - Unit tests: Context/PromptSession CRUD; `context.render` exact format (fence, stable sort, allowlist filter). - Unit test for the nu-script builder in `agent.rs` (no real hero_proc — assert the script string and tags). - Manual smoke: start `hero_code --start`, open the UI, create a repo-scoped context, save it, create a session, attach, execute "say hello", verify the job appears in `hero_proc_ui` with tag `hero_code+agent+claude` and the agent stdout lands back in the chat. Dependencies: Steps 1–6. ### Acceptance Criteria - [ ] Two new tabs "Contexts" and "Agents" are visible in the dashboard and survive page reloads via the hash router. - [ ] Under "Contexts": existing `CODEROOT` repos appear; clicking a directory lazily expands via `code.tree`; only allowlisted files are shown. - [ ] Tri-state selection works: partial when some children are selected, full when all are, clearing a parent clears descendants. - [ ] Saving a context persists it (SQLite, survives restart); Duplicate creates a new record with suffix " (copy)"; Delete removes it. - [ ] "Copy rendered" emits the exact markdown format from the issue. - [ ] Under "Agents": a session can be created, have >=1 context attached, a prompt typed, and "Run" clicked. - [ ] Running a prompt creates a hero_proc job tagged `hero_code + agent + claude`, returns a `job_id`, and that job appears in `hero_proc_ui` at `#jobs/<id>`. - [ ] The execution status updates from `pending -> running -> succeeded/failed` by polling `agent.execution_get`; live log tail appears while running. - [ ] On job termination, the agent's stdout is persisted as a `role:"agent"` ChatMessage and displayed in the chat history. - [ ] All new endpoints are listed in `openrpc.json` and reachable via `POST /rpc`. - [ ] `cargo check -p hero_code_lib -p hero_code_server -p hero_code_ui` passes with no new warnings; existing tests still green. ### Notes **Persistence choice.** SQLite via `rusqlite` — the workspace already ships it for `hero_code_lib::db`. A second DB file (`hero_code_agents.db`) next to `hero_code.db` reuses the factory idiom and avoids introducing sled, hero_db, or filesystem JSON. Redis (`code_db`) is only a cache/metadata store and is not a good fit for structured, queryable entities like contexts/sessions. **UI framework choice.** The repo is vanilla JS + Bootstrap + Askama (see `templates/index.html`, `static/js/*.js`, existing tabs: Forge, IDE, Jobs, Logs, Docs, Admin, Perf, Stats). Adding Contexts and Agents tabs follows the same recipe as the existing `code_manage.js`. No new UI framework. **RPC routing.** `hero_code_ui` no longer proxies `/rpc` — the router sends `/rpc` directly to `hero_code_server`'s Unix socket. New methods only need to be implemented in `hero_code_server/src/rpc/*`. **hero_proc integration.** The `hero_code` CLI already uses `hero_proc_sdk` to register its own service. The same SDK is reused inside `agent.rs` to submit Claude jobs, following the `hero_proc_sdk_jobs_use` recipe verbatim. The agent.nu path is read from `HERO_AGENT_NU_PATH` with a sensible default. **Prompt size handling.** A rendered bundle can easily exceed 1 MB and break shell quoting. The bundle is written to `$HOME/hero/var/agents/<session_id>/<ts>.txt` and the nu script reads it with `open <path>`. Bundles remain on disk for post-mortem inspection. **Scope cut for v1 (this PR).** Dropped from the MVP: token-count estimation (only file-count + byte-count), non-Claude agents, runner-profile selection (hardcode "A0"), drag-drop reorder for attached contexts (up/down buttons instead), inline message editing. **Follow-ups (explicitly deferred, not steps):** - Token counting via a real tokenizer. - Runner profiles A0/A1/A2 with different Claude models. - Context tree virtualization for very large monorepos. - SSE streaming from hero_proc for zero-latency agent tokens. - Semantic search / git-diff-aware contexts. - Export/import contexts as JSON.
Author
Owner

Test Results

  • Total: 40+
  • Passed: all
  • Failed: 0

cargo test completed successfully. All unit tests pass including:

  • db::contexts::model — context CRUD roundtrip, default extensions
  • db::sessions::model — session/message ordering, execution lifecycle
  • db:🏭:tests — factory creation and namespaced APIs
  • db::rpc::tests — job submit/get, logs, engine info, discover
  • db::jobs::model — job status, pagination, filter, purge
  • db::logs::model — log insert/query/delete/count/sources
## Test Results - Total: 40+ - Passed: all - Failed: 0 `cargo test` completed successfully. All unit tests pass including: - db::contexts::model — context CRUD roundtrip, default extensions - db::sessions::model — session/message ordering, execution lifecycle - db::factory::tests — factory creation and namespaced APIs - db::rpc::tests — job submit/get, logs, engine info, discover - db::jobs::model — job status, pagination, filter, purge - db::logs::model — log insert/query/delete/count/sources
Author
Owner

Implementation Summary

All planned steps have been implemented.

Changes made

New files:

  • crates/hero_code_lib/src/db/contexts/ — Context data model and SQLite CRUD (stored in hero_code_agents.db)
  • crates/hero_code_lib/src/db/sessions/ — PromptSession, ChatMessage, ExecutionRecord models and SQLite CRUD
  • crates/hero_code_server/src/rpc/context.rs — JSON-RPC handlers: context.list/get/save/update/delete/render
  • crates/hero_code_server/src/rpc/tree.rs — JSON-RPC handler: code.tree (directory listing under CODEROOT)
  • crates/hero_code_server/src/rpc/session.rs — JSON-RPC handlers: session.list/get/save/update/delete/messages/message_add + agent.execute/execution_get/execution_logs
  • crates/hero_code_ui/static/js/contexts.js — Contexts tab UI: file tree, multi-select, save/edit/delete contexts, copy rendered bundle
  • crates/hero_code_ui/static/js/agents.js — Agents tab UI: session list, chat history, prompt input, context attachment, execution polling

Modified files:

  • crates/hero_code_lib/src/db/factory.rs — Added ContextsApi and SessionsApi to HeroRunnerDb, opened hero_code_agents.db
  • crates/hero_code_lib/src/db/mod.rs — Exposed contexts and sessions modules
  • crates/hero_code_server/src/rpc/mod.rs — Registered all new RPC routes
  • crates/hero_code_server/src/web.rs — Minor cleanup
  • crates/hero_code_server/Cargo.toml — Added hero_proc_sdk dependency
  • crates/hero_code_server/openrpc.json — Added code.tree, context., session., agent.* methods and schema types
  • crates/hero_code_ui/templates/index.html — Added Contexts and Agents tab links and panes
  • crates/hero_code_ui/static/js/dashboard.js — Added switchTab cases for contexts and agents

Key design decisions

  • Contexts and sessions stored in a separate SQLite file (hero_code_agents.db) to avoid contention with job state
  • agent.execute writes the rendered context bundle to $HOME/hero/var/agents/<session_id>/.txt and submits a nu job to hero_proc tagged hero_code+agent+claude
  • agent.execution_get polls hero_proc live for job phase, updates the local execution record when terminal
  • Context rendering walks selected_paths recursively, applies the allowlist, and produces a stable markdown bundle sorted by (repo, path)
## Implementation Summary All planned steps have been implemented. ### Changes made **New files:** - `crates/hero_code_lib/src/db/contexts/` — Context data model and SQLite CRUD (stored in hero_code_agents.db) - `crates/hero_code_lib/src/db/sessions/` — PromptSession, ChatMessage, ExecutionRecord models and SQLite CRUD - `crates/hero_code_server/src/rpc/context.rs` — JSON-RPC handlers: context.list/get/save/update/delete/render - `crates/hero_code_server/src/rpc/tree.rs` — JSON-RPC handler: code.tree (directory listing under CODEROOT) - `crates/hero_code_server/src/rpc/session.rs` — JSON-RPC handlers: session.list/get/save/update/delete/messages/message_add + agent.execute/execution_get/execution_logs - `crates/hero_code_ui/static/js/contexts.js` — Contexts tab UI: file tree, multi-select, save/edit/delete contexts, copy rendered bundle - `crates/hero_code_ui/static/js/agents.js` — Agents tab UI: session list, chat history, prompt input, context attachment, execution polling **Modified files:** - `crates/hero_code_lib/src/db/factory.rs` — Added ContextsApi and SessionsApi to HeroRunnerDb, opened hero_code_agents.db - `crates/hero_code_lib/src/db/mod.rs` — Exposed contexts and sessions modules - `crates/hero_code_server/src/rpc/mod.rs` — Registered all new RPC routes - `crates/hero_code_server/src/web.rs` — Minor cleanup - `crates/hero_code_server/Cargo.toml` — Added hero_proc_sdk dependency - `crates/hero_code_server/openrpc.json` — Added code.tree, context.*, session.*, agent.* methods and schema types - `crates/hero_code_ui/templates/index.html` — Added Contexts and Agents tab links and panes - `crates/hero_code_ui/static/js/dashboard.js` — Added switchTab cases for contexts and agents ### Key design decisions - Contexts and sessions stored in a separate SQLite file (hero_code_agents.db) to avoid contention with job state - agent.execute writes the rendered context bundle to $HOME/hero/var/agents/<session_id>/<ts>.txt and submits a nu job to hero_proc tagged hero_code+agent+claude - agent.execution_get polls hero_proc live for job phase, updates the local execution record when terminal - Context rendering walks selected_paths recursively, applies the allowlist, and produces a stable markdown bundle sorted by (repo, path)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_code#8
No description provided.