Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,7 @@ docs/plans/

# Marketing content
contents/

# Runtime artifacts
.ouroboros/
local.db
46 changes: 38 additions & 8 deletions docs/agent/PLUGIN.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@ Claude Code plugin at `packages/plugin/`. MCP server + queued auto-analysis hook
| File | Purpose |
|------|---------|
| `mcp/server-entry.ts` | Bootstrap entry point — installs native deps (better-sqlite3) then dynamically imports server.ts. Enables single-session install-to-result flow |
| `mcp/server.ts` | MCP server, stdio transport, registers 13 tools (10 local-first + 3 server-backed) |
| `mcp/server.ts` | MCP server, stdio transport, registers 17 tools (14 local-first + 3 server-backed) |
| `mcp/tools/scan-sessions.ts` | Tool: scan Claude Code + Cursor session logs, return metadata |
| `mcp/tools/extract-data.ts` | Tool: deterministic Phase 1 extraction + scoring |
| `mcp/tools/save-domain-results.ts` | Tool: save domain analysis with Zod validation + quality gates |
| `mcp/tools/get-domain-results.ts` | Tool: read saved domain results (one or all) |
| `mcp/tools/get-run-progress.ts` | Tool: inspect current run progress and resume point |
| `mcp/tools/classify-developer-type.ts` | Tool: deterministic type classification (5x3 matrix) |
| `mcp/tools/verify-evidence.ts` | Tool: deterministic evidence verification + stage persistence |
| `mcp/tools/generate-report.ts` | Tool: generate HTML report + localhost server |
| `mcp/tools/sync-to-team.ts` | Tool: sync results to team server (optional) |
| `mcp/tools/save-stage-output.ts` | Tool: save pipeline stage output with schema validation |
| `mcp/tools/get-stage-output.ts` | Tool: read pipeline stage outputs (one or all) |
| `mcp/tools/get-prompt-context.ts` | Tool: stage/domain-specific prompt payloads for skills |
| `mcp/tools/get-user-prefs.ts` | Tool: read user preferences (selected projects, onboarding state) |
| `mcp/tools/save-user-prefs.ts` | Tool: save user preferences |
| `mcp/tools/get-developer-profile.ts` | Tool (server-backed): profile type, scores, personality |
| `mcp/tools/get-growth-areas.ts` | Tool (server-backed): growth areas, optional domain filter |
| `mcp/tools/get-recent-insights.ts` | Tool (server-backed): strengths / anti-patterns / KPT |
Expand All @@ -32,6 +36,7 @@ Claude Code plugin at `packages/plugin/`. MCP server + queued auto-analysis hook
| `lib/api-client.ts` | HTTP client, `fetchUserSummary()`, `verifyAuth()` |
| `lib/prefs.ts` | User preferences (`~/.betterprompt/prefs.json`), first-run detection |
| `lib/debounce.ts` | Debounce rules, state file read/write |
| `lib/project-filters.ts` | Session filtering by selected projects |
| `lib/background-analyzer.ts` | Deprecated cutover stub kept only to fail loudly if invoked |
| `lib/core/session-scanner.ts` | Claude Code JSONL parsing and local data-dir helpers |
| `lib/core/multi-source-session-scanner.ts` | Multi-source scanner coordinator (Claude Code + Cursor) |
Expand Down Expand Up @@ -67,18 +72,22 @@ Claude Code plugin at `packages/plugin/`. MCP server + queued auto-analysis hook
| `extract_data` | `maxSessions?: number` (default 50), `includeProjects?: string[]` | `{ runId, metrics, deterministicScores }` |
| `save_domain_results` | `domain: enum`, `overallScore`, `strengths[]`, `growthAreas[]`, `data?: {}` | `{ domain, score, runId }` |
| `get_domain_results` | `domain?: enum` | Single domain or all saved domains |
| `get_run_progress` | none | `{ runId, completionStatus, nextStep, stages[] }` |
| `verify_evidence` | `threshold?` | `{ totalEvidence, keptCount, filteredCount, domainStats[] }` |
| `classify_developer_type` | none | `{ primaryType, controlLevel, matrixName, matrixEmoji, distribution }` |
| `generate_report` | `port?: number`, `openBrowser?: boolean`, `allowIncomplete?: boolean` | `{ url, reportPath }` |
| `sync_to_team` | `serverUrl?: string` | `{ serverUrl }` |
| `save_stage_output` | `stage: enum`, `data: {}` | `{ stage, runId }` |
| `get_stage_output` | `stage?: string` | Single stage output or all stages |
| `get_prompt_context` | `kind: enum`, `domain?: enum` | Stage/domain-specific prompt payload |
| `get_user_prefs` | none | User preferences (selected projects, onboarding state) |
| `save_user_prefs` | `prefs: {}` | Save user preferences |

Domain enum: `thinkingQuality`, `communicationPatterns`, `learningBehavior`, `contextEfficiency`, `sessionOutcome`, `content`
Domain enum: `aiPartnership`, `sessionCraft`, `toolMastery`, `skillResilience`, `sessionMastery`

Stage enum: `sessionSummaries`, `projectSummaries`, `weeklyInsights`, `typeClassification`, `evidenceVerification`, `contentWriter`, `translator`
Stage enum: `sessionSummaries`, `extractAiPartnership`, `extractSessionCraft`, `extractToolMastery`, `extractSkillResilience`, `extractSessionMastery`, `projectSummaries`, `weeklyInsights`, `typeClassification`, `evidenceVerification`, `contentWriter`

Prompt context kinds: `sessionSummaries`, `domainAnalysis`, `projectSummaries`, `weeklyInsights`, `typeClassification`, `evidenceVerification`, `contentWriter`, `translation`
Prompt context kinds: `sessionSummaries`, `domainAnalysis`, `projectSummaries`, `weeklyInsights`, `typeClassification`, `evidenceVerification`, `contentWriter`

### Server-Backed Tools (backward compatible)

Expand Down Expand Up @@ -167,18 +176,39 @@ generate_report / sync_to_team → markAnalysisComplete()
## Local-First Analysis Pipeline

```
scan_sessions → extract_data → [domain analyses via save_domain_results] →
[save_stage_output for each stage] → classify_developer_type
scan_sessions → extract_data → [agent-dispatched skills] →
classify_developer_type → verify_evidence
generate_report → (optional) sync_to_team
```

Tools use `get_prompt_context` to retrieve stage/domain-specific prompt payloads instead of reading raw Phase 1 files. Domain analyses and stage outputs are validated with Zod schemas and quality gates before persistence.
### Agent-Based Dispatch

`bp analyze` dispatches each analysis skill as an **isolated Agent** (via Claude Code's Agent tool) rather than running skills inline. This prevents context accumulation across stages and enables per-stage model selection.

Each agent reads its skill instructions, calls MCP tools (`get_prompt_context`, `save_stage_output`, `save_domain_results`), and returns. The orchestrator tracks progress via `get_run_progress` and dispatches the next agent.

### Model Tiering

| Tier | Model | Skills |
|------|-------|--------|
| Orchestrator | sonnet | bp-analyze |
| Extraction | haiku | extract-ai-partnership, extract-session-craft, extract-tool-mastery, extract-skill-resilience, extract-session-mastery |
| Summarization | haiku | summarize-sessions, summarize-projects, generate-weekly-insights |
| Narrative | sonnet | write-ai-partnership, write-session-craft, write-tool-mastery, write-skill-resilience, write-session-mastery |
| Classification | sonnet | classify-type |
| Content | sonnet | write-content, translate-report |

### Resume

`bp analyze` calls `get_run_progress` before Phase 1. If a prior run is incomplete, it resumes from the first missing required stage instead of rerunning extraction. `nextStep.tool` is used for deterministic stages like `verify_evidence`; `nextStep.skill` is used for agent-dispatched stages.

Writer contract: `write-*` skills must include `severity` on every growth area, include the domain `data` payload, and retry `save_domain_results` locally on validation errors.

### Stage Gate

`generate_report` checks all required stages before generating:

Required stages: `sessionSummaries`, `thinkingQuality`, `communicationPatterns`, `learningBehavior`, `contextEfficiency`, `sessionOutcome`, `projectSummaries`, `weeklyInsights`, `typeClassification`, `evidenceVerification`, `contentWriter`
Required stages (5-dimension pipeline): `sessionSummaries`, `extractAiPartnership`, `extractSessionCraft`, `extractToolMastery`, `extractSkillResilience`, `extractSessionMastery`, `aiPartnership`, `sessionCraft`, `toolMastery`, `skillResilience`, `sessionMastery`, `projectSummaries`, `weeklyInsights`, `typeClassification`, `evidenceVerification`, `contentWriter`

Pass `allowIncomplete=true` to override the gate.

Expand Down
26 changes: 1 addition & 25 deletions packages/plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,35 +1,11 @@
{
"name": "betterprompt",
"displayName": "BetterPrompt",
"version": "0.2.0",
"description": "Local-first AI collaboration analysis — surfaces your collaboration patterns, growth areas, and anti-patterns directly in Claude Code without requiring a server.",
"author": {
"name": "BetterPrompt"
},
"repository": "https://github.com/onlycastle/BetterPrompt",
"skills": "./skills/",
"mcpServers": "./.mcp.json",
"configuration": {
"serverUrl": {
"type": "string",
"required": false,
"default": "http://localhost:3000",
"description": "URL of your BetterPrompt server (only needed for team sync mode)"
},
"autoAnalyze": {
"type": "boolean",
"default": true,
"description": "Queue analysis after enough new sessions accumulate and auto-resume it in the next Claude Code session"
},
"analyzeThreshold": {
"type": "number",
"default": 5,
"description": "Minimum number of new sessions before triggering auto-analysis"
},
"reportPort": {
"type": "number",
"default": 3456,
"description": "Port for the local report server"
}
}
"mcpServers": "./.mcp.json"
}
Original file line number Diff line number Diff line change
Expand Up @@ -29326,6 +29326,7 @@ import { homedir as homedir2 } from "os";
var COOLDOWN_MS = 4 * 60 * 60 * 1e3;
var MIN_SESSION_DURATION_MS = 3 * 60 * 1e3;
var MAX_RUNNING_STATE_AGE_MS = 30 * 60 * 1e3;
var RUNNING_ANALYSIS_RESUME_GRACE_MS = 45 * 1e3;
var DEFAULT_STATE = {
lastAnalysisTimestamp: null,
lastAnalysisSessionCount: 0,
Expand Down Expand Up @@ -29373,6 +29374,9 @@ function writeState(state) {
)
);
}
function getStateUpdatedAtMs(state) {
return state.stateUpdatedAt ? new Date(state.stateUpdatedAt).getTime() : Number.NaN;
}
function countClaudeSessions() {
const projectsDir = join3(homedir2(), ".claude", "projects");
try {
Expand All @@ -29397,7 +29401,7 @@ function recoverStaleAnalysisState(options) {
if (state.analysisState !== "running") {
return state;
}
const updatedAt = state.stateUpdatedAt ? new Date(state.stateUpdatedAt).getTime() : Number.NaN;
const updatedAt = getStateUpdatedAtMs(state);
const isStale = options?.force || Number.isNaN(updatedAt) || Date.now() - updatedAt > MAX_RUNNING_STATE_AGE_MS;
if (!isStale) {
return state;
Expand Down Expand Up @@ -29457,6 +29461,13 @@ function markAnalysisStarted() {
lastError: null
});
}
function touchAnalysisHeartbeat() {
const state = readState();
if (state.analysisState !== "running") {
return;
}
writeState(state);
}
function markAnalysisComplete(sessionCount) {
debug("debounce", "state transition: -> complete");
writeState({
Expand Down Expand Up @@ -29502,6 +29513,14 @@ function clearAnalysisPending() {
pendingSince: null
});
}
function shouldResumeRunningAnalysis(now = Date.now()) {
const state = readState();
if (state.analysisState !== "running") {
return false;
}
const updatedAt = getStateUpdatedAtMs(state);
return Number.isNaN(updatedAt) || now - updatedAt > RUNNING_ANALYSIS_RESUME_GRACE_MS;
}

export {
$constructor,
Expand Down Expand Up @@ -29554,10 +29573,12 @@ export {
recoverStaleAnalysisState,
shouldTriggerAnalysis,
markAnalysisStarted,
touchAnalysisHeartbeat,
markAnalysisComplete,
markAnalysisFailed,
markAnalysisPending,
isAnalysisPending,
clearAnalysisPending
clearAnalysisPending,
shouldResumeRunningAnalysis
};
//# sourceMappingURL=chunk-KAELRNDJ.js.map
//# sourceMappingURL=chunk-72GWNTBD.js.map

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions packages/plugin/dist/chunk-NH4BKYT6.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/plugin/dist/chunk-NH4BKYT6.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading