@promptwheel/mcp 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +178 -0
- package/dist/advance-helpers.d.ts +27 -0
- package/dist/advance-helpers.d.ts.map +1 -0
- package/dist/advance-helpers.js +127 -0
- package/dist/advance-helpers.js.map +1 -0
- package/dist/advance-prompts.d.ts +48 -0
- package/dist/advance-prompts.d.ts.map +1 -0
- package/dist/advance-prompts.js +420 -0
- package/dist/advance-prompts.js.map +1 -0
- package/dist/advance.d.ts +30 -0
- package/dist/advance.d.ts.map +1 -0
- package/dist/advance.js +752 -0
- package/dist/advance.js.map +1 -0
- package/dist/codebase-index.d.ts +5 -0
- package/dist/codebase-index.d.ts.map +1 -0
- package/dist/codebase-index.js +5 -0
- package/dist/codebase-index.js.map +1 -0
- package/dist/dedup-memory.d.ts +30 -0
- package/dist/dedup-memory.d.ts.map +1 -0
- package/dist/dedup-memory.js +76 -0
- package/dist/dedup-memory.js.map +1 -0
- package/dist/direct-client.d.ts +57 -0
- package/dist/direct-client.d.ts.map +1 -0
- package/dist/direct-client.js +92 -0
- package/dist/direct-client.js.map +1 -0
- package/dist/event-handlers-qa.d.ts +5 -0
- package/dist/event-handlers-qa.d.ts.map +1 -0
- package/dist/event-handlers-qa.js +186 -0
- package/dist/event-handlers-qa.js.map +1 -0
- package/dist/event-handlers-scout.d.ts +5 -0
- package/dist/event-handlers-scout.d.ts.map +1 -0
- package/dist/event-handlers-scout.js +270 -0
- package/dist/event-handlers-scout.js.map +1 -0
- package/dist/event-handlers-ticket.d.ts +5 -0
- package/dist/event-handlers-ticket.d.ts.map +1 -0
- package/dist/event-handlers-ticket.js +232 -0
- package/dist/event-handlers-ticket.js.map +1 -0
- package/dist/event-helpers.d.ts +46 -0
- package/dist/event-helpers.d.ts.map +1 -0
- package/dist/event-helpers.js +125 -0
- package/dist/event-helpers.js.map +1 -0
- package/dist/event-processor.d.ts +15 -0
- package/dist/event-processor.d.ts.map +1 -0
- package/dist/event-processor.js +111 -0
- package/dist/event-processor.js.map +1 -0
- package/dist/formulas.d.ts +27 -0
- package/dist/formulas.d.ts.map +1 -0
- package/dist/formulas.js +109 -0
- package/dist/formulas.js.map +1 -0
- package/dist/guidelines.d.ts +16 -0
- package/dist/guidelines.d.ts.map +1 -0
- package/dist/guidelines.js +44 -0
- package/dist/guidelines.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/learnings.d.ts +42 -0
- package/dist/learnings.d.ts.map +1 -0
- package/dist/learnings.js +117 -0
- package/dist/learnings.js.map +1 -0
- package/dist/project-metadata.d.ts +34 -0
- package/dist/project-metadata.d.ts.map +1 -0
- package/dist/project-metadata.js +617 -0
- package/dist/project-metadata.js.map +1 -0
- package/dist/proposals.d.ts +23 -0
- package/dist/proposals.d.ts.map +1 -0
- package/dist/proposals.js +201 -0
- package/dist/proposals.js.map +1 -0
- package/dist/qa-stats.d.ts +51 -0
- package/dist/qa-stats.d.ts.map +1 -0
- package/dist/qa-stats.js +121 -0
- package/dist/qa-stats.js.map +1 -0
- package/dist/run-manager.d.ts +97 -0
- package/dist/run-manager.d.ts.map +1 -0
- package/dist/run-manager.js +583 -0
- package/dist/run-manager.js.map +1 -0
- package/dist/run-state-bridge.d.ts +13 -0
- package/dist/run-state-bridge.d.ts.map +1 -0
- package/dist/run-state-bridge.js +101 -0
- package/dist/run-state-bridge.js.map +1 -0
- package/dist/scope-policy.d.ts +83 -0
- package/dist/scope-policy.d.ts.map +1 -0
- package/dist/scope-policy.js +278 -0
- package/dist/scope-policy.js.map +1 -0
- package/dist/server.d.ts +18 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +35 -0
- package/dist/server.js.map +1 -0
- package/dist/spindle.d.ts +41 -0
- package/dist/spindle.d.ts.map +1 -0
- package/dist/spindle.js +230 -0
- package/dist/spindle.js.map +1 -0
- package/dist/state.d.ts +36 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +50 -0
- package/dist/state.js.map +1 -0
- package/dist/ticket-worker.d.ts +37 -0
- package/dist/ticket-worker.d.ts.map +1 -0
- package/dist/ticket-worker.js +527 -0
- package/dist/ticket-worker.js.map +1 -0
- package/dist/tool-registry.d.ts +35 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +129 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/execute.d.ts +17 -0
- package/dist/tools/execute.d.ts.map +1 -0
- package/dist/tools/execute.js +418 -0
- package/dist/tools/execute.js.map +1 -0
- package/dist/tools/git.d.ts +7 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +98 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/intelligence.d.ts +10 -0
- package/dist/tools/intelligence.d.ts.map +1 -0
- package/dist/tools/intelligence.js +432 -0
- package/dist/tools/intelligence.js.map +1 -0
- package/dist/tools/session.d.ts +7 -0
- package/dist/tools/session.d.ts.map +1 -0
- package/dist/tools/session.js +533 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/tools/trajectory.d.ts +10 -0
- package/dist/tools/trajectory.d.ts.map +1 -0
- package/dist/tools/trajectory.js +374 -0
- package/dist/tools/trajectory.js.map +1 -0
- package/dist/trajectory-io.d.ts +21 -0
- package/dist/trajectory-io.d.ts.map +1 -0
- package/dist/trajectory-io.js +105 -0
- package/dist/trajectory-io.js.map +1 -0
- package/dist/types.d.ts +229 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# @promptwheel/mcp — MCP Server
|
|
2
|
+
|
|
3
|
+
Stateful MCP server that powers PromptWheel's improvement loop. Exposes tools for session management, scouting, execution, and git operations.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# As stdio MCP server (for Claude Code plugin)
|
|
9
|
+
npx @promptwheel/mcp
|
|
10
|
+
|
|
11
|
+
# Or via the DirectClient API (for any LLM)
|
|
12
|
+
import { DirectClient } from '@promptwheel/mcp/direct-client';
|
|
13
|
+
|
|
14
|
+
const client = await DirectClient.create({ projectPath: '.' });
|
|
15
|
+
client.startSession({ scope: 'src/**', formula: 'security-audit' });
|
|
16
|
+
|
|
17
|
+
while (true) {
|
|
18
|
+
const resp = await client.advance();
|
|
19
|
+
if (resp.next_action === 'STOP') break;
|
|
20
|
+
// ... call your LLM with resp.prompt ...
|
|
21
|
+
await client.ingestEvent('SCOUT_OUTPUT', { proposals: [...] });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
client.endSession();
|
|
25
|
+
await client.close();
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## MCP Tool Reference
|
|
29
|
+
|
|
30
|
+
### Session Management
|
|
31
|
+
|
|
32
|
+
| Tool | Description | Parameters |
|
|
33
|
+
|------|-------------|------------|
|
|
34
|
+
| `promptwheel_start_session` | Initialize a session | `hours?`, `formula?`, `deep?`, `scope?`, `categories?`, `min_confidence?`, `max_prs?`, `step_budget?`, `ticket_step_budget?`, `draft_prs?` |
|
|
35
|
+
| `promptwheel_advance` | Get next action (main loop driver) | — |
|
|
36
|
+
| `promptwheel_ingest_event` | Report event, trigger state transitions | `type`, `payload` |
|
|
37
|
+
| `promptwheel_session_status` | Current session state | — |
|
|
38
|
+
| `promptwheel_end_session` | Finalize session | — |
|
|
39
|
+
| `promptwheel_nudge` | Add hint for next scout cycle | `hint` |
|
|
40
|
+
| `promptwheel_list_formulas` | List available formulas | — |
|
|
41
|
+
| `promptwheel_get_scope_policy` | Get scope policy for current ticket | `file_path?` |
|
|
42
|
+
|
|
43
|
+
### Execution
|
|
44
|
+
|
|
45
|
+
| Tool | Description | Parameters |
|
|
46
|
+
|------|-------------|------------|
|
|
47
|
+
| `promptwheel_next_ticket` | Get next ticket to work on | — |
|
|
48
|
+
| `promptwheel_validate_scope` | Check changed files against scope | `ticketId`, `changedFiles[]` |
|
|
49
|
+
| `promptwheel_complete_ticket` | Mark ticket done, run QA | `ticketId`, `runId`, `summary?` |
|
|
50
|
+
| `promptwheel_fail_ticket` | Mark ticket failed | `ticketId`, `runId`, `reason` |
|
|
51
|
+
|
|
52
|
+
### Git
|
|
53
|
+
|
|
54
|
+
| Tool | Description | Parameters |
|
|
55
|
+
|------|-------------|------------|
|
|
56
|
+
| `promptwheel_git_setup` | Create/checkout branch for ticket | `ticketId`, `baseBranch?` |
|
|
57
|
+
|
|
58
|
+
## Canonical Loop Protocol
|
|
59
|
+
|
|
60
|
+
The core protocol is adapter-agnostic. Any client repeats:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
advance() → get prompt + constraints
|
|
64
|
+
→ execute prompt (any LLM)
|
|
65
|
+
→ ingest_event(type, payload)
|
|
66
|
+
→ repeat until STOP
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Event Types
|
|
70
|
+
|
|
71
|
+
| Event | When | Payload |
|
|
72
|
+
|-------|------|---------|
|
|
73
|
+
| `SCOUT_OUTPUT` | After scouting | `{ proposals: [...] }` |
|
|
74
|
+
| `PLAN_SUBMITTED` | After planning | `{ ticket_id, files_to_touch, estimated_lines, risk_level }` |
|
|
75
|
+
| `TICKET_RESULT` | After execution | `{ status, changed_files, lines_added, lines_removed }` |
|
|
76
|
+
| `QA_COMMAND_RESULT` | Per QA command | `{ command, success, output }` |
|
|
77
|
+
| `QA_PASSED` | All QA passes | `{ summary }` |
|
|
78
|
+
| `QA_FAILED` | QA fails | `{ error }` |
|
|
79
|
+
| `PR_CREATED` | PR created | `{ url, branch }` |
|
|
80
|
+
| `USER_OVERRIDE` | Hint or cancel | `{ hint }` or `{ cancel: true }` |
|
|
81
|
+
|
|
82
|
+
### Phase State Machine
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
SCOUT → NEXT_TICKET → PLAN → EXECUTE → QA → PR → NEXT_TICKET → DONE
|
|
86
|
+
|
|
87
|
+
Terminal states: DONE, BLOCKED_NEEDS_HUMAN, FAILED_BUDGET, FAILED_VALIDATION, FAILED_SPINDLE
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Formulas
|
|
91
|
+
|
|
92
|
+
Built-in formulas customize scout behavior:
|
|
93
|
+
|
|
94
|
+
| Formula | Description | Categories |
|
|
95
|
+
|---------|-------------|------------|
|
|
96
|
+
| `security-audit` | OWASP vulnerabilities | security |
|
|
97
|
+
| `test-coverage` | Missing unit tests | test |
|
|
98
|
+
| `type-safety` | Remove any/unknown | types |
|
|
99
|
+
| `cleanup` | Dead code, unused imports | refactor |
|
|
100
|
+
| `deep` | Architecture review | refactor, perf, security |
|
|
101
|
+
| `docs` | Missing JSDoc | docs |
|
|
102
|
+
|
|
103
|
+
### Custom Formulas
|
|
104
|
+
|
|
105
|
+
Create `.promptwheel/formulas/<name>.yaml`:
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
description: Find and fix error handling issues
|
|
109
|
+
categories: [refactor, security]
|
|
110
|
+
min_confidence: 75 # hint only — does not filter proposals
|
|
111
|
+
risk_tolerance: medium
|
|
112
|
+
prompt: |
|
|
113
|
+
Find functions with missing error handling.
|
|
114
|
+
Look for uncaught promises, empty catch blocks,
|
|
115
|
+
and functions that silently swallow errors.
|
|
116
|
+
tags: [quality]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Run Folder Anatomy
|
|
120
|
+
|
|
121
|
+
Each session creates a run folder at `.promptwheel/runs/<run_id>/`:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
.promptwheel/runs/run_abc123/
|
|
125
|
+
├── state.json # Current RunState (overwritten each step)
|
|
126
|
+
├── events.ndjson # Append-only event log (one JSON per line)
|
|
127
|
+
├── diffs/ # Patch files per step
|
|
128
|
+
│ └── 5-tkt_xyz.patch
|
|
129
|
+
└── artifacts/ # QA logs, scout proposals, etc.
|
|
130
|
+
├── 1-scout-proposals.json
|
|
131
|
+
├── 3-ticket-result.json
|
|
132
|
+
├── 4-qa-npm-test-pass.log
|
|
133
|
+
└── 5-pr-created.json
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Debugging a Failed Run
|
|
137
|
+
|
|
138
|
+
1. **Check phase**: `cat .promptwheel/runs/<id>/state.json | jq .phase`
|
|
139
|
+
2. **Read events**: `cat .promptwheel/runs/<id>/events.ndjson | jq .`
|
|
140
|
+
3. **Find the failure**: `grep FAILED .promptwheel/runs/<id>/events.ndjson`
|
|
141
|
+
4. **Check spindle**: `cat .promptwheel/runs/<id>/state.json | jq .spindle`
|
|
142
|
+
5. **Read QA logs**: `cat .promptwheel/runs/<id>/artifacts/*qa*`
|
|
143
|
+
|
|
144
|
+
### state.json Fields
|
|
145
|
+
|
|
146
|
+
| Field | Description |
|
|
147
|
+
|-------|-------------|
|
|
148
|
+
| `phase` | Current state machine phase |
|
|
149
|
+
| `step_count` / `step_budget` | Progress tracking |
|
|
150
|
+
| `tickets_completed` / `tickets_failed` | Work summary |
|
|
151
|
+
| `spindle` | Loop detection state (output_hashes, diff_hashes, iterations_since_change) |
|
|
152
|
+
| `current_ticket_id` | Active ticket being worked on |
|
|
153
|
+
| `plan_approved` | Whether commit plan was approved |
|
|
154
|
+
| `hints` | Pending hints from nudge |
|
|
155
|
+
|
|
156
|
+
## Architecture
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
Claude Code / Any LLM
|
|
160
|
+
└─ MCP: @promptwheel/mcp (stdio)
|
|
161
|
+
├─ advance() — deterministic state machine
|
|
162
|
+
├─ processEvent() — event-driven transitions
|
|
163
|
+
├─ checkSpindle() — loop detection
|
|
164
|
+
├─ deriveScopePolicy()— scope enforcement
|
|
165
|
+
├─ loadFormula() — formula system
|
|
166
|
+
├─ loadGuidelines() — CLAUDE.md context injection
|
|
167
|
+
└─ SQLite state — tickets, runs, proposals
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Project Guidelines Context
|
|
171
|
+
|
|
172
|
+
The advance engine automatically loads project guidelines and prepends them to scout and execute prompts. This ensures agents follow project conventions without any configuration.
|
|
173
|
+
|
|
174
|
+
- **Claude runs** search for `CLAUDE.md` first, then fall back to `AGENTS.md`
|
|
175
|
+
- **Codex runs** search for `AGENTS.md` first, then fall back to `CLAUDE.md`
|
|
176
|
+
- Loaded fresh on every `advance()` call (MCP sessions are stateless between calls)
|
|
177
|
+
- Wrapped in `<project-guidelines>` XML tags
|
|
178
|
+
- Full file content injected (no truncation)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { RunManager } from './run-manager.js';
|
|
2
|
+
import type { AdaptiveRiskAssessment } from '@promptwheel/core/learnings/shared';
|
|
3
|
+
import { type Trajectory, type TrajectoryState } from '@promptwheel/core/trajectory/shared';
|
|
4
|
+
import type { SectorState } from '@promptwheel/core/sectors/shared';
|
|
5
|
+
export declare const DEFAULT_LEARNINGS_BUDGET = 2000;
|
|
6
|
+
/** Load trajectory state from project root — returns null if missing/invalid. */
|
|
7
|
+
export declare function loadTrajectoryData(rootPath: string): {
|
|
8
|
+
trajectory: Trajectory;
|
|
9
|
+
state: TrajectoryState;
|
|
10
|
+
} | null;
|
|
11
|
+
/** Load sectors.json from project root — returns null if missing/invalid. */
|
|
12
|
+
export declare function loadSectorsState(rootPath: string): SectorState | null;
|
|
13
|
+
/**
|
|
14
|
+
* Build a learnings block for prompt injection. Tracks injected IDs in state.
|
|
15
|
+
* Uses cached learnings from RunState (loaded at session start) to avoid redundant file I/O.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildLearningsBlock(run: RunManager, contextPaths: string[], contextCommands: string[]): string;
|
|
18
|
+
/**
|
|
19
|
+
* Build a risk context block for prompts when adaptive trust detects elevated/high risk.
|
|
20
|
+
* Returns empty string for low/normal risk.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildRiskContextBlock(riskAssessment: AdaptiveRiskAssessment | undefined): string;
|
|
23
|
+
export declare function getScoutAutoApprove(): string[];
|
|
24
|
+
export declare function getExecuteAutoApprove(category: string | null): string[];
|
|
25
|
+
export declare function getQaAutoApprove(): string[];
|
|
26
|
+
export declare function getPrAutoApprove(): string[];
|
|
27
|
+
//# sourceMappingURL=advance-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advance-helpers.d.ts","sourceRoot":"","sources":["../src/advance-helpers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAO9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,EACL,KAAK,UAAU,EACf,KAAK,eAAe,EAIrB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAEpE,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,eAAe,CAAA;CAAE,GAAG,IAAI,CAwB9G;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAarE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,UAAU,EACf,YAAY,EAAE,MAAM,EAAE,EACtB,eAAe,EAAE,MAAM,EAAE,GACxB,MAAM,CA4BR;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,sBAAsB,GAAG,SAAS,GAAG,MAAM,CA6BhG;AAED,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAEvE;AAED,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { getRegistry } from './tool-registry.js';
|
|
4
|
+
import { selectRelevant, formatLearningsForPrompt, recordAccess, } from './learnings.js';
|
|
5
|
+
import { parseTrajectoryYaml, } from '@promptwheel/core/trajectory/shared';
|
|
6
|
+
export const DEFAULT_LEARNINGS_BUDGET = 2000;
|
|
7
|
+
/** Load trajectory state from project root — returns null if missing/invalid. */
|
|
8
|
+
export function loadTrajectoryData(rootPath) {
|
|
9
|
+
try {
|
|
10
|
+
const statePath = path.join(rootPath, '.promptwheel', 'trajectory-state.json');
|
|
11
|
+
if (!fs.existsSync(statePath))
|
|
12
|
+
return null;
|
|
13
|
+
const trajState = JSON.parse(fs.readFileSync(statePath, 'utf8'));
|
|
14
|
+
if (trajState.paused)
|
|
15
|
+
return null;
|
|
16
|
+
const trajDir = path.join(rootPath, '.promptwheel', 'trajectories');
|
|
17
|
+
if (!fs.existsSync(trajDir))
|
|
18
|
+
return null;
|
|
19
|
+
const files = fs.readdirSync(trajDir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));
|
|
20
|
+
for (const file of files) {
|
|
21
|
+
const content = fs.readFileSync(path.join(trajDir, file), 'utf8');
|
|
22
|
+
const traj = parseTrajectoryYaml(content);
|
|
23
|
+
if (traj.name === trajState.trajectoryName && traj.steps.length > 0) {
|
|
24
|
+
return { trajectory: traj, state: trajState };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
if (err instanceof Error && !('code' in err && err.code === 'ENOENT')) {
|
|
30
|
+
console.warn(`[promptwheel] Failed to load trajectory data: ${err.message}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
/** Load sectors.json from project root — returns null if missing/invalid. */
|
|
36
|
+
export function loadSectorsState(rootPath) {
|
|
37
|
+
try {
|
|
38
|
+
const filePath = path.join(rootPath, '.promptwheel', 'sectors.json');
|
|
39
|
+
if (!fs.existsSync(filePath))
|
|
40
|
+
return null;
|
|
41
|
+
const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
42
|
+
if (data?.version !== 2 || !Array.isArray(data.sectors))
|
|
43
|
+
return null;
|
|
44
|
+
return data;
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (err instanceof Error && !('code' in err && err.code === 'ENOENT')) {
|
|
48
|
+
console.warn(`[promptwheel] Failed to load sectors.json: ${err.message}`);
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Build a learnings block for prompt injection. Tracks injected IDs in state.
|
|
55
|
+
* Uses cached learnings from RunState (loaded at session start) to avoid redundant file I/O.
|
|
56
|
+
*/
|
|
57
|
+
export function buildLearningsBlock(run, contextPaths, contextCommands) {
|
|
58
|
+
const s = run.require();
|
|
59
|
+
if (!s.learnings_enabled)
|
|
60
|
+
return '';
|
|
61
|
+
// Lazy-load learnings from disk on first use
|
|
62
|
+
run.ensureLearningsLoaded();
|
|
63
|
+
const projectPath = run.rootPath;
|
|
64
|
+
const allLearnings = s.cached_learnings;
|
|
65
|
+
if (allLearnings.length === 0)
|
|
66
|
+
return '';
|
|
67
|
+
const relevant = selectRelevant(allLearnings, { paths: contextPaths, commands: contextCommands });
|
|
68
|
+
const budget = DEFAULT_LEARNINGS_BUDGET;
|
|
69
|
+
const block = formatLearningsForPrompt(relevant, budget);
|
|
70
|
+
if (!block)
|
|
71
|
+
return '';
|
|
72
|
+
// Track which learnings were injected
|
|
73
|
+
const injectedIds = relevant
|
|
74
|
+
.filter(l => block.includes(l.text))
|
|
75
|
+
.map(l => l.id);
|
|
76
|
+
s.injected_learning_ids = [...new Set([...s.injected_learning_ids, ...injectedIds])];
|
|
77
|
+
// Record access
|
|
78
|
+
if (injectedIds.length > 0) {
|
|
79
|
+
recordAccess(projectPath, injectedIds);
|
|
80
|
+
}
|
|
81
|
+
return block + '\n\n';
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Build a risk context block for prompts when adaptive trust detects elevated/high risk.
|
|
85
|
+
* Returns empty string for low/normal risk.
|
|
86
|
+
*/
|
|
87
|
+
export function buildRiskContextBlock(riskAssessment) {
|
|
88
|
+
if (!riskAssessment)
|
|
89
|
+
return '';
|
|
90
|
+
if (riskAssessment.level === 'low' || riskAssessment.level === 'normal')
|
|
91
|
+
return '';
|
|
92
|
+
const lines = [
|
|
93
|
+
'<risk-context>',
|
|
94
|
+
`## Adaptive Risk: ${riskAssessment.level.toUpperCase()} (score: ${riskAssessment.score})`,
|
|
95
|
+
'',
|
|
96
|
+
];
|
|
97
|
+
if (riskAssessment.fragile_paths.length > 0) {
|
|
98
|
+
lines.push('### Known Fragile Paths');
|
|
99
|
+
for (const fp of riskAssessment.fragile_paths.slice(0, 5)) {
|
|
100
|
+
lines.push(`- \`${fp}\``);
|
|
101
|
+
}
|
|
102
|
+
lines.push('');
|
|
103
|
+
}
|
|
104
|
+
if (riskAssessment.known_issues.length > 0) {
|
|
105
|
+
lines.push('### Known Issues in These Files');
|
|
106
|
+
for (const issue of riskAssessment.known_issues) {
|
|
107
|
+
lines.push(`- ${issue}`);
|
|
108
|
+
}
|
|
109
|
+
lines.push('');
|
|
110
|
+
}
|
|
111
|
+
lines.push('**Be extra careful** — these files have a history of failures. Consider smaller changes and more thorough testing.');
|
|
112
|
+
lines.push('</risk-context>');
|
|
113
|
+
return lines.join('\n') + '\n\n';
|
|
114
|
+
}
|
|
115
|
+
export function getScoutAutoApprove() {
|
|
116
|
+
return getRegistry().getAutoApprovePatterns({ phase: 'SCOUT', category: null });
|
|
117
|
+
}
|
|
118
|
+
export function getExecuteAutoApprove(category) {
|
|
119
|
+
return getRegistry().getAutoApprovePatterns({ phase: 'EXECUTE', category });
|
|
120
|
+
}
|
|
121
|
+
export function getQaAutoApprove() {
|
|
122
|
+
return getRegistry().getAutoApprovePatterns({ phase: 'QA', category: null });
|
|
123
|
+
}
|
|
124
|
+
export function getPrAutoApprove() {
|
|
125
|
+
return getRegistry().getAutoApprovePatterns({ phase: 'PR', category: null });
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=advance-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advance-helpers.js","sourceRoot":"","sources":["../src/advance-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { AdvanceConstraints } from './types.js';
|
|
2
|
+
import type { Formula } from './formulas.js';
|
|
3
|
+
import type { CodebaseIndex } from './codebase-index.js';
|
|
4
|
+
export declare function buildScoutEscalation(retryCount: number, explorationLog: string[], scoutedDirs: string[], codebaseIndex: CodebaseIndex | null): string;
|
|
5
|
+
export declare function buildScoutPrompt(scope: string, categories: string[], minConfidence: number, maxProposals: number, dedupContext: string[], formula: Formula | null, hints: string[], eco: boolean, minImpactScore?: number, scoutedDirs?: string[], excludeDirs?: string[], coverageContext?: {
|
|
6
|
+
scannedSectors: number;
|
|
7
|
+
totalSectors: number;
|
|
8
|
+
percent: number;
|
|
9
|
+
sectorPercent?: number;
|
|
10
|
+
sectorSummary?: string;
|
|
11
|
+
}): string;
|
|
12
|
+
export declare function buildPlanPrompt(ticket: {
|
|
13
|
+
title: string;
|
|
14
|
+
description: string | null;
|
|
15
|
+
allowedPaths: string[];
|
|
16
|
+
verificationCommands: string[];
|
|
17
|
+
category?: string | null;
|
|
18
|
+
}): string;
|
|
19
|
+
export declare function buildExecutePrompt(ticket: {
|
|
20
|
+
title: string;
|
|
21
|
+
description: string | null;
|
|
22
|
+
allowedPaths: string[];
|
|
23
|
+
verificationCommands: string[];
|
|
24
|
+
category?: string | null;
|
|
25
|
+
}, plan: unknown): string;
|
|
26
|
+
export declare function buildQaPrompt(ticket: {
|
|
27
|
+
title: string;
|
|
28
|
+
verificationCommands: string[];
|
|
29
|
+
}): string;
|
|
30
|
+
export declare function buildPlanningPreamble(ticket: {
|
|
31
|
+
metadata?: Record<string, unknown> | null;
|
|
32
|
+
}): string;
|
|
33
|
+
/** Escape a string for use inside double-quoted shell arguments */
|
|
34
|
+
export declare function shellEscape(s: string): string;
|
|
35
|
+
export declare function buildInlineTicketPrompt(ticket: {
|
|
36
|
+
id: string;
|
|
37
|
+
title: string;
|
|
38
|
+
description: string | null;
|
|
39
|
+
allowedPaths: string[];
|
|
40
|
+
verificationCommands: string[];
|
|
41
|
+
metadata?: Record<string, unknown> | null;
|
|
42
|
+
category?: string | null;
|
|
43
|
+
}, constraints: AdvanceConstraints, guidelinesBlock: string, metadataBlock: string, createPrs: boolean, draft: boolean, direct: boolean, setupCommand?: string, baselineFailures?: string[]): string;
|
|
44
|
+
export declare function buildPrPrompt(ticket: {
|
|
45
|
+
title: string;
|
|
46
|
+
description: string | null;
|
|
47
|
+
} | null, draftPr: boolean): string;
|
|
48
|
+
//# sourceMappingURL=advance-prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advance-prompts.d.ts","sourceRoot":"","sources":["../src/advance-prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EAAE,EACxB,WAAW,EAAE,MAAM,EAAE,EACrB,aAAa,EAAE,aAAa,GAAG,IAAI,GAClC,MAAM,CAqCR;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAAE,EACpB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,OAAO,GAAG,IAAI,EACvB,KAAK,EAAE,MAAM,EAAE,EACf,GAAG,EAAE,OAAO,EACZ,cAAc,GAAE,MAAU,EAC1B,WAAW,GAAE,MAAM,EAAO,EAC1B,WAAW,GAAE,MAAM,EAAO,EAC1B,eAAe,CAAC,EAAE;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAClI,MAAM,CA+IR;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAAC,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,CA6B/K;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAAC,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EACvI,IAAI,EAAE,OAAO,GACZ,MAAM,CAqCR;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,MAAM,CAa/F;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,CAiBnG;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAAC,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAC9L,WAAW,EAAE,kBAAkB,EAC/B,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,OAAO,EAClB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,gBAAgB,GAAE,MAAM,EAAO,GAC9B,MAAM,CA+KR;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,EAC5D,OAAO,EAAE,OAAO,GACf,MAAM,CAoBR"}
|