diff --git a/CLAUDE.md b/CLAUDE.md index 81e5c18..918bb99 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -142,6 +142,42 @@ Key services: [TemplateConfig.swift](scarf/scarf/Core/Models/TemplateConfig.swif **Schema is Swift-primary.** If `TemplateConfigField.FieldType` gains a new case, update in order: `TemplateConfig.swift` (model + validation), `tools/build-catalog.py` (`SUPPORTED_CONFIG_FIELD_TYPES` + type-specific rules), `widgets.js` (`summariseConstraint`), `TemplateConfigSheet.swift` (new control subview), tests on both sides. Schema drift between validator + installer is the kind of bug users only notice after shipping. +### Project-scoped chat + Scarf-managed AGENTS.md context (v2.3) + +v2.3 adds a per-project Sessions tab and a "New Chat" button that spawns `hermes acp` with `cwd = project.path`. Session-to-project attribution is persisted in a Scarf-owned sidecar at `~/.hermes/scarf/session_project_map.json` — the ACP wire protocol has no project-metadata hook (extra params are silently dropped), and `state.db` has no cwd column, so the sidecar is Scarf's source of truth for "which project does this session belong to?" Managed by [SessionAttributionService.swift](scarf/scarf/Core/Services/SessionAttributionService.swift); read by the per-project [ProjectSessionsView.swift](scarf/scarf/Features/Projects/Views/ProjectSessionsView.swift). + +**Giving the agent project awareness.** Hermes auto-reads a context file from the session's cwd at startup — priority order `.hermes.md` → `HERMES.md` → `AGENTS.md` → `CLAUDE.md` → `.cursorrules`, first match wins, 20KB cap. We lean on that by writing a Scarf-managed block into `/AGENTS.md` before opening the session. Service: [ProjectAgentContextService.swift](scarf/scarf/Core/Services/ProjectAgentContextService.swift). Block shape: + +``` + +## Scarf project context +_Auto-generated by Scarf — do not edit between the begin/end markers._ + +You are operating inside a Scarf project named **""**. … + +- **Project directory:** `` +- **Dashboard:** `/.scarf/dashboard.json` +- **Template:** `` v +- **Configuration fields:** `field_a`, `field_b (secret — name only, value stored in Keychain)` +- **Registered cron jobs:** `[tmpl:] ` — schedule …, currently paused|enabled +- **Uninstall manifest:** `/.scarf/template.lock.json` + +Any content below this block is template- or user-authored; preserve and defer to it. + +``` + +**Invariants.** + +- **Secret-safe.** Block surfaces field NAMES, never VALUES. A project with a Keychain-stored secret shows `api_token (secret — name only, …)`; the Keychain ref URI and any plaintext value never appear. Auditable by `refreshListsFieldNamesNotValues` in `ProjectAgentContextServiceTests`. +- **Idempotent.** Two refreshes with unchanged state produce byte-identical output. The write is skipped entirely when no delta, avoiding file-watcher churn. +- **Bounded.** Everything outside the markers is preserved on every refresh. Template-author AGENTS.md content lives safely below the block. +- **Non-fatal.** `ChatViewModel.startACPSession` calls refresh with `try?` + log — a failed write doesn't block the chat from starting; worst case is the session loses project awareness. +- **Refresh timing.** Called BEFORE `client.start()` so the block lands before Hermes's session-boot context scan. Skipping this ordering = the agent sees stale context from the previous refresh (or nothing, on fresh projects). + +**Template-author contract.** A template shipped via the catalog should include an `AGENTS.md` with the template's operational instructions. Authors leave the `` region alone — Scarf populates it at chat-start time. Everything below is template-owned and preserved. + +**Known caveat.** If any parent directory of the project contains `.hermes.md` or `HERMES.md`, those shadow the project's `AGENTS.md` (higher in Hermes's priority order). No fix in v2.3 — deferred to v2.4 pending user input on how to handle authored `.hermes.md` files. + ## Template Catalog Shipped community templates live at `templates///` (one level down — `templates/CONTRIBUTING.md` explains the submission flow for authors). The catalog site is generated from this directory and served at `awizemann.github.io/scarf/templates/` alongside the Sparkle appcast — the two coexist on the `gh-pages` branch but touch completely disjoint paths. diff --git a/templates/awizemann/template-author/staging/skills/scarf-template-author/SKILL.md b/templates/awizemann/template-author/staging/skills/scarf-template-author/SKILL.md index 1376b09..7b4e79f 100644 --- a/templates/awizemann/template-author/staging/skills/scarf-template-author/SKILL.md +++ b/templates/awizemann/template-author/staging/skills/scarf-template-author/SKILL.md @@ -397,6 +397,7 @@ Things to check before declaring the scaffold done: - [ ] `dashboard.json` has `version: 1` at the top. - [ ] `AGENTS.md` documents every config field, every updated widget, and the cron behaviour — the user relies on it as the source of truth when things drift. - [ ] **No raw URLs in field descriptions.** Use `[link text](https://…)` markdown syntax instead — raw URLs read as long unbreakable tokens in the Configuration sheet. Same rule for long paths and other unbreakable strings; wrap in `` ` `` if they must appear verbatim. +- [ ] **Leave the `` / `` region alone in the project's `AGENTS.md`.** As of Scarf v2.3, the app auto-injects a project-identity block at chat-start time (project name, directory, template id, configuration field names, cron jobs). Anything you write inside that region will be overwritten on the next chat start. Put template-specific agent instructions BELOW the block so they're preserved across refreshes. ## Reference — source of truth files diff --git a/templates/awizemann/template-author/template-author.scarftemplate b/templates/awizemann/template-author/template-author.scarftemplate index b63d1b0..5112ee9 100644 Binary files a/templates/awizemann/template-author/template-author.scarftemplate and b/templates/awizemann/template-author/template-author.scarftemplate differ diff --git a/templates/catalog.json b/templates/catalog.json index 8004eff..f0b5c19 100644 --- a/templates/catalog.json +++ b/templates/catalog.json @@ -69,8 +69,8 @@ "name": "Alan Wizemann", "url": "https://github.com/awizemann" }, - "bundleSha256": "bebc30551dc92717da96608bbdf448c5d7c47bdb66807037b139a242ef8c3b74", - "bundleSize": 14423, + "bundleSha256": "56ab97eeb45ab7b9e6715ce9c88ec2c953bf795698cd19628d300d5b8cffd475", + "bundleSize": 14610, "category": "developer-tools", "config": null, "contents": {