530 lines
23 KiB
Markdown
530 lines
23 KiB
Markdown
# harness-tools
|
|
|
|
Personal [Pi](https://github.com/earendil-works/pi-mono) extensions, skills, global agent instructions, sandbox profiles, and supporting services.
|
|
|
|
## What this repository installs
|
|
|
|
[`config/pi-links.json`](config/pi-links.json) is the source of truth for the normal installation. The link manager exposes:
|
|
|
|
- global agent instructions for Pi, Codex, and Claude;
|
|
- 35 shared skills under `~/.agents/skills/`, including the model-invoked [`develop-workflow`](skills/develop/develop-workflow/SKILL.md) skill;
|
|
- the `manage-pi-links` and `nono-profiles` project-only skills under `.pi/skills/`;
|
|
- no global Pi extension symlinks. Active extensions are installed separately as pinned Gitea npm packages.
|
|
|
|
The repository contains `bash-cwd`, `copy-all`, `dictate` (Linux host-service dictation), `effort-controls`, `fast-browser` (experimental local JEV browser control), `file-search`, `interactive-subagents`, `lm-studio`, `native-hooks`, `prompt-snippets`, `subagents`, `todo-herdr`, and `update`. The link manifest does not install any extension globally. New feature work uses `develop-workflow`; both legacy workflow implementations are retained under [`__archived/extensions/`](__archived/extensions/README.md) per [ADR 0007](docs/adr/0007-archive-legacy-workflows-05SEP2026.md). The `pptx`, `stop-slop`, `subagents`, and `xlsx` skills are intentionally excluded. Archived resources under `__archived/` are never installed. Update `config/pi-links.json` deliberately if that policy changes.
|
|
|
|
The unpublished [`fast-browser` prototype](extensions/fast-browser/README.md) runs caller-bounded local-browser tests with JEV candidate selection, optional Pi-model text generation, and local test credentials. It supports unattended automation, file/TUI/per-call settings, isolated Chromium-family browser sessions or explicit CDP attachment, and exclusively locked named profiles with manual sign-in setup. See the [feasibility review](docs/browser-use-jev-feasibility.md) and [prototype plan](docs/fast-browser-prototype-plan.md).
|
|
|
|
## Fresh-machine setup
|
|
|
|
The commands below reproduce the normal setup. They assume Linux, a systemd user session, and the current canonical checkout path. Pi and the shared skills work on other platforms, but the nono launcher and Dictate sections are Linux-specific.
|
|
|
|
### 1. Install the base tools
|
|
|
|
Required:
|
|
|
|
- Git with access to `git.jb.codes`;
|
|
- Node.js 22.19 or newer;
|
|
- Bun 1.3.14 or newer;
|
|
- Pi Coding Agent;
|
|
- a configured model provider.
|
|
|
|
Install Pi using its official npm package:
|
|
|
|
```bash
|
|
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
|
|
pi --version
|
|
```
|
|
|
|
A Bun global install also works, but record its executable path later when configuring `pi-sbx`.
|
|
|
|
Start Pi once and authenticate with a subscription or API-key provider:
|
|
|
|
```bash
|
|
pi
|
|
```
|
|
|
|
Run `/login` inside Pi. Pi stores its user state under `${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}`. When Pi runs through nono, prefer nono credential routes so real API keys do not enter the sandbox; see [Sandboxed Pi credentials](#sandboxed-pi-credentials).
|
|
|
|
### 2. Clone the repository
|
|
|
|
Several current profiles and instruction imports contain `/srv/data/code/harness-tools`, so using that path requires no repository edits:
|
|
|
|
```bash
|
|
if [ ! -e /srv/data/code ]; then
|
|
sudo install -d -o "$USER" -g "$(id -gn)" /srv/data/code
|
|
fi
|
|
test -d /srv/data/code && test -w /srv/data/code || {
|
|
echo '/srv/data/code already exists but is not a writable directory' >&2
|
|
exit 1
|
|
}
|
|
|
|
git clone ssh://git@git.jb.codes:7722/jb/harness-tools.git \
|
|
/srv/data/code/harness-tools
|
|
cd /srv/data/code/harness-tools
|
|
```
|
|
|
|
The setup creates `/srv/data/code` only when absent. If it already exists, keep its current ownership and obtain access through the machine's normal administration policy.
|
|
|
|
If the checkout lives elsewhere, replace the machine-specific paths before syncing:
|
|
|
|
- `docs/global.CLAUDE.md`;
|
|
- `profiles/nono/pi-local.json`;
|
|
- `profiles/nono/pi-orca-local.json`;
|
|
- `profiles/nono/pi-work.json`;
|
|
- the copied `~/.config/pi-sbx/config.json` described below.
|
|
|
|
Dictate currently targets `/run/user/1000/pi-dictate.sock` in both the extension and profile. It therefore expects UID 1000. Change and review the socket path before installation if `id -u` reports another UID.
|
|
|
|
### 3. Install repository dependencies
|
|
|
|
The monorepo's typechecking, tests, packaging, and extension development require its Bun dependencies even though extensions ship as TypeScript source:
|
|
|
|
```bash
|
|
cd /srv/data/code/harness-tools
|
|
bun install --frozen-lockfile
|
|
bun run typecheck
|
|
```
|
|
|
|
Use `bun install --frozen-lockfile` after pulling a lockfile change and plain `bun install` only when intentionally updating [`bun.lock`](bun.lock). Node.js and Bun must satisfy the versions in [`package.json`](package.json).
|
|
|
|
### 4. Install instructions and skills
|
|
|
|
Preview the exact changes first, then apply them:
|
|
|
|
```bash
|
|
cd /srv/data/code/jb-pi/harness-tools
|
|
./scripts/pi-links.mjs sync --dry-run
|
|
./scripts/pi-links.mjs sync
|
|
./scripts/pi-links.mjs check
|
|
```
|
|
|
|
A successful check currently reports 39 links and zero local package entries. The manager:
|
|
|
|
- preserves unrelated global resources;
|
|
- refuses to overwrite regular files, directories, or links owned outside this repository;
|
|
- uses absolute links for global resources and relative links for project-only skills.
|
|
|
|
Resolve any reported collision manually instead of deleting it blindly. Run `/reload` in an active Pi session, or restart Pi, after the sync.
|
|
|
|
The repository root is a private Bun workspace and is not installable as a Pi package. The curated `config/pi-links.json` policy manages instructions and skills but deliberately exposes no extension symlinks. Install published `@jbcode/pi-*` packages for normal use; use explicit local paths only for temporary development. See [Bun workspace packages and Gitea npm publishing](docs/npm-packages.md).
|
|
|
|
### 5. Verify Pi
|
|
|
|
Install the desired pinned packages from [Optional Pi packages from Gitea](#optional-pi-packages-from-gitea), then start Pi:
|
|
|
|
```bash
|
|
pi
|
|
```
|
|
|
|
Inside Pi:
|
|
|
|
1. Run `/reload`.
|
|
2. Confirm `/effort` and `/snippets` are available.
|
|
3. Ask Pi to list its available skills and confirm a shared skill such as `tdd` appears.
|
|
4. From this repository, confirm the project-only `manage-pi-links` and `nono-profiles` skills appear.
|
|
|
|
## Optional Pi packages from Gitea
|
|
|
|
The currently published and deployed extension set is:
|
|
|
|
- `@jbcode/pi-dictate@0.2.0`;
|
|
- `@jbcode/pi-effort-controls@0.1.0`;
|
|
- `@jbcode/pi-prompt-snippets@0.1.0`;
|
|
- `@jbcode/pi-interactive-subagents@3.7.3`;
|
|
- `@jbcode/pi-todo-herdr@0.2.5`.
|
|
|
|
[`@jbcode/pi-bash-cwd`](extensions/bash-cwd) is an unpublished compatibility package for Pi 0.84.x. It adds a validated optional `cwd` argument to the built-in `bash` tool so commands can target hidden worktrees and nested packages without an inline `cd`. Keep using explicit directory proofs for Git worktree mutations even with the override installed.
|
|
|
|
Configure the scoped Gitea npm registry and install only the packages you want. Keep the token in the user environment or user-level npm configuration; never commit it:
|
|
|
|
```ini
|
|
@jbcode:registry=https://git.jb.codes/api/packages/jb/npm/
|
|
//git.jb.codes/api/packages/jb/npm/:_authToken=${GITEA_NPM_TOKEN}
|
|
```
|
|
|
|
```bash
|
|
pi install npm:@jbcode/pi-dictate@0.2.0
|
|
pi install npm:@jbcode/pi-effort-controls@0.1.0
|
|
pi install npm:@jbcode/pi-prompt-snippets@0.1.0
|
|
pi install npm:@jbcode/pi-interactive-subagents@3.7.3
|
|
pi install npm:@jbcode/pi-todo-herdr@0.2.5
|
|
pi list
|
|
```
|
|
|
|
Restart Pi or run `/reload` afterward. These package entries remain independent of `config/pi-links.json`, so `./scripts/pi-links.mjs check` still reports zero local package entries.
|
|
|
|
Do not globally enable `harness-tools/extensions/subagents` at the same time as `pi-interactive-subagents`. They provide overlapping subagent tools. The curated harness-tools manifest leaves its in-repository implementation disabled for this reason.
|
|
|
|
### Configure interactive subagents
|
|
|
|
[`@jbcode/pi-interactive-subagents`](extensions/interactive-subagents) creates asynchronous child Pi sessions in Herdr tabs or tmux panes. It requires one terminal backend:
|
|
|
|
- **Herdr:** install its Pi integration, then launch Pi inside a Herdr-managed pane;
|
|
- **tmux:** launch Pi inside tmux when Herdr is unavailable.
|
|
|
|
For Herdr:
|
|
|
|
```bash
|
|
herdr integration install pi
|
|
herdr integration status
|
|
herdr
|
|
```
|
|
|
|
Start Pi in a Herdr pane. The extension detects `HERDR_ENV=1` and opens each subagent in an unfocused tab. The `pi-local` nono profile already declares the reviewed Herdr socket used on the original machine; update that machine-specific path if necessary.
|
|
|
|
For tmux:
|
|
|
|
```bash
|
|
tmux new -A -s pi 'pi'
|
|
```
|
|
|
|
The package bundles `scout`, `researcher`, and `worker` agent definitions. Their configured provider, model, thinking level, and tool allowlist live in the package's `agents/` directory. Authenticate the configured provider and confirm the named model is available. To override a bundled definition without editing Pi's managed Git clone, create a same-named file in `${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}/agents/` or a trusted project's `.pi/agents/`; project definitions take precedence over global definitions, which take precedence over package definitions.
|
|
|
|
Inside Pi, verify and try the extension:
|
|
|
|
1. Run `/reload`.
|
|
2. Ask Pi to call `subagents_list`.
|
|
3. Confirm `scout`, `researcher`, and `worker` are listed.
|
|
4. Run `/subagent scout Summarize this repository` from a disposable test checkout.
|
|
5. Confirm a Herdr tab or tmux pane opens and the completed result returns to the parent session.
|
|
|
|
The status widget is enabled by the package's example configuration when no local `config.json` exists. Copy and edit `config.json.example` beside the installed package only when a status override is needed. Treat Pi's managed package installation as disposable because package updates may reset it; prefer global or project agent overrides for durable customization.
|
|
|
|
### Configure Native Hooks
|
|
|
|
[`@jbcode/pi-native-hooks`](extensions/native-hooks) coordinates trusted personal diagnostic and verification policies after workspace mutations. Review its [trust model and initialization workflow](extensions/native-hooks/README.md) before use. Preview with `/hooks-init --dry-run`; do not run `/hooks-init --apply` until every destination and executable policy has been reviewed.
|
|
|
|
### Configure Pi Todo Herdr
|
|
|
|
[`@jbcode/pi-todo-herdr`](extensions/todo-herdr) provides the `set_tasks`, `patch_tasks`, `rm_task`, `list_task`, and `get_task` tools plus a session-local Pi task widget. Herdr is optional for the tools and widget.
|
|
|
|
Inside Pi after `/reload`:
|
|
|
|
1. Confirm the five task tools are available.
|
|
2. Run `/todo` to toggle the widget.
|
|
3. Ask Pi to create a small three-step test plan, update one task, and list the tree.
|
|
|
|
For Herdr sidebar task metadata, back up and edit the existing configuration:
|
|
|
|
```bash
|
|
cp -a ~/.config/herdr/config.toml \
|
|
~/.config/herdr/config.toml.before-pi-todo-herdr
|
|
"${EDITOR:-vi}" ~/.config/herdr/config.toml
|
|
```
|
|
|
|
If `[ui.sidebar.agents]` already exists, edit its existing `rows` value and add `"$task_progress"`, `"$task"`, and `"$task_count"` where desired. Do not add a duplicate TOML table header. If the table does not exist, append the complete block:
|
|
|
|
```toml
|
|
[ui.sidebar.agents]
|
|
rows = [["state_icon", "workspace", "tab"], ["$ask", "$ask_count"], ["$task_progress", "$task", "$task_count"]]
|
|
```
|
|
|
|
Apply and verify the change:
|
|
|
|
```bash
|
|
herdr server reload-config
|
|
herdr status client
|
|
```
|
|
|
|
### Update or remove the Gitea packages
|
|
|
|
These installations are version-pinned. After publishing a new version, install that exact spec to replace the prior pin. Remove packages by npm identity:
|
|
|
|
```bash
|
|
pi remove npm:@jbcode/pi-dictate
|
|
pi remove npm:@jbcode/pi-effort-controls
|
|
pi remove npm:@jbcode/pi-prompt-snippets
|
|
pi remove npm:@jbcode/pi-interactive-subagents
|
|
pi remove npm:@jbcode/pi-todo-herdr
|
|
```
|
|
|
|
Run `/reload` after a version change or removal.
|
|
|
|
### Imported source provenance
|
|
|
|
The three packages were imported as snapshots of their source repositories' `main` branches. [`config/imported-packages.json`](config/imported-packages.json) records each source and exact commit. Check for upstream movement without changing this checkout:
|
|
|
|
```bash
|
|
bun run imports:check
|
|
```
|
|
|
|
Stage fresh snapshots outside the repository for review and reconciliation:
|
|
|
|
```bash
|
|
bun scripts/import-package-snapshots.mjs stage all --output /tmp/harness-tools-imports
|
|
```
|
|
|
|
The stage command deliberately does not overwrite monorepo files. Review upstream changes, preserve the scoped package manifests and catalog dependencies, run the full validation suite, and then update the recorded commit.
|
|
|
|
## Companion tools used by installed skills
|
|
|
|
The link sync installs skill instructions, not every external program those skills may call. Install the companion tools you intend to use.
|
|
|
|
### OpenSrc for dependency research
|
|
|
|
`code-research` and `package-source` require the `opensrc` CLI and intentionally use `/srv/data/opensrc` as the single source cache:
|
|
|
|
```bash
|
|
npm install -g --prefix "$HOME/.local" opensrc
|
|
if [ ! -e /srv/data/opensrc ]; then
|
|
sudo install -d -o "$USER" -g "$(id -gn)" /srv/data/opensrc
|
|
fi
|
|
test -d /srv/data/opensrc && test -w /srv/data/opensrc || {
|
|
echo '/srv/data/opensrc already exists but is not a writable directory' >&2
|
|
exit 1
|
|
}
|
|
|
|
if [ ! -e "$HOME/.opensrc" ] && [ ! -L "$HOME/.opensrc" ]; then
|
|
ln -s /srv/data/opensrc "$HOME/.opensrc"
|
|
fi
|
|
|
|
command -v opensrc
|
|
readlink -f "$HOME/.opensrc"
|
|
```
|
|
|
|
The setup preserves existing directory ownership and any existing `~/.opensrc`. If that path already exists, inspect it instead of replacing it. Completion requires it to resolve to `/srv/data/opensrc`.
|
|
|
|
If `~/.opensrc` already exists, inspect it instead of replacing it. Completion requires it to resolve to `/srv/data/opensrc`.
|
|
|
|
### Browser Harness
|
|
|
|
The `browser-harness` skill requires `uv`, Chrome or Chromium, and the Browser Harness CLI:
|
|
|
|
```bash
|
|
uv tool install --python 3.12 --upgrade --force browser-harness
|
|
browser-harness --doctor
|
|
browser-harness <<'PY'
|
|
print(page_info())
|
|
PY
|
|
```
|
|
|
|
For a Browser Use cloud session, authenticate separately with `browser-harness auth login`. Local browser control does not require a cloud key.
|
|
|
|
### Artifact presentation
|
|
|
|
The `artifact-presenter` skill uses [Herdr](https://herdr.dev) and [mcat](https://github.com/Skardyy/mcat). Install both and verify:
|
|
|
|
```bash
|
|
command -v herdr
|
|
command -v mcat
|
|
herdr --version
|
|
mcat --version
|
|
```
|
|
|
|
On Arch-based systems, mcat is available as the `mcat-bin` AUR package. Follow Herdr's installation guide for its CLI. The skill falls back to reporting the artifact path when either program is unavailable.
|
|
|
|
### PDF work
|
|
|
|
The `pdf` skill calls tools as needed rather than maintaining a repository environment. For its common workflows, install the relevant subset of:
|
|
|
|
- Python packages: `pypdf`, `pdfplumber`, `reportlab`, `pymupdf`, `pytesseract`, and `pdf2image`;
|
|
- system tools: Poppler (`pdftotext`, `pdfimages`, and `pdftoppm`), `qpdf`, and Tesseract OCR.
|
|
|
|
The intentionally excluded `pptx` and `xlsx` skills have additional office and rendering dependencies and are not part of the normal setup.
|
|
|
|
## Optional Linux sandbox setup
|
|
|
|
The repository-managed [nono](https://github.com/always-further/nono) profiles and `pi-sbx` launcher are optional, but they reproduce the normal restricted Pi runtime.
|
|
|
|
### Install nono and its Pi package
|
|
|
|
Install the `nono` CLI using its upstream instructions, then pull the parent Pi profile:
|
|
|
|
```bash
|
|
nono pull nolabs-ai/pi
|
|
nono profile show nolabs-ai/pi
|
|
```
|
|
|
|
### Link the repository profiles
|
|
|
|
```bash
|
|
cd /srv/data/code/harness-tools
|
|
mkdir -p ~/.config/nono/profiles
|
|
|
|
for profile in pi-local pi-orca-local pi-harness-tools pi-work; do
|
|
source="$PWD/profiles/nono/$profile.json"
|
|
destination="$HOME/.config/nono/profiles/$profile.json"
|
|
if [ -L "$destination" ] && \
|
|
[ "$(readlink -f "$destination")" = "$(readlink -f "$source")" ]; then
|
|
continue
|
|
fi
|
|
if [ -e "$destination" ] || [ -L "$destination" ]; then
|
|
echo "Refusing to replace existing profile: $destination" >&2
|
|
exit 1
|
|
fi
|
|
ln -s "$source" "$destination"
|
|
done
|
|
|
|
for profile in pi-local pi-orca-local pi-harness-tools pi-work; do
|
|
nono profile validate "$profile"
|
|
done
|
|
```
|
|
|
|
The loop is rerunnable for links already targeting this checkout and refuses every other collision.
|
|
|
|
These profiles inherit from one another, so install and validate all four even if only `pi-local` is used initially. Review their filesystem paths, Orca integration paths, socket grants, network allowlist, and work-specific Git path on every new machine.
|
|
|
|
### Install the routed launcher
|
|
|
|
`pi-sbx` is a Fish script. Install Fish, then link the launch commands and systemd slice:
|
|
|
|
```bash
|
|
cd /srv/data/code/harness-tools
|
|
mkdir -p ~/.local/bin ~/.config/pi-sbx ~/.config/systemd/user
|
|
|
|
safe_link() {
|
|
source="$1"
|
|
destination="$2"
|
|
if [ -L "$destination" ] && \
|
|
[ "$(readlink -f "$destination")" = "$(readlink -f "$source")" ]; then
|
|
return 0
|
|
fi
|
|
if [ -e "$destination" ] || [ -L "$destination" ]; then
|
|
echo "Refusing to replace existing path: $destination" >&2
|
|
return 1
|
|
fi
|
|
ln -s "$source" "$destination"
|
|
}
|
|
|
|
safe_link "$PWD/scripts/pi-sbx.fish" "$HOME/.local/bin/pi-sbx"
|
|
safe_link "$PWD/scripts/pi-sbx-profile.py" "$HOME/.local/bin/pi-sbx-profile"
|
|
safe_link "$PWD/scripts/pi-orca.fish" "$HOME/.local/bin/pi-orca"
|
|
safe_link "$PWD/scripts/orca-nono-profile.py" "$HOME/.local/bin/orca-nono-profile"
|
|
safe_link "$PWD/systemd/user/pi-agents.slice" \
|
|
"$HOME/.config/systemd/user/pi-agents.slice"
|
|
|
|
if [ ! -e "$HOME/.config/pi-sbx/config.json" ]; then
|
|
cp "$PWD/config/pi-sbx.example.json" "$HOME/.config/pi-sbx/config.json"
|
|
chmod 600 "$HOME/.config/pi-sbx/config.json"
|
|
else
|
|
echo 'Keeping existing ~/.config/pi-sbx/config.json'
|
|
fi
|
|
systemctl --user daemon-reload
|
|
```
|
|
|
|
The setup preserves an existing launcher, systemd unit, or routing configuration unless it already links to this checkout. Resolve reported collisions manually after inspecting both paths.
|
|
|
|
Edit `~/.config/pi-sbx/config.json` before launching. Set:
|
|
|
|
- `nodeExecutable` to `readlink -f "$(command -v node)"`;
|
|
- `piExecutable` to the real Pi executable path;
|
|
- `piAgentDirectory` to the matching Pi state directory;
|
|
- directory routes to paths that exist on this machine;
|
|
- profile-specific runtimes only when a different Node ABI or Pi state directory is intentional.
|
|
|
|
The checked-in example contains paths from the original machine and is a template, not a portable final configuration. Separate Pi agent directories are required when profiles use incompatible Node ABIs with native dependencies.
|
|
|
|
Verify and launch:
|
|
|
|
```bash
|
|
pi-sbx-profile list
|
|
pi-sbx-profile show
|
|
pi-sbx-profile set pi-local /path/to/a/project
|
|
pi-sbx-profile resolve /path/to/a/project
|
|
pi-sbx
|
|
```
|
|
|
|
See [`docs/nono.md`](docs/nono.md) for routing behavior, multi-repository grants, Internet tiers, profile editing, and troubleshooting denials.
|
|
|
|
### Sandboxed Pi credentials
|
|
|
|
The base `nolabs-ai/pi` package supports mediated credential routes. Store secrets in the OS keychain or another nono-supported secret source, then enable only the required route names in a reviewed child profile. For example, supported built-in route names include `openai`, `anthropic`, `gemini`, `github`, and `gitlab`.
|
|
|
|
Do not place real provider keys in files readable by sandboxed Pi if the goal is credential mediation. Consult the installed package guide after `nono pull`:
|
|
|
|
```text
|
|
~/.config/nono/packages/nolabs-ai/pi/README.md
|
|
```
|
|
|
|
## Optional Dictate service
|
|
|
|
Dictate is a Linux-only host service. Every backend requires:
|
|
|
|
- PipeWire with `pw-record`;
|
|
- systemd user services;
|
|
- `uv`;
|
|
- access to the exact `/run/user/1000/pi-dictate.sock`, unless the socket path is changed for another UID.
|
|
|
|
The default backend is local NeMo/Parakeet. Local installation additionally requires an NVIDIA GPU, a working CUDA runtime, network access for initial provisioning, and several gigabytes for the locked environment and pinned model. Meta and OpenAI are explicit cloud opt-ins. Cloud-only installation does not install NeMo, CUDA, or model weights, but it requires a dedicated host credential and outbound DNS/TLS access from the service.
|
|
|
|
Install one backend from the repository root:
|
|
|
|
```bash
|
|
cd /srv/data/code/harness-tools
|
|
./services/dictate/install.sh install --backend local
|
|
# or:
|
|
./services/dictate/install.sh install --backend meta --api-key-file /path/to/meta-key
|
|
./services/dictate/install.sh install --backend openai --api-key-file /path/to/openai-key
|
|
```
|
|
|
|
`--api-key-file` copies a regular source file into the host-owned mode-`0600` credential directory. Never pass a literal key. Configure an installed backend or validate it with:
|
|
|
|
```bash
|
|
./services/dictate/install.sh configure --backend local
|
|
./services/dictate/install.sh check
|
|
systemctl --user status pi-dictate.socket pi-dictate.service
|
|
```
|
|
|
|
Local mode remains offline after provisioning and uses the checksum-pinned Parakeet archive. Cloud mode streams bounded PCM to the selected provider only after its session is authenticated and ready. Backend changes are privileged host operations, require validation and a service restart, and fail closed if systemd network hardening does not match the selection. The service does not write audio files or expose provider credentials to Pi. Cloud provider retention, terms, and billing policies apply to audio and configured context sent with a cloud session.
|
|
|
|
Restart a sandboxed Pi after profile or socket changes. In Pi, press `Alt+M` to start or stop dictation, `Alt+N` or `/dictate-cancel` to cancel, and `/dictate-status` to display bounded backend/model diagnostics. See [`extensions/dictate/README.md`](extensions/dictate/README.md) for configuration, provider links, privacy, dictionary, model, and troubleshooting details.
|
|
|
|
## Maintenance
|
|
|
|
After pulling repository changes:
|
|
|
|
```bash
|
|
cd /srv/data/code/jb-pi/harness-tools
|
|
git pull --rebase
|
|
bun install --frozen-lockfile
|
|
./scripts/pi-links.mjs sync --dry-run
|
|
./scripts/pi-links.mjs sync
|
|
./scripts/pi-links.mjs check
|
|
bun run typecheck
|
|
```
|
|
|
|
Run `/reload` after skill, extension, instruction, or separately installed Gitea package changes. Re-run `./services/dictate/install.sh` when Dictate's host service or protocol changes.
|
|
|
|
Before removing repository-managed exposure, preview exactly what will be deleted:
|
|
|
|
```bash
|
|
./scripts/pi-links.mjs prune --dry-run
|
|
```
|
|
|
|
Only run `./scripts/pi-links.mjs prune` after reviewing every removal. The manager prunes repository-owned exposure and leaves unrelated global resources alone.
|
|
|
|
## Development and checks
|
|
|
|
Extensions are TypeScript modules loaded directly by Pi; no build step is required.
|
|
|
|
```bash
|
|
bun install --frozen-lockfile
|
|
bun run typecheck
|
|
bun run test
|
|
```
|
|
|
|
For a one-off extension development run:
|
|
|
|
```bash
|
|
pi -e ./extensions/effort-controls
|
|
pi -e ./extensions/update
|
|
```
|
|
|
|
## Repository layout
|
|
|
|
```text
|
|
config/ Installation and launcher manifests
|
|
docs/ Usage guides, plans, and ADRs
|
|
extensions/ Bun workspace packages for Pi extensions and shared runtime code
|
|
profiles/nono/ Repository-managed nono profiles
|
|
scripts/ Link manager and sandbox launch helpers
|
|
services/ Host-side services used by extensions
|
|
skills/ Pi skills, one SKILL.md per skill
|
|
systemd/user/ Repository-managed systemd user units
|
|
```
|
|
|
|
## License
|
|
|
|
MIT
|