Metadata-Version: 2.4
Name: ironsilk
Version: 0.9.13
Summary: Domain/workspace context management — Hermes Navigator v1 (published under ironsilk codename)
License: MIT
Keywords: context,domain,hermes,ironsilk,miadi,navigator,tmux,workspace
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.11
Requires-Dist: aiosqlite>=0.20
Requires-Dist: click>=8.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0
Provides-Extra: controller
Requires-Dist: libtmux>=0.28; extra == 'controller'
Provides-Extra: daemon
Requires-Dist: watchdog>=4.0; extra == 'daemon'
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: studio
Requires-Dist: textual>=0.50; extra == 'studio'
Provides-Extra: telegram
Requires-Dist: httpx>=0.27; extra == 'telegram'
Requires-Dist: python-telegram-bot>=21.0; extra == 'telegram'
Description-Content-Type: text/markdown

# ironsilk — Domain/Workspace Context Management
<!-- Ref: jgwill/Miadi#265 -->

> **Naming note** — `ironsilk` is the PyPI codename for this package during the
> active refactoring phase of the platform. The underlying runtime was developed
> as `hermes-navigator` (now deprecated → https://pypi.org/project/hermes-navigator/).
> The final product identity and package name are not yet settled.
> `tide` is the canonical CLI entry point. The Python import path
> (`hermes_navigator`) is unchanged until a deliberate import migration is
> planned.
> Once the product name is confirmed, `ironsilk` will transition to the canonical name.
>
> **State-root note** — `~/.hermes` is also transitional. A product-owned
> dotfolder such as `~/.ironsilk` or `~/.miadi` must still be chosen before
> this becomes a durable user-state contract. Workspace/project config now
> lives at `.miadi/tide.yaml`.

### Naming Migration Debt

| Identifier | Classification | Decision Surface |
| --- | --- | --- |
| `hnavig` CLI | Delete/rename now | not published as a console alias |
| `runtime/hermes-navigator` | Migration debt | repository path/package layout |
| `hermes_navigator` | Migration debt | Python import/module path |
| `HNAVIG_HOME` / `HERMES_HOME` | Migration debt | state-root env vars |
| `~/.hermes` | Migration debt | current default state root; likely Miadi-owned replacement |
| `.miadi/tide.yaml` | Current contract | workspace/project config filename |
| `hermes-navigator.service` | Migration debt | user-service unit name |


## description
`ironsilk` currently ships the historical Hermes Navigator implementation behind
the `tide` CLI. It gives William (and any local Hermes-class agent) instant
orientation across active development domains and many terminal surfaces.

## What It Does

- **R1 — Domain Detection:** Auto-detects which domain each terminal/tmux pane belongs to, using a priority chain of signals (env var → tmux name → git remote → path prefix → heuristic)
- **R4 — Terminal Focus:** Lists or switches tmux focus to a domain's terminal group
- **R2 — Context Engine:** Always-on background collector that builds a queryable snapshot of all terminal activity, scoped by domain
- **R5 — Approval Queue:** Proposed terminal actions flow through a review queue before execution
- **R7 — Session Store:** Named persistent sessions resumable from desktop or Telegram (`/resume <name>`)
- **R8 — Skill Interface:** Packaged as a Hermes skill, callable from any Hermes-class agent

**Issue:** [jgwill/Miadi#265](https://github.com/jgwill/Miadi/issues/265)

---

## Quick Start

```bash
# Install
cd runtime/hermes-navigator
pip install -e .

# Configure domains
mkdir -p ~/.hermes
cp examples/domains.yml ~/.hermes/domains.yml
# Edit ~/.hermes/domains.yml to match your domain roots

# Detect domain for current directory
tide detect

# Detect for a specific path
tide detect --cwd ~/src/Miadi

# List terminals for a domain
tide focus miadi

# Show context snapshot
tide context

# Start background daemon
tide daemon

# Install/start as a user service
tide service install --interval 15 --now

# Release/install smoke gate
tide doctor --release-target 0.9.7

# Operator cockpit: know/enter existing tmux work
tide operator terminals
tide operator peek 7 --lines 80
tide operator attach 7
tide operator registry save
tide operator registry last-known
tide operator registry drift
tide operator checkpoint
tide operator checkpoint --write
tide operator steer-proposal 7 --message "continue from the visible prompt"
tide session new ava-260512 --cwd /usr/local/src/ironsilk
tide session attach ava-260512
```

## Fast Demo Path For This Branch

Want to try the workspace/context slice without touching your real
`~/.hermes` state?

```bash
cd runtime/hermes-navigator
pip install -e .
./examples/demo-miadi-workspace.sh /usr/local/src/mightyeagle
```

What this does:
- sets `HNAVIG_HOME` to an isolated temp directory
- writes a one-domain config pointed at the repo you pass in
- captures a persisted context snapshot when the demo scene is frozen
- runs `detect`, `ecf observe`, `scene activate`, `scene list`, `scene snapshot`, and `scene resume`
- leaves the generated SQLite/files behind so you can inspect them after the run

You can also point the runtime at any alternate state directory yourself:

```bash
export HNAVIG_HOME=/tmp/tide-demo
tide detect --cwd /usr/local/src/mightyeagle
```

---

## Configuration

### `~/.hermes/domains.yml` — Domain Registry

```yaml
domains:
  - name: miadi
    aliases: [main, mia]
    roots:
      - ~/src/Miadi
      - ~/work/Miadi
    remotes:
      - "github.com/jgwill/Miadi"
    env_var: "MIADI_DOMAIN"
    tmux_pattern: "miadi-*"

  - name: aureon
    aliases: [aur]
    roots:
      - ~/src/aureon
    remotes:
      - "github.com/jgwill/aureon"
    tmux_pattern: "aureon-*"
```

See `examples/domains.yml` for a full example.

### `~/.hermes/config.yml` — Navigator Config

```yaml
mode: observer           # observer | controller
daemon_interval: 5.0     # seconds between context polls
session_db: ~/.hermes/sessions.db
context_log: ~/.hermes/context/log.ndjson
domains_config: ~/.hermes/domains.yml
```

See `examples/config.yml` for full options.

---

## Commands

The examples below use the canonical `tide` CLI.

### Detection

```bash
# Detect domain for current directory
tide detect

# Detect for specific cwd
tide detect --cwd ~/src/Miadi

# Detect for specific tmux pane
tide detect --pane %42

# Detect all panes in current tmux session
tide detect --all-panes
```

### Focus (R4)

```bash
# List terminals for a domain (observer mode)
tide focus miadi

# List matching desktop terminal windows (Terminator/Konsole/etc.)
tide focus miadi --desktop
tide focus miadi --desktop --format json

# Activate a matching desktop window (controller mode + approval required)
tide mode controller
tide focus miadi --desktop --activate
tide focus miadi --desktop --activate --window-id 0x00eaf0d8

# Activate tmux focus to domain pane group (controller mode required)
tide mode controller
tide focus miadi
```

### Operator Cockpit

These commands are the first "avoid context rot" surface. They are deliberately
small: list the live tmux targets, inspect recent scrollback without attaching,
and print the exact attach/switch commands before changing focus.

```bash
# List existing tmux sessions/panes and their attach commands
tide operator terminals
tide operator terminals --format json

# Inspect what is happening in a session or pane without attaching
tide operator peek 7 --lines 80
tide operator peek %7 --format json

# Print the commands for entering a target
tide operator attach 7

# Execute attach/switch from an interactive controller terminal
tide mode controller
tide operator attach 7 --run

# Persist terminal awareness as append-only JSONL
tide operator registry save
tide operator registry last-known
tide operator registry drift

# One read-only "know before entering" checkpoint
tide operator checkpoint
tide operator checkpoint --target 7 --peek-lines 20
tide operator checkpoint --format json
tide operator checkpoint --write
tide operator checkpoint --target 7 --peek-lines 20 --write

# Human-reviewable follow-up proposal; no send is performed
tide operator steer-proposal 7 --message "continue from the visible prompt"
tide operator steer-proposal 7 --message-file prompt.md --write
tide operator steer-proposal 7 --message "continue" --peek-lines 40
tide operator steer-proposal 7 --message "continue" --format json
```

The registry is a read-only awareness surface after capture: `save` appends a
timestamped snapshot under the Navigator state directory, `last-known` reads the
newest persisted snapshot, and `drift` compares current tmux state with that
snapshot. It stores observed tmux fields separately from inferred Navigator
fields such as domain and attach commands.

`operator checkpoint` combines current terminals, the last-known registry
metadata, drift summary, stale/last-seen hints, and safe entry commands. It does
not capture scrollback unless `--target` is provided.

Add `--write` to save a portable Markdown and JSON handoff under
`HNAVIG_HOME/operator/checkpoints/`. This serializes the same checkpoint report;
it does not attach, resume, or mutate terminals.

`operator steer-proposal` creates a reviewed-message artifact for a specific
target. It prints manual `tmux send-keys` suggestions only; Navigator does not
send input, attach, resume, or require controller mode.

### Context (R2)

```bash
# Show full context snapshot
tide context

# Filter by domain
tide context --domain miadi

# JSON output
tide context --format json

# Context from last 30 minutes
tide context --since 30m
```

### Sessions (R7)

```bash
# Tmux-style named session plan (dry-run by default)
tide session new ava-260512 --cwd /usr/local/src/ironsilk
tide session attach ava-260512

# Execute from a local human-controlled terminal
tide mode controller
tide session new ava-260512 --cwd /usr/local/src/ironsilk --run
tide session attach ava-260512 --run

# Create a named session
tide session create aureon-refactor-2025

# Resume a session
tide session resume aureon-refactor-2025

# List all sessions
tide session list

# Archive a session
tide session archive aureon-refactor-2025
```

`session new` and `session attach` are tmux-backed verbs for the v0.7.0
Hermes-Agent CLI base. They print exact tmux commands by default; execution
requires `ACTIVE_CONTROLLER` mode and an interactive local terminal.

### Doctor / Release Gate

```bash
tide doctor
tide doctor --release-target 0.9.7 --strict
tide doctor --release-target 0.9.7 --require-daemon --strict
```

`doctor` checks package version, state/config shape, tmux availability, daemon
ping/context readiness, user service hints, and the operator/session CLI
surfaces needed before workspace registry work.

### Mode

```bash
# Check current mode
tide mode

# Switch to active controller (enables tmux actions)
tide mode controller

# Switch back to observer (safe default)
tide mode observer
```

### Daemon

```bash
# Start daemon (blocks; use & or a process manager)
tide daemon

# Start with custom poll interval
tide daemon --interval 10

# Scene launch opens a terminal/editor for a stored workspace. On systems with
# Terminator installed, Navigator prefers Terminator for new terminal windows.
tide scene activate /path/to/project --launch

# Daemon writes to:
#   ~/.hermes/context/latest.json    (last snapshot)
#   ~/.hermes/context/log.ndjson     (rolling log)
#   ~/.hermes/daemon.pid             (PID file)
```

### User Service

The ironsilk daemon should run as a **user service**, not a root/system service.
It observes your user terminals, desktop windows, tmux panes, and user-owned
state. The service writes a systemd user unit at
`~/.config/systemd/user/hermes-navigator.service`.

```bash
# Install and start immediately
tide service install --interval 15 --now

# If you want an explicit isolated runtime state:
tide service install --interval 15 --state-home ~/.local/state/hermes-navigator --now

# Control it later
tide service status
tide service restart
tide service stop
tide service uninstall
```

If `~/.hermes` exists but is not accessible to your current user, Navigator
falls back to `~/.local/state/hermes-navigator`. If `systemctl --user` is
unavailable, keep using `tide daemon` in a terminal or a local process manager
until the desktop session imports user services.

### Desktop App / Overlay

There is not yet a real floating Hermes window. The current working surfaces
are:

- `tide context` — current daemon snapshot, including desktop windows
- `tide focus <domain> --desktop` — matching terminal windows
- `tide session ...` — named session continuity
- `app/docs/miadi-agent/navigator` — an interactive docs/mock UI that shows the
  intended overlay, approval queue, sessions, and Telegram continuity story

The desktop overlay is specified in
`rispecs/hermes-navigator/05-ui-surface.spec.md`, but implementation remains the
next product step.

---

## Architecture Overview

```
domains.yml ──► DomainDetector ──► ContextEngine ──► Daemon
                                              │
                                     ┌────────┼─────────┐
                                     │        │         │
                                 SessionStore  ApprovalQ  Focus
                                     │
                                    CLI (tide)
```

**Data flow (Phase 1):**
1. `DomainDetector` reads `domains.yml` and detects domain identity for tmux panes
2. `ContextEngine` polls tmux and desktop windows every N seconds and builds `ContextSnapshot`
3. `Daemon` runs `ContextEngine.start_continuous()` and writes to `~/.hermes/`
4. `tide` commands query the daemon or directly invoke detection/focus

---

## Integration with Hermes Skill Ecosystem

The navigator is packaged as a Hermes skill at `skills/navigator.skill.yml`. Any Hermes-class agent can load this manifest and call:

- `navigator.focus(domain)` — list or activate domain terminal group
- `navigator.context(domain?, format?)` — get context snapshot
- `navigator.propose(action)` — queue a terminal action for approval
- `navigator.session.resume(name)` — rehydrate a named session
- `navigator.session.list()` — list all sessions

See `rispecs/hermes-navigator/04-skill-contract.spec.md` for full action definitions.

---

## Development

```bash
# Install in development mode
pip install -e ".[dev]"

# Run directly
python -m hermes_navigator.cli --help

# Use the installed console entry point.
tide --help
```

### Project Structure

```
runtime/hermes-navigator/
├── hermes_navigator/
│   ├── __init__.py         # package init
│   ├── models.py           # data models
│   ├── config.py           # config management
│   ├── domain_detector.py  # R1 — domain detection
│   ├── context_engine.py   # R2 — always-on context
│   ├── session_store.py    # R7 — named sessions (SQLite)
│   ├── focus.py            # R4 — terminal focus
│   ├── approval_queue.py   # R5 — action approval
│   ├── daemon.py           # background daemon
│   └── cli.py              # tide CLI
├── skills/
│   └── navigator.skill.yml  # Hermes skill manifest
├── examples/
│   ├── domains.yml        # example domain config
│   └── config.yml           # example navigator config
├── pyproject.toml
└── README.md
```

---

## Specs

- Master: `rispecs/hermes-navigator/00-hermes-navigator-master.spec.md`
- Domain Detection: `rispecs/hermes-navigator/01-domain-detection.spec.md`
- Context Engine: `rispecs/hermes-navigator/02-context-engine.spec.md`
- Session Store: `rispecs/hermes-navigator/03-session-store.spec.md`
- Skill Contract: `rispecs/hermes-navigator/04-skill-contract.spec.md`
- UI Surface: `rispecs/hermes-navigator/05-ui-surface.spec.md`
- Daemon Lifecycle: `rispecs/hermes-navigator/06-daemon-lifecycle.spec.md`
- Mode And Safety: `rispecs/hermes-navigator/07-mode-and-safety.spec.md`
- Threat Model: `rispecs/hermes-navigator/08-threat-model.spec.md`
- Telegram Bridge: `rispecs/hermes-navigator/09-telegram-bridge.spec.md`
- Domain Relational Graph: `rispecs/hermes-navigator/10-domain-relational-graph.spec.md`
- Status: `rispecs/hermes-navigator/STATUS.md`
