feat(terminal): add panopticon onboard β Claude-backed setup launcher#217
Draft
tildesrc wants to merge 42 commits into
Draft
feat(terminal): add panopticon onboard β Claude-backed setup launcher#217tildesrc wants to merge 42 commits into
panopticon onboard β Claude-backed setup launcher#217tildesrc wants to merge 42 commits into
Conversation
Adds a `panopticon onboard` subcommand that opens an interactive Claude Code session with the full first-time setup guide baked into the system prompt, so new users get a guided walkthrough without running any manual curl/make commands themselves. The only requirement is a working `claude` install. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`scripts/onboard` is a self-contained bash script (works on Linux and macOS) that opens a Claude Code session with the full Panopticon setup guide baked in via --append-system-prompt. The only requirement is a working `claude` install in PATH β no Python, no make, nothing else. Removes the earlier Python implementation from terminal/__main__.py. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Stage 5: steer towards GitHub or purely-local repos; recommend a small coding task as the test; explain git_url accepts local paths - Stage 6: recommend github-self-reviewed (full planningβPRβmerge lifecycle, self-review) over spike; note spike as fallback for local-only repos - Stage 7: explain that first attach lands in PLANNING mode and the user must give a prompt; add an example planning prompt; explain how to view plan.md via the dashboard artifact browser (a β e) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- scripts/onboard writes ~/.panopticon/.onboarded sentinel at startup - dashboard skips the first-run repo-screen auto-open when that sentinel exists (the onboard flow already created the repo) - WIZARD_CONTEXT instructs Claude to collect repo/task details from the user and run the curl calls itself (stages 5 and 6) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All stage headings now read "Stage X of 7"; sub-step lists in Stage 3 (auth, 5 steps), Stage 5 (repo info, 4 items), and Stage 7 (view plan, 3 steps) are annotated with their totals. Added a preamble instruction telling Claude to always announce progress with the full count. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds panopticon.env.template to the repo root with placeholder values for CLAUDE_CODE_OAUTH_TOKEN and (commented) GH_TOKEN. Stage 3 of the wizard now instructs Claude to copy the template to the chosen env-file path if the file does not already exist (never clobbers), then tells the user to fill in real values in their editor. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦ific editor Added a preamble rule forbidding Claude from naming any specific editor (nano, vim, etc.); softened step 4 of 5 and plan-viewing step 3 of 3 to say "preferred editor" / "default handler" instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stage 4 now explicitly tells Claude not to run make start itself β instead ask the user to run it, then verify via /healthz. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stage 5 no longer asks the user for a short repo ID (derived from the git URL) or the default branch (assumed to be main, with a mention to the user). Ask list drops from 4 items to 2. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦se failures Stage 6 now instructs Claude to poll container_status until live (~3 min budget), then diagnose failed/stuck states: failed+lifecycle_detail, stuck-building, stuck-claiming/queued. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
macOS ships bash 3.2, which has a bug where a heredoc nested inside $() fails to parse. Switch to the compatible read -r -d '' pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stage 2 now directs the onboarding assistant to run the build commands itself; the user is only asked to run make start (which opens the dashboard). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tildesrc
commented
Jun 29, 2026
Comment on lines
+1
to
+6
| # Panopticon repo env-file template | ||
| # Copy this to a path OUTSIDE the repo, e.g.: | ||
| # cp panopticon.env.template ~/.panopticon/secrets/<repo-name>.env | ||
| # chmod 0600 ~/.panopticon/secrets/<repo-name>.env | ||
| # Then fill in the real values and never commit them. | ||
|
|
Contributor
Author
There was a problem hiding this comment.
Do not include these instructions in this file itself. It is confusing to the user.
β¦late file Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SQLAlchemy's async engine requires greenlet, but SQLAlchemy only declares it for select platform_machine values (Linux aarch64, x86_64, etc.) and omits macOS arm64. uv therefore skipped greenlet on Apple Silicon, so the task service crashed on startup with 'No module named greenlet'. Declare greenlet as an explicit, marker-free project dependency so every platform installs it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(ci): add smoke test for make start on Linux and macOS Adds a `host` Makefile target that starts the task service and session-service runner in background tmux sessions without the interactive console. `make start` is refactored to depend on `host` (eliminating the duplicated tmux session setup), then runs `panopticon console`. A new `smoke.yml` GHA workflow exercises `make host` on ubuntu-latest and macos-latest, polling the service health check and asserting both tmux sessions are alive. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(ci): capture service logs and increase health-check timeout for macOS Log task-service and session-service output via `tee` in `make host` so crash output survives tmux session death. Dump log files alongside pane captures in the failure handler. Increase health-check poll from 30 s to 60 s to give macOS more startup time. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(deps): declare sqlalchemy[asyncio] to install greenlet on macOS arm64 SQLAlchemy's base dependency on greenlet is conditional on platform_machine, which includes aarch64 (Linux ARM) but not arm64 (macOS ARM). The asyncio extra pins greenlet unconditionally, so switching to sqlalchemy[asyncio] fixes the startup crash on macos-latest GitHub Actions runners (Apple Silicon). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Panopticon <panopticon@local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(dashboard): add fartbarf easter egg Typing f-a-r-t-b-a-r-f in the dashboard opens a surprise URL. The URL is stored as a base64 blob and the constants use terse non-descriptive names so the purpose isn't obvious on inspection. Fully undocumented β absent from HOTKEYS and HelpScreen. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(dashboard): encode _KS as base64 like _KU Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(dashboard): trigger easter egg via FARTBARF task memo Replace the key-sequence trigger with a memo-intercept: typing FARTBARF as the task memo (case-insensitive) opens the URL instead of creating a task. The comparison string is also base64-encoded so neither the trigger word nor the destination are readable in plain text. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(dashboard): inline _KU at the call site Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(dashboard): extract memo check into _apply_memo_filter Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(dashboard): remove easter egg tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Panopticon Agent <agent@panopticon.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: add macOS developer setup guide Covers Docker Desktop vs Docker Engine distinction, tmux requirement, what runs on the macOS host vs inside Linux containers, quick start, and known macOS limitations (--network host, Docker-in-Docker on Apple Silicon). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: remove confusing make serve line from what-runs-where diagram Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Panopticon Agent <panopticon@example.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
When CI passes (EXIT:0) but the PR already has auto-merge enabled (autoMergeRequest non-null), babysit-ci now invokes /babysit-merge instead of stopping β so the task's turn stays on the agent and the merge queue is shepherded without requiring a user hand-off. Co-authored-by: Panopticon Agent <agent@panopticon.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(workflows): per-repo workflow filtering via opt_in flag
Each workflow declares opt_in = True (hidden by default, must be
explicitly enabled per repo) or False (shown for all repos unless
disabled). Repos carry enabled_workflows and disabled_workflows lists
that override the defaults.
- GET /repos/{repo_id}/workflows returns the filtered list for a repo
- POST /tasks now validates the chosen workflow is visible for the repo
- Dashboard fetches the repo-scoped list after the user picks a repo
- github-peer-reviewed and github-self-reviewed are now opt_in = True
- New Alembic migration adds the two JSON columns to the repos table
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(dashboard): workflow fields in repo form (enabled/disabled, comma-separated)
The repo create/edit form (`g` β `e`) now shows two text inputs for
enabled_workflows and disabled_workflows (comma-separated workflow names).
Pre-populated from the stored repo in edit mode; values are parsed back
into lists on submit and sent via the existing PATCH/POST API.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Panopticon Agent <agent@panopticon>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Add `verbose: bool = False` to `CommandRunner`, `_subprocess_run`, `ImageBuilder.build()`, and `ImageBuilder.build_base_if_missing()`. When verbose, docker build stdout/stderr inherit the runner process's streams instead of being captured, so the output is visible live in the runner's tmux pane (reachable via `u` from the dashboard). The spawner passes `verbose=True` for both base-image and composed-image builds, and adds `_log.info()` calls at each lifecycle phase (claiming β preparing β building β starting β awaiting β failed). `host.main()` now calls `logging.basicConfig(level=INFO)` so those messages actually appear. Co-authored-by: Claude <claude@anthropic.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(dashboard): add auto-submit checkbox to memo modal The memo modal now includes a Space-toggled checkbox that controls whether the memo is submitted automatically (routed as `initial_prompt` β delivered as a positional arg to `claude`, no manual Enter needed) or pasted unsent (original behaviour, user presses Enter to begin). Workflows declare their default via `auto_submit_memo: ClassVar[bool]`. `github-self-reviewed`, `github-peer-reviewed`, and `local-git-self-reviewed` default to `True` (task description is sufficient context to start immediately); `spike` and `orchestrator` default to `False` (free-form tasks benefit from the user confirming or editing the prompt first). The flag is exposed through `GET /workflows` as `auto_submit_memo` and consumed by the dashboard when the workflow picker returns a selection. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(dashboard): rename checkbox label to "Use as initial prompt" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(dashboard): store memo on task even when auto-submitted as initial_prompt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(dashboard): rename checkbox label to "Submit as initial prompt" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Panopticon <panopticon@local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦or (#231) * feat(dashboard): fade terminal task rows instead of drawing a separator Terminal (COMPLETE/DROPPED) tasks now render in dim styling on all columns rather than being visually separated by a grey divider row. The separator row, its key sentinel, and the arrow-key skip logic for it are all removed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(dashboard): dim terminal tasks by state, not section membership A governed task that is COMPLETE/DROPPED but whose governor is still active lives in the active section, so the old section-based `terminal` flag missed it. Switch to checking `task["state"] in TERMINAL_LABELS` directly in `_add_row` so every terminal-state task is faded regardless of which section it was placed in. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Panopticon Agent <agent@panopticon.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦dpoint (#235) list_workflow_infos_for_repo omitted auto_submit_memo, causing the dashboard to always fall back to False for the memo checkbox regardless of the workflow's actual setting. Also updates the return type annotation in service.py and api.py. Co-authored-by: Panopticon <panopticon@example.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows "agent N/M" in the bottom-right corner of the footer where N is the number of active tasks currently on the agent's turn and M is the total active (non-terminal) tasks. The counter reflects the global system state even when a search filter is applied. Subclasses Footer as _StatusFooter so the counter Static survives Footer's recompose cycles (triggered by _bindings_ready); action_refresh uses a query() guard to tolerate the brief window before Footer first composes. Co-authored-by: Panopticon Agent <agent@panopticon.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
The prefill mechanism (watching for ESC[?2004h via pipe-pane then pasting the memo via paste-buffer) is replaced by passing the memo as initial_prompt, which claude receives as a CLI arg and processes immediately on first spawn. Removes prefill.py and test_prefill.py entirely; cleans up the PrefillLauncher protocol, _launch_prefill, _wants_prefill, _config_volume_exists, and _maybe_prefill from local_runner.py; drops memo= from the spawnerβrunner call; and fixes the MCP initial_prompt description (was "prefilled unsent", now correctly describes the immediate-processing behaviour). Co-authored-by: Panopticon <panopticon@local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(dashboard): replace workflow text inputs with WorkflowConfigScreen modal
The repo form's enabled/disabled workflow fields were free-text comma-separated
inputs with no discovery β users had to know workflow names exactly. Replace them
with a dedicated WorkflowConfigScreen that lists all known workflows as a togglable
checklist, showing each workflow's name, opt-in badge, and when_to_use description
as you Tab through.
RepoFormScreen now shows a one-line summary ("N opted-in, M disabled" / "defaults")
and a "configure workflows" button that opens the modal. The opt-in/opt-out semantics
are handled internally: checked opt-in workflows land in enabled_workflows; unchecked
opt-out workflows land in disabled_workflows.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(dashboard): move workflow config to a tab on the repos modal
Instead of a separate WorkflowConfigScreen sub-modal accessed via a button in
the repo edit form, workflow preferences are now a native tab on ReposScreen
itself. The repos modal shows two tabs: "repos" (the existing DataTable) and
"workflows" (a SpaceCheckbox list for the highlighted repo, with a when_to_use
description pane and Ctrl+S to save).
WorkflowConfigScreen is removed; RepoFormScreen reverts to managing only core
repo fields; ReposScreen fetches the workflow list on mount and rebuilds the
checklist on tab switch.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(dashboard): move workflow config to a tab on the repo form modal
The workflow opt-in/opt-out checklist is now a second tab ("workflows") inside
RepoFormScreen, sitting alongside the existing "general" tab. Both tabs' values
are collected together on form save (Enter or Ctrl+S from any field).
ReposScreen reverts to a plain DataTable list with no workflow tab of its own β
workflows are configured per-repo in the create/edit form where the rest of that
repo's settings live.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(dashboard): drop [opt-in] label from workflow checkboxes
The suffix described the workflow's default behaviour (opt-in vs opt-out),
not whether it was enabled β which is exactly what the checkbox state conveys.
Remove it so the UI reads as an enabled/disabled toggle, not a type indicator.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(dashboard): stable modal height on tab switch; fix opt_in bool serialization
Two bugs:
- RepoFormScreen resized when switching tabs because `height: auto` tracked
the active tab's content. Fixed by setting `height: 80%`.
- Workflow checkboxes showed all workflows as enabled because the service was
serializing opt_in as the string "true"/"false" (always truthy in Python).
WorkflowInfo.opt_in is now bool; service emits the raw bool.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(workflows): make local-git-self-reviewed opt-in; fix opt_in test to expect bool
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(dashboard): workflow list fills the modal height
Remove the fixed max-height cap on wf-scroll; let form-tabs, pane-workflows,
and wf-scroll each take 1fr so the scrollable list stretches to fill the
available modal space, with the description pane pinned at the bottom.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(dashboard): add enter/esc hint to repo form modal
A dim centred hint line below the tabs is visible on both the general
and workflows tabs, so the user always knows how to save or cancel.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Panopticon <panopticon@local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦sum (#237) * feat(container): track cost-weighted tokens instead of raw four-tier sum tokens_used was a raw sum of all token tiers, dominated by cheap cache-reads (~0.1Γ price), making it ~300Γ larger than token_estimate β a units mismatch, not bad estimation. Replace with cost-weighted input-equivalent tokens (cache-reads Γ0.1, output Γ5.0) via a new pricing module, so the measured quantity is both a better billing signal and a sensible estimate target. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: flag cost-weighted prompt guidance as tech debt for non-Claude agents TODO comments in pricing.py (canonical), planned_workflow.py, and orchestrator.py note that the β0.1Γ/β5Γ framing in planning prompts is Anthropic-specific and will need to be generalised when non-Claude LLM backends are supported. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Panopticon <panopticon@localhost> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦238) * feat(artifacts): hide dotfile artifacts by default in the dashboard Artifacts whose names start with '.' are now valid and hidden from the dashboard artifact modal by default β a 'Show hidden' checkbox appears when any exist. The babysit skill state files are renamed to use dot prefixes so they don't clutter the artifact list. - core/artifacts.py: relax validate_segment() β dotfile names are now allowed; only '.' and '..' (directory sentinels) remain forbidden. - terminal/dashboard.py: ArtifactScreen filters dotfile names on open; a SpaceCheckbox('Show hidden') appears when hidden artifacts exist and toggles them in/out of the OptionList. - workflows/github_forge.py: rename babysit-ci-state.json β .babysit-ci-state.json and babysit-merge-state.json β .babysit-merge-state.json in the skill instructions. - tests: update traversal-rejection tests (remove .hidden from bad-name lists), add dotfile round-trip tests for the store and MCP layer. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(tech-debt): flag Claude-specific token cost prompts for multi-agent generalisation TODO markers in planned_workflow.py (TOKEN_ESTIMATED responsibility) and orchestrator.py (spawn-task recipe step 4) noting that the 'tokens' unit and set_token_estimate tool are Claude-specific and need revisiting when non-Claude agents are supported. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Revert "chore(tech-debt): flag Claude-specific token cost prompts for multi-agent generalisation" This reverts commit b0855c0. * feat(artifacts): right-justify the Show hidden checkbox in the artifact modal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * revert: remove right-justify wrapper from Show hidden checkbox Left-aligned is the idiomatic position for checkboxes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Panopticon Agent <agent@panopticon.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
β¦me label to "active agents" (#240) When Textual fires _bindings_ready (modal open/close, focus change) Footer.recompose() recreates its children, resetting the counter Static to "". With width:auto the empty widget collapses and the key-binding hint pills expand to cover it. Fix by storing _counter_text on _StatusFooter and seeding the Static with it on each recompose. Also rename the label from "agent N/M" to "active agents N/M". Co-authored-by: Panopticon Agent <agent@panopticon.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(dashboard): open memo in \$EDITOR with ctrl+g Pressing ctrl+g while in the MemoScreen's text input suspends the Textual app and opens the current text in \$EDITOR (falling back to vi), then writes the result back into the input on editor exit. Uses shlex.split on the editor value so multi-word settings like "code --wait" work correctly. Catches SuspendNotSupported and shows a notification in headless/web environments. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(dashboard): multi-line memo support β TextArea + slug truncation Replace MemoScreen's single-line Input with a TextArea so memos edited via ctrl+g ($EDITOR) can contain newlines. Submit moves from Enter to ctrl+s (matching RepoFormScreen; Enter now inserts newlines). Truncate multi-line memos to the first line in the slug cell so table row height stays consistent; the detail pane already handles multi-line fine. Drop "one-line" from the MCP tool docstring. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(dashboard): Enter submits memo modal β MemoTextArea subclass Replace the ctrl+s submit key with Enter (restoring original UX) by subclassing TextArea as MemoTextArea and overriding _on_key to call action_submit instead of inserting a newline on Enter. The TextArea still displays multi-line content from ctrl+g ($EDITOR); the editor is the intended path for multi-line memos. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(dashboard): MemoTextArea auto-expands to fit content (up to 10 rows) Start the memo field at 1 row (single-line look); on_text_area_changed updates styles.height to the line count capped at MAX_LINES=10, so content loaded via ctrl+g ($EDITOR) expands the field to show all lines without a fixed tall box in the common single-line case. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(dashboard): compact=True on MemoTextArea so text is visible at height 1 Without compact mode TextArea has internal padding that pushes content out of view when the widget is a single row tall, making typed text invisible. compact=True removes that padding. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(memo-editor): enter submits from checkbox, add ctrl+g hint label Enter on the checkbox now submits the memo modal (via the screen-level binding); event.stop() in MemoTextArea._on_key prevents double-fire. A dim hint label "ctrl+g: open in $EDITOR" is shown below the checkbox. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Panopticon Agent <agent@panopticon.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Log key lifecycle events at INFO (state transitions, task creation, slug changes, claim/release, registration, provisioning, runner events, cascade drops) and DEBUG (url, blocked, responsibilities, artifacts, lifecycle phases, MCP tool invocations). Mirrors the session-service logging pattern (`_log = logging.getLogger(__name__)`, basicConfig in the entry point). Co-authored-by: Panopticon <panopticon@example.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
After `make stop` + `make start`, tasks stayed `claimed_by="local"` in SQLite, so the runner immediately healed them on restart. With a cached image and existing workspace the spawn completed in 1β3 s β before the dashboard's first render β making one task appear `live` with no visible lifecycle phases while the others showed `healing`. Two changes to `make stop`: 1. Reclaim tasks first (`POST /runners/local/reclaim`) so they reset to `queued` before the service is killed. After `make start` the dashboard shows `queued`, then the runner claims and spawns through the full visible lifecycle. Best-effort: the curl fails silently if the service is already down. 2. Switch the docker container filter from `name=^panopticon-` (regex anchor semantics vary by Docker version) to `label=panopticon.task` (containers are already labeled in `LocalRunner.spawn`), which is reliable and version-independent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After any restart (clean `make stop` or unexpected reboot), tasks kept `claimed_by` in SQLite. The runner reconnected with the same ID, `heal()` fired immediately, and with a cached image + existing workspace the spawn completed in 1β3 s β before the dashboard's first render β so one task always appeared `live` with no visible lifecycle phases. `Spawner.startup_reclaim(tasks)` runs once on the first successful task fetch (via a `startup` flag in `HostDaemon.run`). For each task claimed by this runner it checks `is_running()`: - Container gone (reboot / clean stop): release the claim β `queued` β `spawn_one` picks it up through the full visible spawn lifecycle. - Container still running (runner-only crash): keep the claim β `heal` handles it normally. Best-effort per task: a failed release is silently skipped. Also switches `make stop`'s docker filter from `name=^panopticon-` (regex anchor semantics vary by Docker version) to `label=panopticon.task` (containers are already labeled in `LocalRunner.spawn`). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removed a reference to the design documentation branch.
Removed reference to CLAUDE.md from the README.
Removed status and development sections from README.
β¦241) Adds a paragraph to Workflow.overview() β the static system prompt injected into every container β telling the agent to use put_artifact for reports and other non-code deliverables instead of printing inline or writing ephemeral container files. Updates the golden briefing fixture to match. Co-authored-by: Panopticon <panopticon@local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a
panopticon onboardsubcommand that opens an interactive Claude Code session configured to guide a new user through first-time Panopticon setup β no multi-stage Python wizard, no prereq probing in code. The only requirement is a workingclaudeinstall.What it does
WIZARD_CONTEXT) with a full setup guide: prereqs β build β auth β start β configure repo β create first task β troubleshooting β what's next--append-system-promptso Claude has the full context before the first user turnINITIAL_PROMPTas the first user message so Claude begins guiding immediatelysubprocess.run(["claude", "--append-system-prompt", ..., INITIAL_PROMPT])β inherits the caller's TTY for a fully interactive sessionFiles
src/panopticon/terminal/onboard.pyβWIZARD_CONTEXT,INITIAL_PROMPT,run_onboard()with injectable runnersrc/panopticon/terminal/__main__.pyβ wiresonboardsubcommandtests/test_onboard.pyβ 4 tests; no realclaudeinvokedSee plan.md for the full design.
π€ Generated with Claude Code