mirror of
https://github.com/firstsun-dev/git-files-sync.git
synced 2026-07-22 06:54:27 +00:00
chore: add agent harness (state, verification, lifecycle tracking)
Adds the missing harness subsystems so future agent sessions can start, stay in scope, verify work, and resume reliably: - feature_list.json: local mirror of active/next-up work (GitHub Issues on Project #6 remains the source of truth for the full backlog) - progress.md / session-handoff.md / archive/2026-07.md: session state, restart point, and monthly archive of finished work - init.sh: install + lint + test + build verification entrypoint - AGENTS.md: added Startup Workflow, Definition of Done, Stay in Scope, and End of Session sections (existing agent-tier content kept as-is) - CLAUDE.md: added a short Agent Workflow section routing to the above Validated with the firstsun-harness audit script: 100/100 across all five subsystems (instructions, state, verification, scope, lifecycle). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YYCTyZw7gUmJ7oh1VTmAqh
This commit is contained in:
parent
28f4f8efd0
commit
597989b53c
7 changed files with 239 additions and 0 deletions
26
AGENTS.md
26
AGENTS.md
|
|
@ -1,5 +1,31 @@
|
|||
# Project Agent Design & Hierarchy (Synchronized with Skills)
|
||||
|
||||
## Startup Workflow
|
||||
|
||||
Before writing code:
|
||||
- Read `feature_list.json` (active/next-up work — GitHub Issues on `firstsun-dev/git-files-sync`, Project #6, is the real source of truth; re-sync stale entries) and `progress.md` (what's currently open).
|
||||
- Read `session-handoff.md` for the previous session's exact stopping point.
|
||||
- Run `./init.sh` to confirm a clean, green baseline before editing.
|
||||
|
||||
## Definition of Done
|
||||
|
||||
A feature is done only when all of the following hold, with evidence recorded (command + result) in `progress.md`:
|
||||
- `npx eslint .` — 0 errors
|
||||
- `npm run build` — passes (tsc + Obsidian 1.11.0 compat typecheck + esbuild)
|
||||
- `npx vitest run` — passes
|
||||
- Manual verification in Obsidian, when the change has a runtime UI surface
|
||||
|
||||
## Stay in Scope
|
||||
|
||||
- One feature at a time: pick a single `feature_list.json` entry and finish it (with recorded evidence) before starting the next.
|
||||
- Don't expand scope mid-task — file a new GitHub issue via the `firstsun-pm` skill instead of quietly bundling unrelated work.
|
||||
|
||||
## End of Session
|
||||
|
||||
Before ending a session:
|
||||
- Overwrite `session-handoff.md` (don't append) with the new stopping point so the repo stays restartable.
|
||||
- Move finished items from `progress.md` into `archive/YYYY-MM.md` (current month) — next steps in `progress.md` should read as a short list, not a changelog.
|
||||
|
||||
## Agent Tiers
|
||||
|
||||
### 1. High-Tier (Red/Orange Group)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Agent Workflow
|
||||
|
||||
- **Startup**: read `feature_list.json` (active/next-up work; GitHub Issues on `firstsun-dev/git-files-sync`, Project #6, is the actual source of truth — re-sync before trusting stale entries) and `progress.md` (what's open right now), then `session-handoff.md` for the previous session's exact stopping point.
|
||||
- **Before editing**: run `./init.sh` (installs deps, then lint + test + build) to confirm you're starting from a green baseline.
|
||||
- **Definition of done**: `npx eslint .` has 0 errors, `npm run build` passes (includes the Obsidian 1.11.0 compat typecheck), and `npx vitest run` passes, *and* evidence of that run is recorded (one line: command + result) in `progress.md` or the PR description — not just claimed.
|
||||
- **Scope**: work one `feature_list.json` entry at a time; don't start the next until the current one's evidence is recorded.
|
||||
- **End of session**: overwrite `session-handoff.md` with the new stopping point, move finished items from `progress.md` into `archive/YYYY-MM.md` (current month).
|
||||
- Issue/PR conventions (Conventional Commits titles, Project #6 fields, English-only for this public plugin repo) are defined in the `firstsun-pm` skill, not duplicated here.
|
||||
|
||||
## Development Commands
|
||||
- Build: `npm run build` (runs type check and esbuild in production mode)
|
||||
- Dev: `npm run dev` (builds in watch mode using esbuild)
|
||||
|
|
|
|||
9
archive/2026-07.md
Normal file
9
archive/2026-07.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Progress Archive — 2026-07
|
||||
|
||||
One archive file per calendar month. Each entry is one line: feature id/name +
|
||||
commit hash. Debugging narrative and design discussion belong in the commit
|
||||
message, not here. Start a new `archive/YYYY-MM.md` file when the month rolls
|
||||
over — don't let a single archive file grow without bound either.
|
||||
|
||||
- feat-001: Project Setup verified clean (npm install/lint/build/test) (commit 28f4f8e)
|
||||
- feat-002: Settings UX bundle implemented — conflict modal resize + tabs (#42), connection status badge (#41), local ignore patterns (#40); 254 tests pass, lint/build clean (commit 28f4f8e, branch claude/settings-ux-improvements-260713)
|
||||
46
feature_list.json
Normal file
46
feature_list.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"_note": "GitHub Issues (firstsun-dev/git-files-sync, Project #6) is the source of truth for the full backlog and priority/estimate fields. This file mirrors only the active feature and the next few candidates so an agent session has a local, offline checkpoint — sync it against `gh issue list --repo firstsun-dev/git-files-sync --state open` at the start of a session rather than treating it as authoritative.",
|
||||
"features": [
|
||||
{
|
||||
"id": "feat-001",
|
||||
"name": "Project Setup",
|
||||
"description": "Confirm the project can install dependencies, run verification, and start from a clean checkout",
|
||||
"dependencies": [],
|
||||
"status": "done",
|
||||
"evidence": "Commit 28f4f8e - npm install/lint/build/test all pass from a clean checkout"
|
||||
},
|
||||
{
|
||||
"id": "feat-002",
|
||||
"name": "Settings UX bundle (issues #40, #41, #42)",
|
||||
"description": "Local ignore-pattern sync setting (#40), persistent connection status badge in settings (#41), and resized/tabbed conflict resolution modal (#42)",
|
||||
"dependencies": ["feat-001"],
|
||||
"status": "in-review",
|
||||
"evidence": "Commit 28f4f8e on branch claude/settings-ux-improvements-260713 - lint/build/test pass (254 tests); pushed to origin, PR not yet opened"
|
||||
},
|
||||
{
|
||||
"id": "feat-003",
|
||||
"name": "fix: symbolic link pull fails (issue #33)",
|
||||
"description": "Bug report with screenshot; needs repro/investigation before a fix can be scoped",
|
||||
"dependencies": [],
|
||||
"status": "not-started",
|
||||
"evidence": ""
|
||||
},
|
||||
{
|
||||
"id": "feat-004",
|
||||
"name": "fix: resolve sonarqube issues (issue #45)",
|
||||
"description": "Review current SonarQube findings and fix code smells/bugs/security hotspots where applicable",
|
||||
"dependencies": [],
|
||||
"status": "not-started",
|
||||
"evidence": ""
|
||||
},
|
||||
{
|
||||
"id": "feat-005",
|
||||
"name": "feat(settings): folder picker for root path / vault folder (issue #48)",
|
||||
"description": "Searchable folder suggester for the Root path and Vault folder settings fields, replacing free-text entry",
|
||||
"dependencies": [],
|
||||
"status": "not-started",
|
||||
"evidence": ""
|
||||
}
|
||||
],
|
||||
"_evidenceStyle": "Keep evidence to one line: commit hash + short pointer (e.g. 'Commit abc1234 - added X, tests pass'). Debugging narrative and design discussion belong in the commit message, not this file."
|
||||
}
|
||||
24
init.sh
Executable file
24
init.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "=== Harness Initialization ==="
|
||||
|
||||
echo "=== npm install ==="
|
||||
npm install
|
||||
|
||||
echo "=== npm run lint ==="
|
||||
npm run lint
|
||||
|
||||
echo "=== npm test ==="
|
||||
npm test
|
||||
|
||||
echo "=== npm run build ==="
|
||||
npm run build
|
||||
|
||||
echo "=== Verification Complete ==="
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Read feature_list.json to see current feature state"
|
||||
echo "2. Pick ONE unfinished feature to work on"
|
||||
echo "3. Implement only that feature"
|
||||
echo "4. Re-run verification before claiming done"
|
||||
66
progress.md
Normal file
66
progress.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Session Progress Log
|
||||
|
||||
<!--
|
||||
CLEANUP CADENCE: this file tracks only what's still open. When a feature
|
||||
finishes, move its narrative to archive/YYYY-MM.md (current month) as a
|
||||
one-line entry (name + commit hash) and remove it from here. Archive once
|
||||
this file passes ~80 lines — "What's Done" is a snapshot, not a permanent
|
||||
changelog.
|
||||
-->
|
||||
|
||||
Completed work is archived in [archive/](./archive/), one file per calendar month — this file only tracks what's still open.
|
||||
|
||||
## Current State
|
||||
|
||||
**Last Updated:** 2026-07-13 11:40
|
||||
**Session ID:** session_01YYCTyZw7gUmJ7oh1VTmAqh
|
||||
**Active Feature:** feat-002 - Settings UX bundle (issues #40, #41, #42)
|
||||
|
||||
## Status
|
||||
|
||||
### What's Done
|
||||
|
||||
- [x] feat-001 - Project Setup verified (see archive/2026-07.md)
|
||||
- [x] feat-002 implementation - all three sub-features coded, tested, linted, built (see archive/2026-07.md)
|
||||
|
||||
### What's In Progress
|
||||
|
||||
- [ ] feat-002 - Open a PR for branch `claude/settings-ux-improvements-260713` and get it merged
|
||||
- Details: commit 28f4f8e is pushed to origin; no PR opened yet
|
||||
- Blockers: none, just needs `gh pr create`
|
||||
|
||||
### What's Next
|
||||
|
||||
1. Open PR for `claude/settings-ux-improvements-260713`, close issues #40/#41/#42 on merge
|
||||
2. Pick up feat-003 (issue #33, symlink pull fails) — needs repro investigation first
|
||||
3. Re-sync this file's backlog entries against `gh issue list --repo firstsun-dev/git-files-sync --state open` since new issues may have been filed (e.g. #48 folder picker was added mid-session)
|
||||
|
||||
## Blockers / Risks
|
||||
|
||||
- None currently.
|
||||
|
||||
## Decisions Made
|
||||
|
||||
- **Discarded a stale local WIP for Obsidian 1.12.x compatibility**: origin/main already shipped this via PR #46 (`applyDestructiveStyle`, `typecheck-compat.mjs`) with a different mechanism. Local main was fast-forwarded to origin/main and the new features (#40/#41/#42) were manually re-applied on top of the correct base rather than merged via `git stash pop` (which would have conflicted/duplicated the compat layer).
|
||||
- **feat-002 bundles three issues in one commit**: #40/#41/#42 touch overlapping files (`src/settings.ts`, `styles.css`, `tests/setup.ts`) closely enough that splitting into three atomic commits wasn't worth the risk of an intermediate broken state.
|
||||
|
||||
## Files Modified This Session
|
||||
|
||||
- `src/settings.ts` - connection status badge (#41), ignore patterns setting (#40)
|
||||
- `src/ui/SyncConflictModal.ts` - Diff/Local/Remote tab switcher (#42)
|
||||
- `src/logic/gitignore-manager.ts`, `src/main.ts` - local ignore pattern matching (#40)
|
||||
- `styles.css` - badge + modal + tab styles
|
||||
- `tests/setup.ts`, `tests/ui/setup-dom.ts` - expanded Obsidian mocks (TextAreaComponent, removeClass, configDir, etc.)
|
||||
- `tests/logic/gitignore-manager.test.ts`, `tests/logic/sync-manager*.test.ts`, `tests/ui/SyncConflictModal.test.ts`, `tests/ui/SettingsConnectionStatus.test.ts` - new/updated tests
|
||||
|
||||
## Evidence of Completion
|
||||
|
||||
- [x] Tests pass: `npx vitest run` → 254/254 passed
|
||||
- [x] Type check clean: `npm run build` (tsc + Obsidian 1.11.0 compat typecheck + esbuild) → clean
|
||||
- [x] Lint clean: `npx eslint .` → 0 errors
|
||||
- [ ] Manual verification in Obsidian: not done (no Obsidian instance available in this environment)
|
||||
|
||||
## Notes for Next Session
|
||||
|
||||
- Branch `claude/settings-ux-improvements-260713` is pushed but has no PR yet — check with the user before opening one (they were asked and hadn't confirmed as of session end).
|
||||
- `feature_list.json`'s backlog (feat-003..005) is a snapshot from 2026-07-13; re-check `gh issue list` before trusting it.
|
||||
59
session-handoff.md
Normal file
59
session-handoff.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# Session Handoff
|
||||
|
||||
<!--
|
||||
OVERWRITE, don't append: this file describes only the most recent session.
|
||||
Rewrite it at end of session; older handoffs live in git history, and completed
|
||||
work belongs in archive/YYYY-MM.md. If this file grows past ~80 lines, it is
|
||||
accumulating history instead of handing off.
|
||||
-->
|
||||
|
||||
## Current Objective
|
||||
|
||||
- Goal: Implement issues #40 (local ignore patterns), #41 (settings connection status badge), #42 (resize conflict modal)
|
||||
- Current status: Implemented, tested, linted, built clean; committed and pushed. PR not yet opened (pending user confirmation).
|
||||
- Branch / commit: `claude/settings-ux-improvements-260713` @ 28f4f8e
|
||||
|
||||
## Completed This Session
|
||||
|
||||
- [x] #42 - Resized conflict modal (`min(1100px,92vw) x min(85vh,800px)`, flex layout, removed 280px content cap, added Diff/Local/Remote tab switcher on narrow screens)
|
||||
- [x] #41 - Persistent connection status badge in settings tab (Checking/Connected/Not connected), 800ms debounce on token/branch/URL/owner/repo edits, updates in place (no focus-stealing re-render)
|
||||
- [x] #40 - "Ignore patterns" setting (multi-line, .gitignore-style), applied in `GitignoreManager.isIgnored()` additively alongside remote/local `.gitignore`
|
||||
- [x] Filed issue #48 (folder picker for root path / vault folder settings) at user's request mid-session
|
||||
- [x] Rebased local `main` onto `origin/main` to adopt the already-shipped Obsidian 1.12.x compat work (PR #46), discarding a stale duplicate local WIP, then re-applied the above three features cleanly on top
|
||||
|
||||
## Verification Evidence
|
||||
|
||||
| Check | Command | Result | Notes |
|
||||
|---|---|---|---|
|
||||
| Lint | `npx eslint .` | 0 errors | Repo-wide, no exceptions |
|
||||
| Type check + compat | `npm run build` | Pass | Includes `typecheck-compat.mjs` against Obsidian 1.11.0 |
|
||||
| Tests | `npx vitest run` | 254/254 passed | 17 test files |
|
||||
| Manual (in Obsidian) | — | Not done | No Obsidian instance available in this environment |
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `src/settings.ts`, `src/ui/SyncConflictModal.ts`, `src/logic/gitignore-manager.ts`, `src/main.ts`, `styles.css`
|
||||
- `tests/setup.ts`, `tests/ui/setup-dom.ts` (expanded Obsidian test mocks)
|
||||
- `tests/logic/gitignore-manager.test.ts`, `tests/logic/sync-manager.test.ts`, `tests/logic/sync-manager-mapping.test.ts`
|
||||
- `tests/ui/SyncConflictModal.test.ts`, `tests/ui/SettingsConnectionStatus.test.ts` (new)
|
||||
|
||||
## Decisions Made
|
||||
|
||||
- Bundled #40/#41/#42 into a single commit rather than three, since they touch overlapping files closely enough that atomic per-issue commits risked an intermediate broken build.
|
||||
- Discarded the local uncommitted 1.12.x-compat WIP (user confirmed it was superseded by origin/main's PR #46) rather than trying to merge two different compat mechanisms.
|
||||
|
||||
## Blockers / Risks
|
||||
|
||||
- None blocking. Open item: PR for the pushed branch hasn't been created — user was asked "要接著幫你開 PR 嗎?" and the session moved to harness setup before they answered.
|
||||
|
||||
## Next Session Startup
|
||||
|
||||
1. Read `CLAUDE.md`.
|
||||
2. Read `feature_list.json` and `progress.md`.
|
||||
3. Review this handoff.
|
||||
4. Run `./init.sh` before editing.
|
||||
5. Check whether the user wants a PR opened for `claude/settings-ux-improvements-260713` before starting new work.
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
- Ask the user whether to open the PR for the pushed branch; if yes, use `gh pr create` per the repo's PR conventions (see `CLAUDE.md` / firstsun-pm workflow) and reference issues #40/#41/#42 so they auto-close on merge.
|
||||
Loading…
Reference in a new issue