Commit graph

65 commits

Author SHA1 Message Date
dj-oyu
0e86e63db8 merge: feat/task-2-subagent-orchestration
TASKS-2 Subagent Orchestration (Container Model):
- ContainerMessage + channel-based escalation tools
- Deliberate (plan-first) and Exploratory preset workflows
- AskConductor/SubmitPlan (subagent) + Answer/Review (conductor)
- SessionRecorder DAG integration (question/plan turns)
- Environment context injection and orchestration guidance
- gci import ordering fix across pkg/{tools,agent,session}

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 02:03:02 +09:00
dj-oyu
7b70d70252 feat(tasks-2): implement subagent orchestration container model
Add Container Model for subagent↔conductor communication:
- ContainerMessage + channel-based escalation (ask_conductor, submit_plan)
- Deliberate vs Exploratory preset workflows with SubagentPlanState
- AnswerSubagentTool + ReviewSubagentPlanTool for conductor side
- SessionRecorder extensions (RecordQuestion, RecordPlanSubmit)
- Environment context injection (MEMORY.md extraction, plan context)
- Orchestration guidance with escalation tools documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 01:36:25 +09:00
dj-oyu
2f156f4ef5 feat(task4): refactor miniapp static serving and frontend bundle/tests 2026-03-05 01:31:41 +09:00
dj-oyu
6af0cab7af docs(tasks): add TASKS-7 for provider wire compatibility concerns 2026-03-05 00:40:31 +09:00
dj-oyu
e4af360184 merge: bring task1 memory/performance and docs updates 2026-03-05 00:14:10 +09:00
dj-oyu
80d502ac7b docs(tasks): align CLAUDE and TASKS-2 with task1 state 2026-03-05 00:11:34 +09:00
dj-oyu
10ca7828ef docs: add TASKS-6 skeleton for SOUL.md persona evolution
Sleep-driven persona reconstruction: integrate experiences from
session turns, apply forgetting pressure, rewrite SOUL.md.
Blocked on TASKS-2 (orchestration) completion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:56:19 +09:00
dj-oyu
1ecd70c62a feat(task1): implement memory and performance optimizations 2026-03-04 23:54:01 +09:00
dj-oyu
6210eaae4c feat(session): add /session CLI commands and Mini App graph UI (TASKS-3 Phase 3)
- Refactor handleSessionCommand into subcommand dispatcher (list/graph/fork/reset)
- Add SessionGraphNode type and GetSessionGraph() for Mini App API
- Add /miniapp/api/sessions/graph endpoint with SSE integration
- Add session tree rendering in Mini App frontend
- Mark TASKS-3 fully complete (Phase 0-3)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:22:14 +09:00
dj-oyu
c3053052ee Merge branch 'feat/task-3-session-dag-sqlite' into codex/fix-telegram-thread-conversation-issues 2026-03-04 22:49:40 +09:00
dj-oyu
df4e65069b feat(session): add CompactOldTurns, SessionGraph, and session lifecycle (TASKS-3 Phase 2)
- CompactOldTurns: turn-granularity compaction replacing full-rewrite path
- SessionGraph + TurnWriter: thin wrapper for future staged migration
- Startup Prune (7d TTL) + periodic prune (6h) in flushLoop
- AgentLoop gcLoop: 30min GC of idle sessionLocks entries
- Wire CompactOldTurns into summarizeSession with fallback

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 22:49:17 +09:00
dj-oyu
adadcc5f51 Merge branch 'feat/task-5-heartbeat-worktree-management' into codex/fix-telegram-thread-conversation-issues 2026-03-04 22:46:11 +09:00
dj-oyu
7bdac60160 feat(task5): add worktree management commands and miniapp 2026-03-04 22:45:44 +09:00
dj-oyu
934027affb feat(session): add Fork/Report turn recording for session DAG (TASKS-3 Phase 1)
Introduce SessionRecorder interface to bridge pkg/tools → pkg/session
without circular imports. SubagentManager now records Fork, Turn, and
Completion events in SQLite. processSystemMessage writes TurnReport
directly to the store with AdvanceStored to prevent double-writes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 22:15:32 +09:00
dj-oyu
6062b17ba5 feat(session): implement SQLite SessionStore + LegacyAdapter (TASKS-3 Phase 0)
Replace JSON file-based session storage with SQLite backend while
maintaining full backward compatibility through LegacyAdapter.

New files:
- pkg/session/types.go: Turn, SessionInfo, CreateOpts, ListFilter types
- pkg/session/store.go: SessionStore interface (15 methods)
- pkg/session/sqlite.go: SQLite implementation (WAL mode, modernc.org/sqlite)
- pkg/session/legacy_adapter.go: wraps SessionStore with SessionManager API
- pkg/session/migrate.go: JSON → SQLite migration at startup

Changes:
- pkg/agent/instance.go: Sessions type changed to *LegacyAdapter
- loop.go / loop_test.go: zero changes (method signatures identical)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:55:13 +09:00
dj-oyu
81a8abf1f2 docs: split CLAUDE.md tasks into parallel todo tracks
Extract all unimplemented design plans and tasks from CLAUDE.md into
5 independent todo files, each targeting a separate branch for parallel
implementation:

- TASKS-1: Memory & Performance Optimization
- TASKS-2: Subagent Orchestration (Container Model)
- TASKS-3: Session DAG (SQLite Store)
- TASKS-4: Mini App & Static Serving
- TASKS-5: Heartbeat Worktree Management

CLAUDE.md now retains only implemented references, coding guidelines,
and a summary table linking to each todo file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:20:50 +09:00
dj-oyu
5c046cecfc docs: add revised Session DAG design with SBC-friendly constraints
Append refined design below the initial DAG Migration Plan, based on
SBC performance constraints and design review:

- Session-internal linearity, inter-session DAG (no per-message nodes)
- SQLite single-file backend instead of per-node JSON files
- Subagent reports as user-role turns instead of system-role merge nodes
- Turn-granularity segments with cached linear view
- Concrete Go interfaces (SessionStore, SessionGraph, TurnWriter)
- 4-phase migration path with LegacyAdapter for backward compatibility

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 19:31:51 +09:00
dj-oyu
65d4c794ce docs: add session DAG migration plan with parallel work tracks 2026-03-04 19:01:47 +09:00
dj-oyu
d07c527f23 docs: add Mini App static file serving and bundler considerations to CLAUDE.md 2026-02-25 05:15:08 +09:00
dj-oyu
2952f2da73 refactor: introduce orch.AgentReporter — decouple Broadcaster from SubagentManager
- Add pkg/orch/reporter.go: AgentReporter interface + Noop singleton
- Broadcaster now implements AgentReporter (ReportSpawn/StateChange/Conversation/GC)
- ToolLoopConfig: replace OnStateChange func with Reporter+AgentID
- SubagentManager: accept AgentReporter in constructor, remove internal Broadcaster
  and GetBroadcaster(); all Publish calls replaced with Report* calls
- AgentLoop: add orchBroadcaster/*orchReporter fields, reporter() nil-safe helper,
  SetOrchReporter/GetOrchBroadcaster public API
- NewAgentLoop: create struct before registerSharedTools so al.reporter() is
  available; auto-detect orchestration from registry config
- runAgentLoop: ReportSpawn on entry, defer ReportGC on exit
- runLLMIteration: ReportStateChange("waiting") before LLM call,
  ReportStateChange("toolcall", name) before each tool execution
- cmd_gateway.go: wire GetOrchBroadcaster() → handler.SetOrchBroadcaster()
- Update subagent_tool_test.go for new constructor signature
- Document hierarchy in CLAUDE.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 04:01:17 +09:00
dj-oyu
253d4f5dbc docs: rewrite CLAUDE.md with full orchestration design
- Remove completed Security TODOs and detailed memory optimization
  task lists (A-H tables, Phase 0-4 plans)
- Keep architectural insights: D-1~D-6, code smells checklist,
  storage protection strategy
- Subagent orchestration design fully updated with:
  - Why orchestration: fork, conductor-as-manager, conversation fork
  - Bidirectional channel (ContainerMessage: question/result/status)
  - Preset classification: Exploratory vs Deliberate
  - Subagent plan mode: in-memory clarifying/review/executing
  - MEMORY.md ## Orchestration section (Delegated/Findings/Decisions)
  - Context injection from MEMORY.md (auto inject_plan_context)
  - Search tools allowed for all presets
  - Startup flag --orchestration design
  - Conductor identity system prompt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 01:46:27 +09:00
dj-oyu
9cd51612ac docs: add subagent container design to CLAUDE.md
Design decisions from sub-agent-technical-breakdown session:
- SubagentContainer with goroutine/channel lifecycle model
- 5 presets (scout/analyst/coder/worker/coordinator)
- SandboxConfig with write root, exec allowlist regex, spawn permissions
- npm excluded from all presets (worktree node_modules problem)
- pnpm/bun/uv run added to coder and worker
- Conductor identity and orchestration guidance for system prompt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 01:21:31 +09:00
dj-oyu
e0538ef1cc refactor: move worktree directory to workspace/.worktrees/
Previously workspace/.picoclaw/worktrees/ which created redundant
nesting since workspace is already under ~/.picoclaw/. The dot prefix
hides the directory from normal project listings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:10:23 +09:00
dj-oyu
ec7b98708d docs: fix session roadmap — clarify lazy loading vs cross-session search tradeoff inline
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 15:09:08 +09:00
dj-oyu
ba38e2c9e9 docs: add 13th review feedback (R-1) — lazy loading vs cross-session search contradiction
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 15:08:03 +09:00
dj-oyu
06d6969f3a Merge branch 'worktree-memory-optimization-impl' into memory-optimization-review 2026-02-24 15:06:11 +09:00
dj-oyu
6623c44ae4 docs: add session management future roadmap to Phase 5
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 15:05:50 +09:00
dj-oyu
94d599fea1 docs: apply review Q feedback — clarify telegram.go B table entry
Q-1: Annotate that extractMarkdownTables() out slice already has capacity
hint (L834), only tables (L835) needs fix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:02:43 +09:00
dj-oyu
b20a8c2a08 docs: add 12th review feedback (Q-1) — B table telegram.go entry includes already-implemented out slice
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 15:01:59 +09:00
dj-oyu
ee1a625dcb docs: apply review P feedback — add missing Phase 0-2 items, annotate B table
P-1: Add telegram.go extractMarkdownTables() tables slice to Phase 0-2.
Mark toolloop.go as already implemented in B candidate table.
Mark session_tracker.go:121 as excluded (active session count unknown at
call time, static estimate not possible).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:53:28 +09:00
dj-oyu
c8f96d66c6 docs: add 11th review feedback (P-1) — Phase 0-2 missing two medium-priority B items
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:51:50 +09:00
dj-oyu
8a512a6168 docs: apply review O feedback — fix push() name, add reTaskLine to Phase 0-4
O-1: Fix Phase 1 annotation: add() → push() (actual ring buffer method name
at logger.go L69).

O-2: Add memory.go L567/L663 inline regexp.MustCompile to Phase 0-4 table
— both are identical to existing package variable reTaskLine (L469).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:48:08 +09:00
dj-oyu
ee0167e043 docs: add 10th review feedback (O-1, O-2) — push() naming error and reTaskLine inline omissions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:45:54 +09:00
dj-oyu
1d11874c54 docs: apply review N/M feedback — remove unsafe Phase 1 items, fix Phase 3-2 scope
N-1: Remove session_tracker.go ListActive() → []*SessionEntry (value copy
is the only concurrency safety with lockless Touch(); ~80 byte struct copy
is negligible at UI-request frequency).

N-2: Remove skills/registry.go pointer-to-interface proposal (SkillRegistry
is already an interface; *SkillRegistry is an antipattern; 2-5 × 16-byte
copy is negligible).

M-1: Fix Phase 3-2 scope note — replace GetReviewContext (no Split) with
GetPlanContext/FormatPlanDisplay (actual Split users).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:35:56 +09:00
dj-oyu
463be3d777 docs: add 9th review feedback (N-1, N-2) — false optimizations in Phase 1
N-1: session_tracker.go ListActive() returning []*SessionEntry is unsafe.
Touch() mutates *SessionEntry fields directly without per-struct lock.
The current *entry value copy (L125) is the only safety mechanism. Pointer
return exposes live objects to concurrent Touch() writes. Also no meaningful
perf benefit (~80 byte structs, low-frequency UI calls). Remove from Phase 1.

N-2: skills/registry.go registries field is []SkillRegistry (interface type).
"pointer slice" would mean pointer-to-interface, a Go antipattern. Copy cost
is n*16 bytes (n=2-5 typical) — negligible. Remove from Phase 1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:30:58 +09:00
dj-oyu
ee0afbe193 docs: add 8th review feedback (M-1) to CLAUDE.md
M-1: Phase 3-2 "効果範囲の限定" example incorrectly lists GetReviewContext
as a split optimization target — it only does sb.WriteString(content) with
no split helpers. Same for GetInterviewContext. Actual targets are
GetPlanContext and FormatPlanDisplay (already correct in the action section).
No impact on implementation correctness.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:25:49 +09:00
dj-oyu
7b8531cdd0 docs: apply seventh review feedback L-1, remove FEEDBACK section
- L-1: Phase 3-2 Split target corrected from GetMemoryContext()
  (which doesn't call Split helpers directly) to GetPlanContext()
  and FormatPlanDisplay() (which both call extractPhaseContent,
  extractCommandsSection, extractContextSection)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:23:30 +09:00
dj-oyu
ba1c8a75fa docs: add 7th review feedback (L-1) to CLAUDE.md
L-1: Phase 3-2 incorrectly lists GetMemoryContext() as a strings.Split
optimization target — it doesn't directly call any split helpers after
Phase 3-1. GetPlanContext() is the correct target: it calls
extractPhaseContent, extractCommandsSection, extractContextSection
which all split independently on the same content.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:22:05 +09:00
dj-oyu
e52547f17d docs: apply sixth review feedback K-1, remove FEEDBACK section
- K-1: add currentPhase inline (rePhase.FindStringSubmatch) to
  FormatPlanDisplay() snippet — was missing, leaving an extra
  ReadLongTerm() call

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:19:41 +09:00
dj-oyu
ac233c77c7 docs: add 6th review feedback (K-1) to CLAUDE.md
K-1: Phase 3-1 FormatPlanDisplay() snippet omits GetCurrentPhase() L667
inlining — currentPhase is used at L672/L676-680 and ReadLongTerm() would
remain after the fix. Add rePhase.FindStringSubmatch inline to snippet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:18:43 +09:00
dj-oyu
435f9eab6c docs: apply fifth review feedback J-1~J-2, remove FEEDBACK section
- J-1: fix Phase 3-1 snippets — split by function, correct status
  type ([]string→m[1]), move getPlanPhasesFrom to FormatPlanDisplay
- J-2: add GetPlanContext() L562-563 to Phase 3-1 targets (inline
  GetCurrentPhase/GetTotalPhases to avoid 3 extra ReadLongTerm calls)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:16:27 +09:00
dj-oyu
b6eff3d8cc docs: add 5th review feedback (J-1, J-2) to CLAUDE.md
J-1: Phase 3-1 snippet has two errors vs actual GetMemoryContext() —
getPlanPhasesFrom is only needed in FormatPlanDisplay, not GetMemoryContext;
reStatus.FindStringSubmatch returns []string not string, needs m[1] extraction.

J-2: GetPlanContext() L562-563 has the same inline-able ReadLongTerm
redundancy (GetCurrentPhase + GetTotalPhases) not addressed in Phase 3-1;
after fix GetMemoryContext would still do 4 reads instead of the implied 1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:13:17 +09:00
dj-oyu
f9e7037043 docs: apply fourth review feedback I-1~I-2, remove FEEDBACK section
- I-1: simplify Phase 4-1 — remove dirty flag, just delete save()
  from RecordUsage/RecordPrompt and add ticker + Close()
- I-2: Phase 3-1 uses inline regex calls (not new private functions)
  for HasActivePlan/GetPlanStatus/etc, only GetPlanPhases needs a
  private variant

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:10:56 +09:00
dj-oyu
45a0d4b16e docs: revise I-2 — private helpers are mostly inline regex, not new functions
Most HasActivePlan/GetPlanStatus/GetCurrentPhase/GetTotalPhases calls can
be replaced by inlining the package-level regex vars (L137-145) directly.
Only GetPlanPhases (42 lines) warrants a new private function. Reduce
estimated new function count from 5 down to 1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:04:04 +09:00
dj-oyu
2a32ee74ea docs: audit and revise 4th review feedback with code references
I-1: add exact line numbers (L61/L77/L90/L111), correct "ONLY writers"
claim (Reset() L103 also calls save()), note Close() doesn't exist yet.

I-2: add line numbers for all public methods (L148/L154/L164/L175/L270),
highlight immediate redundancy in GetMemoryContext() L730 and
FormatPlanDisplay() L658 where ReadLongTerm() result is already in scope,
note extractPhaseContent(content,phase) L231 as existing proof-of-pattern,
correct wrong HasActivePlan() body in code sample.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:01:47 +09:00
dj-oyu
e54a49f902 docs: add 4th review feedback (I-1, I-2) to CLAUDE.md
I-1: Phase 4-1 dirty flag is unnecessary for stats.Tracker — only two
writers exist so data is always dirty; simplify to timer-only approach.

I-2: Phase 3-1 private helper functions (hasActivePlanFrom, etc.) do not
yet exist and must be created; plan did not make this explicit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:58:55 +09:00
dj-oyu
1d956d953a docs: apply third review feedback H-1~H-4, remove FEEDBACK section
- H-1: rewrite Phase 4-2 to target loop.go Save() call sites (not
  AddFullMessage which is already in-memory only). L996 becomes dirty
  mark, 4 low-frequency sites keep immediate Save()
- H-2: remove misplaced MarkStep annotation from Phase 1 logger.go
- H-3: add ParsedPlan in-memory model to Phase 5 table
- H-4: update Phase 3 commit count to 2 in summary

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:54:36 +09:00
dj-oyu
b9c6ec17fd docs: clarify H-1 - AddFullMessage() already has no Save() call
The plan's proposed change to AddFullMessage() would reduce zero writes
because AddFullMessage() never called Save() to begin with. Save() is
called explicitly from loop.go at 5 sites; loop.go already controls
persistence timing. Phase 4-2 must be rewritten to target loop.go
Save() calls directly, particularly L996 (per-turn, high frequency).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:51:30 +09:00
dj-oyu
fed503cc59 docs: add third FEEDBACK round to implementation plan review
All G-1~G-4 confirmed resolved. New findings:
H-1 Phase 4-2 misidentifies Save() trigger - it is called from 5
explicit sites in loop.go (not AddFullMessage), with L996 being the
high-frequency per-turn save and L299/836/2339/2568 as semantic
checkpoints needing individual deferral decisions.
H-2 Phase 1 logger.go row has misplaced MarkStep note from Phase 3-2.
H-3 Phase 5 missing ParsedPlan in-memory model item despite Phase 3-2
referencing it as the prerequisite for mutation-path Split fix.
H-4 Phase 3 summary still shows 1 commit; FormatPlanDisplay addition
makes it 2 commits minimum.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:49:29 +09:00
dj-oyu
db78df5172 docs: apply second review feedback G-1~G-4, remove FEEDBACK section
- G-1: update Phase 1 logger to []*LogEntry ring buffer + visit() pattern
- G-2: add FormatPlanDisplay() to Phase 3-1 content passthrough targets
- G-3: limit Phase 3-2 Split dedup scope to read-only paths only
- G-4: consolidate claude_cli_provider.go:133 into Phase 0-3 only

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:46:17 +09:00