theroundtaible 0.2.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 +191 -0
- package/dist/adapters/base.d.ts +18 -0
- package/dist/adapters/base.d.ts.map +1 -0
- package/dist/adapters/base.js +67 -0
- package/dist/adapters/base.js.map +1 -0
- package/dist/adapters/claude-cli.d.ts +10 -0
- package/dist/adapters/claude-cli.d.ts.map +1 -0
- package/dist/adapters/claude-cli.js +42 -0
- package/dist/adapters/claude-cli.js.map +1 -0
- package/dist/adapters/gemini-cli.d.ts +10 -0
- package/dist/adapters/gemini-cli.d.ts.map +1 -0
- package/dist/adapters/gemini-cli.js +37 -0
- package/dist/adapters/gemini-cli.js.map +1 -0
- package/dist/adapters/openai-api.d.ts +11 -0
- package/dist/adapters/openai-api.d.ts.map +1 -0
- package/dist/adapters/openai-api.js +53 -0
- package/dist/adapters/openai-api.js.map +1 -0
- package/dist/adapters/openai-cli.d.ts +10 -0
- package/dist/adapters/openai-cli.d.ts.map +1 -0
- package/dist/adapters/openai-cli.js +37 -0
- package/dist/adapters/openai-cli.js.map +1 -0
- package/dist/commands/apply.d.ts +11 -0
- package/dist/commands/apply.d.ts.map +1 -0
- package/dist/commands/apply.js +193 -0
- package/dist/commands/apply.js.map +1 -0
- package/dist/commands/chronicle.d.ts +6 -0
- package/dist/commands/chronicle.d.ts.map +1 -0
- package/dist/commands/chronicle.js +60 -0
- package/dist/commands/chronicle.js.map +1 -0
- package/dist/commands/code-red.d.ts +5 -0
- package/dist/commands/code-red.d.ts.map +1 -0
- package/dist/commands/code-red.js +162 -0
- package/dist/commands/code-red.js.map +1 -0
- package/dist/commands/discuss.d.ts +5 -0
- package/dist/commands/discuss.d.ts.map +1 -0
- package/dist/commands/discuss.js +173 -0
- package/dist/commands/discuss.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +188 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +6 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +53 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +69 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/summon.d.ts +6 -0
- package/dist/commands/summon.d.ts.map +1 -0
- package/dist/commands/summon.js +52 -0
- package/dist/commands/summon.js.map +1 -0
- package/dist/consensus.d.ts +36 -0
- package/dist/consensus.d.ts.map +1 -0
- package/dist/consensus.js +183 -0
- package/dist/consensus.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator.d.ts +32 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +608 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/types.d.ts +111 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/adapters.d.ts +12 -0
- package/dist/utils/adapters.d.ts.map +1 -0
- package/dist/utils/adapters.js +66 -0
- package/dist/utils/adapters.js.map +1 -0
- package/dist/utils/chronicle.d.ts +14 -0
- package/dist/utils/chronicle.d.ts.map +1 -0
- package/dist/utils/chronicle.js +44 -0
- package/dist/utils/chronicle.js.map +1 -0
- package/dist/utils/config.d.ts +13 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +69 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/context.d.ts +19 -0
- package/dist/utils/context.d.ts.map +1 -0
- package/dist/utils/context.js +81 -0
- package/dist/utils/context.js.map +1 -0
- package/dist/utils/decree.d.ts +31 -0
- package/dist/utils/decree.d.ts.map +1 -0
- package/dist/utils/decree.js +84 -0
- package/dist/utils/decree.js.map +1 -0
- package/dist/utils/error-log.d.ts +18 -0
- package/dist/utils/error-log.d.ts.map +1 -0
- package/dist/utils/error-log.js +125 -0
- package/dist/utils/error-log.js.map +1 -0
- package/dist/utils/file-writer.d.ts +22 -0
- package/dist/utils/file-writer.d.ts.map +1 -0
- package/dist/utils/file-writer.js +122 -0
- package/dist/utils/file-writer.js.map +1 -0
- package/dist/utils/git.d.ts +13 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +40 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +5 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/prompt.d.ts +18 -0
- package/dist/utils/prompt.d.ts.map +1 -0
- package/dist/utils/prompt.js +181 -0
- package/dist/utils/prompt.js.map +1 -0
- package/dist/utils/session.d.ts +37 -0
- package/dist/utils/session.d.ts.map +1 -0
- package/dist/utils/session.js +160 -0
- package/dist/utils/session.js.map +1 -0
- package/package.json +54 -0
- package/templates/code-red-prompt.md +54 -0
- package/templates/system-prompt.md +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# TheRoundtAIble
|
|
2
|
+
|
|
3
|
+
> **"Where no AI is King, but all serve the Code."**
|
|
4
|
+
|
|
5
|
+
A CLI tool that lets multiple AI models (Claude, Gemini, GPT) automatically discuss software problems and reach consensus — so you don't have to be the messenger between them.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
1. You ask a question
|
|
10
|
+
2. TheRoundtAIble sends it to your configured AI "knights"
|
|
11
|
+
3. Each knight responds with their proposal and scores agreement (0-10)
|
|
12
|
+
4. Rounds continue until **consensus** is reached or max rounds hit
|
|
13
|
+
5. You choose: let the Lead Knight execute, do it yourself, or decide later
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
You: roundtable discuss "How should we refactor the auth module?"
|
|
17
|
+
|
|
18
|
+
ROUND 1 — KNIGHTS! DRAW YOUR KEYBOARDS!
|
|
19
|
+
|
|
20
|
+
Claude (7/10) → proposes JWT with NextAuth wrapper
|
|
21
|
+
Gemini (8/10) → agrees, suggests refresh token strategy
|
|
22
|
+
GPT (6/10) → "Can we just ship it?"
|
|
23
|
+
|
|
24
|
+
ROUND 2 — FOR KING AND KONG!
|
|
25
|
+
|
|
26
|
+
Claude (9/10) → accepts refresh strategy
|
|
27
|
+
Gemini (10/10) → fully agrees
|
|
28
|
+
GPT (9/10) → "Fine, let's do it properly"
|
|
29
|
+
|
|
30
|
+
Against all odds... they actually agree.
|
|
31
|
+
|
|
32
|
+
What is your decree, Your Majesty?
|
|
33
|
+
1. Let the knights forge it — they write the code
|
|
34
|
+
2. I'll wield the sword myself — just show me the plan
|
|
35
|
+
3. Adjourn the court — decide later
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Key principle
|
|
39
|
+
|
|
40
|
+
**No API keys required by default.** Works with your existing AI subscriptions (Claude Pro/Max, Gemini Advanced, ChatGPT Plus). API keys are an optional fallback.
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install -g theroundtaible
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Or use without installing:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx theroundtaible init
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Prerequisites
|
|
55
|
+
|
|
56
|
+
- Node.js 20+
|
|
57
|
+
- At least one AI CLI tool installed:
|
|
58
|
+
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) — `claude` command
|
|
59
|
+
- [Gemini CLI](https://github.com/google-gemini/gemini-cli) — `gemini` command
|
|
60
|
+
- [Codex CLI](https://github.com/openai/codex) — `codex` command
|
|
61
|
+
- Or an OpenAI API key (`OPENAI_API_KEY` env var) as fallback
|
|
62
|
+
|
|
63
|
+
## Quick start
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Initialize in your project
|
|
67
|
+
cd your-project
|
|
68
|
+
roundtable init
|
|
69
|
+
|
|
70
|
+
# Start a discussion
|
|
71
|
+
roundtable discuss "How should we structure the database schema?"
|
|
72
|
+
|
|
73
|
+
# Review based on current git changes
|
|
74
|
+
roundtable summon
|
|
75
|
+
|
|
76
|
+
# Apply the consensus decision
|
|
77
|
+
roundtable apply
|
|
78
|
+
|
|
79
|
+
# Emergency bug diagnosis
|
|
80
|
+
roundtable code-red "login page crashes on submit"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Commands
|
|
84
|
+
|
|
85
|
+
| Command | Description |
|
|
86
|
+
|---------|-------------|
|
|
87
|
+
| `roundtable init` | Interactive setup wizard — detects your AI tools |
|
|
88
|
+
| `roundtable discuss "topic"` | Start a multi-AI discussion |
|
|
89
|
+
| `roundtable summon` | Start a discussion based on your `git diff` |
|
|
90
|
+
| `roundtable apply` | Execute the consensus decision (Lead Knight writes code) |
|
|
91
|
+
| `roundtable apply --noparley` | Execute without file-by-file review (dangerous) |
|
|
92
|
+
| `roundtable code-red "symptoms"` | Emergency diagnostic mode — knights become doctors |
|
|
93
|
+
| `roundtable status` | Show current session status |
|
|
94
|
+
| `roundtable list` | List all discussion sessions |
|
|
95
|
+
| `roundtable chronicle` | View the decision log |
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
|
|
99
|
+
After `roundtable init`, your `.roundtable/config.json` controls everything:
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"knights": [
|
|
104
|
+
{
|
|
105
|
+
"name": "Claude",
|
|
106
|
+
"adapter": "claude-cli",
|
|
107
|
+
"capabilities": ["architecture", "debugging", "testing"],
|
|
108
|
+
"priority": 1,
|
|
109
|
+
"fallback": "claude-api"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"name": "Gemini",
|
|
113
|
+
"adapter": "gemini-cli",
|
|
114
|
+
"capabilities": ["docs", "ui-ux", "planning"],
|
|
115
|
+
"priority": 2
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
"rules": {
|
|
119
|
+
"max_rounds": 5,
|
|
120
|
+
"consensus_threshold": 9,
|
|
121
|
+
"timeout_per_turn_seconds": 120
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Consensus threshold:** All knights must score >= this value AND have no pending issues.
|
|
127
|
+
|
|
128
|
+
## Adapters
|
|
129
|
+
|
|
130
|
+
| Adapter | Method | Subscription? | Fallback |
|
|
131
|
+
|---------|--------|---------------|----------|
|
|
132
|
+
| `claude-cli` | `claude -p "prompt" --print` | Claude Pro/Max | `claude-api` |
|
|
133
|
+
| `gemini-cli` | `gemini -p "prompt"` | Gemini Advanced | `gemini-api` |
|
|
134
|
+
| `openai-cli` | `codex "prompt"` | ChatGPT Pro | `openai-api` |
|
|
135
|
+
| `openai-api` | OpenAI REST API | No (API key) | — |
|
|
136
|
+
|
|
137
|
+
## Code-Red mode
|
|
138
|
+
|
|
139
|
+
When a bug won't die, call in the doctors:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
roundtable code-red "the API returns 500 on user creation"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The knights switch to diagnostic mode:
|
|
146
|
+
- **Triage round:** Initial assessment of symptoms
|
|
147
|
+
- **Blind round:** Each doctor diagnoses independently (prevents groupthink)
|
|
148
|
+
- **Convergence rounds:** Doctors compare findings and converge on root cause
|
|
149
|
+
- **File requests:** Doctors can request specific source files as evidence
|
|
150
|
+
|
|
151
|
+
When they agree on a diagnosis, you choose: **Fix now**, **Report only**, or **Log for later**.
|
|
152
|
+
|
|
153
|
+
All diagnoses are tracked in `.roundtable/error-log.md` with CR-XXX IDs.
|
|
154
|
+
|
|
155
|
+
## Project structure
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
your-project/
|
|
159
|
+
.roundtable/
|
|
160
|
+
config.json # Which knights, rules, capabilities
|
|
161
|
+
chronicle.md # Decision log (persistent memory)
|
|
162
|
+
error-log.md # Code-red diagnostic log
|
|
163
|
+
sessions/
|
|
164
|
+
2026-02-16-auth-refactor/
|
|
165
|
+
topic.md # The question
|
|
166
|
+
discussion.md # Full discussion (all rounds)
|
|
167
|
+
decisions.md # The consensus decision
|
|
168
|
+
status.json # Current phase and progress
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Architecture
|
|
172
|
+
|
|
173
|
+
See [architecture-docs.md](architecture-docs.md) for the full technical architecture, project structure, and contribution guide.
|
|
174
|
+
|
|
175
|
+
## Roadmap
|
|
176
|
+
|
|
177
|
+
- [x] Multi-AI discussions with consensus
|
|
178
|
+
- [x] Claude, Gemini, and OpenAI adapters
|
|
179
|
+
- [x] Knight personalities (they roast each other)
|
|
180
|
+
- [x] Apply decisions with Parley/No Parley modes
|
|
181
|
+
- [x] Code-Red emergency diagnostic mode
|
|
182
|
+
- [x] Git-diff based discussions (`summon`)
|
|
183
|
+
- [x] Chronicle (persistent decision memory)
|
|
184
|
+
- [ ] VS Code extension
|
|
185
|
+
- [ ] Web dashboard for session visualization
|
|
186
|
+
- [ ] More adapters (DeepSeek, Llama, Mistral)
|
|
187
|
+
- [ ] CI/CD integration (GitHub Actions)
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT — Tarik Polat ([polatinos](https://github.com/polatinos))
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ConsensusBlock } from "../types.js";
|
|
2
|
+
export type AdapterErrorKind = "not_installed" | "timeout" | "auth" | "api" | "unknown";
|
|
3
|
+
export declare class AdapterError extends Error {
|
|
4
|
+
readonly kind: AdapterErrorKind;
|
|
5
|
+
readonly adapterName: string;
|
|
6
|
+
constructor(message: string, kind: AdapterErrorKind, adapterName: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Classify an error thrown during adapter execution into a known kind.
|
|
10
|
+
*/
|
|
11
|
+
export declare function classifyError(error: unknown, adapterName: string): AdapterError;
|
|
12
|
+
export declare abstract class BaseAdapter {
|
|
13
|
+
abstract readonly name: string;
|
|
14
|
+
abstract execute(prompt: string, timeoutMs?: number): Promise<string>;
|
|
15
|
+
abstract isAvailable(): Promise<boolean>;
|
|
16
|
+
parseConsensus(response: string, round: number): ConsensusBlock | null;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAExF,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM;CAMzE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,YAAY,CAkB/E;AAED,8BAAsB,WAAW;IAC/B,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAE/B,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAErE,QAAQ,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAExC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;CAmCvE"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export class AdapterError extends Error {
|
|
2
|
+
kind;
|
|
3
|
+
adapterName;
|
|
4
|
+
constructor(message, kind, adapterName) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "AdapterError";
|
|
7
|
+
this.kind = kind;
|
|
8
|
+
this.adapterName = adapterName;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Classify an error thrown during adapter execution into a known kind.
|
|
13
|
+
*/
|
|
14
|
+
export function classifyError(error, adapterName) {
|
|
15
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
16
|
+
const lower = msg.toLowerCase();
|
|
17
|
+
if (lower.includes("enoent") || lower.includes("not found") || lower.includes("not recognized")) {
|
|
18
|
+
return new AdapterError(msg, "not_installed", adapterName);
|
|
19
|
+
}
|
|
20
|
+
if (lower.includes("timeout") || lower.includes("timed out") || lower.includes("etimedout")) {
|
|
21
|
+
return new AdapterError(msg, "timeout", adapterName);
|
|
22
|
+
}
|
|
23
|
+
if (lower.includes("401") || lower.includes("403") || lower.includes("unauthorized") || lower.includes("api key")) {
|
|
24
|
+
return new AdapterError(msg, "auth", adapterName);
|
|
25
|
+
}
|
|
26
|
+
if (lower.includes("api error") || lower.includes("429") || lower.includes("500") || lower.includes("502") || lower.includes("503")) {
|
|
27
|
+
return new AdapterError(msg, "api", adapterName);
|
|
28
|
+
}
|
|
29
|
+
return new AdapterError(msg, "unknown", adapterName);
|
|
30
|
+
}
|
|
31
|
+
export class BaseAdapter {
|
|
32
|
+
parseConsensus(response, round) {
|
|
33
|
+
// Try to extract JSON block from the response
|
|
34
|
+
// Knights are instructed to end with a JSON block containing consensus_score
|
|
35
|
+
const jsonPatterns = [
|
|
36
|
+
// Fenced code block with json
|
|
37
|
+
/```json\s*\n?([\s\S]*?)\n?\s*```/,
|
|
38
|
+
// Fenced code block without language
|
|
39
|
+
/```\s*\n?([\s\S]*?)\n?\s*```/,
|
|
40
|
+
// Raw JSON object containing consensus_score
|
|
41
|
+
/(\{[^{}]*"consensus_score"\s*:[^{}]*\})/,
|
|
42
|
+
];
|
|
43
|
+
for (const pattern of jsonPatterns) {
|
|
44
|
+
const match = response.match(pattern);
|
|
45
|
+
if (!match?.[1])
|
|
46
|
+
continue;
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(match[1].trim());
|
|
49
|
+
if (typeof parsed.consensus_score === "number") {
|
|
50
|
+
return {
|
|
51
|
+
knight: parsed.knight || this.name,
|
|
52
|
+
round: parsed.round || round,
|
|
53
|
+
consensus_score: parsed.consensus_score,
|
|
54
|
+
agrees_with: Array.isArray(parsed.agrees_with) ? parsed.agrees_with : [],
|
|
55
|
+
pending_issues: Array.isArray(parsed.pending_issues) ? parsed.pending_issues : [],
|
|
56
|
+
proposal: parsed.proposal,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Try next pattern
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseAdapter } from "./base.js";
|
|
2
|
+
export declare class ClaudeCliAdapter extends BaseAdapter {
|
|
3
|
+
readonly name = "Claude";
|
|
4
|
+
private command;
|
|
5
|
+
private defaultTimeout;
|
|
6
|
+
constructor(command?: string, timeoutMs?: number);
|
|
7
|
+
isAvailable(): Promise<boolean>;
|
|
8
|
+
execute(prompt: string, timeoutMs?: number): Promise<string>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=claude-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-cli.d.ts","sourceRoot":"","sources":["../../src/adapters/claude-cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,QAAQ,CAAC,IAAI,YAAY;IAEzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,GAAE,MAAiB,EAAE,SAAS,GAAE,MAAgB;IAM7D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAwBnE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
import { BaseAdapter } from "./base.js";
|
|
3
|
+
export class ClaudeCliAdapter extends BaseAdapter {
|
|
4
|
+
name = "Claude";
|
|
5
|
+
command;
|
|
6
|
+
defaultTimeout;
|
|
7
|
+
constructor(command = "claude", timeoutMs = 120_000) {
|
|
8
|
+
super();
|
|
9
|
+
this.command = command;
|
|
10
|
+
this.defaultTimeout = timeoutMs;
|
|
11
|
+
}
|
|
12
|
+
async isAvailable() {
|
|
13
|
+
try {
|
|
14
|
+
const result = await execa("where", [this.command], { reject: false });
|
|
15
|
+
return result.exitCode === 0;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async execute(prompt, timeoutMs) {
|
|
22
|
+
const timeout = timeoutMs ?? this.defaultTimeout;
|
|
23
|
+
// Claude reads from stdin when no -p flag is given.
|
|
24
|
+
// Use --print for non-interactive output.
|
|
25
|
+
// Remove CLAUDECODE env var entirely to allow invocation from within VS Code
|
|
26
|
+
// terminal where Claude Code is running. Empty string is not enough.
|
|
27
|
+
const env = { ...process.env };
|
|
28
|
+
delete env.CLAUDECODE;
|
|
29
|
+
const result = await execa(this.command, ["--print"], {
|
|
30
|
+
input: prompt,
|
|
31
|
+
timeout,
|
|
32
|
+
reject: false,
|
|
33
|
+
env,
|
|
34
|
+
});
|
|
35
|
+
if (result.exitCode !== 0) {
|
|
36
|
+
const errorMsg = result.stderr || result.stdout || "Unknown error";
|
|
37
|
+
throw new Error(`Claude CLI failed (exit ${result.exitCode}): ${errorMsg}`);
|
|
38
|
+
}
|
|
39
|
+
return result.stdout;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=claude-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-cli.js","sourceRoot":"","sources":["../../src/adapters/claude-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,OAAO,gBAAiB,SAAQ,WAAW;IACtC,IAAI,GAAG,QAAQ,CAAC;IAEjB,OAAO,CAAS;IAChB,cAAc,CAAS;IAE/B,YAAY,UAAkB,QAAQ,EAAE,YAAoB,OAAO;QACjE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YACvE,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,SAAkB;QAC9C,MAAM,OAAO,GAAG,SAAS,IAAI,IAAI,CAAC,cAAc,CAAC;QAEjD,oDAAoD;QACpD,0CAA0C;QAC1C,6EAA6E;QAC7E,qEAAqE;QACrE,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC/B,OAAO,GAAG,CAAC,UAAU,CAAC;QAEtB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,EAAE;YACpD,KAAK,EAAE,MAAM;YACb,OAAO;YACP,MAAM,EAAE,KAAK;YACb,GAAG;SACJ,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAC,QAAQ,MAAM,QAAQ,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseAdapter } from "./base.js";
|
|
2
|
+
export declare class GeminiCliAdapter extends BaseAdapter {
|
|
3
|
+
readonly name = "Gemini";
|
|
4
|
+
private command;
|
|
5
|
+
private defaultTimeout;
|
|
6
|
+
constructor(command?: string, timeoutMs?: number);
|
|
7
|
+
isAvailable(): Promise<boolean>;
|
|
8
|
+
execute(prompt: string, timeoutMs?: number): Promise<string>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=gemini-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-cli.d.ts","sourceRoot":"","sources":["../../src/adapters/gemini-cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,QAAQ,CAAC,IAAI,YAAY;IAEzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,GAAE,MAAiB,EAAE,SAAS,GAAE,MAAgB;IAM7D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAkBnE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
import { BaseAdapter } from "./base.js";
|
|
3
|
+
export class GeminiCliAdapter extends BaseAdapter {
|
|
4
|
+
name = "Gemini";
|
|
5
|
+
command;
|
|
6
|
+
defaultTimeout;
|
|
7
|
+
constructor(command = "gemini", timeoutMs = 120_000) {
|
|
8
|
+
super();
|
|
9
|
+
this.command = command;
|
|
10
|
+
this.defaultTimeout = timeoutMs;
|
|
11
|
+
}
|
|
12
|
+
async isAvailable() {
|
|
13
|
+
try {
|
|
14
|
+
await execa(this.command, ["--version"]);
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async execute(prompt, timeoutMs) {
|
|
22
|
+
const timeout = timeoutMs ?? this.defaultTimeout;
|
|
23
|
+
// Gemini docs: "-p/--prompt appended to input on stdin (if any)"
|
|
24
|
+
// Pass prompt via stdin to avoid command line length limits
|
|
25
|
+
const result = await execa(this.command, ["-p", ""], {
|
|
26
|
+
input: prompt,
|
|
27
|
+
timeout,
|
|
28
|
+
reject: false,
|
|
29
|
+
});
|
|
30
|
+
if (result.exitCode !== 0) {
|
|
31
|
+
const errorMsg = result.stderr || result.stdout || "Unknown error";
|
|
32
|
+
throw new Error(`Gemini CLI failed (exit ${result.exitCode}): ${errorMsg}`);
|
|
33
|
+
}
|
|
34
|
+
return result.stdout;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=gemini-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-cli.js","sourceRoot":"","sources":["../../src/adapters/gemini-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,OAAO,gBAAiB,SAAQ,WAAW;IACtC,IAAI,GAAG,QAAQ,CAAC;IAEjB,OAAO,CAAS;IAChB,cAAc,CAAS;IAE/B,YAAY,UAAkB,QAAQ,EAAE,YAAoB,OAAO;QACjE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,SAAkB;QAC9C,MAAM,OAAO,GAAG,SAAS,IAAI,IAAI,CAAC,cAAc,CAAC;QAEjD,iEAAiE;QACjE,4DAA4D;QAC5D,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE;YACnD,KAAK,EAAE,MAAM;YACb,OAAO;YACP,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAC,QAAQ,MAAM,QAAQ,EAAE,CAAC,CAAC;QAC9E,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseAdapter } from "./base.js";
|
|
2
|
+
export declare class OpenAIApiAdapter extends BaseAdapter {
|
|
3
|
+
readonly name = "GPT";
|
|
4
|
+
private model;
|
|
5
|
+
private apiKey;
|
|
6
|
+
private defaultTimeout;
|
|
7
|
+
constructor(model?: string, envKey?: string, timeoutMs?: number);
|
|
8
|
+
isAvailable(): Promise<boolean>;
|
|
9
|
+
execute(prompt: string, timeoutMs?: number): Promise<string>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=openai-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-api.d.ts","sourceRoot":"","sources":["../../src/adapters/openai-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,QAAQ,CAAC,IAAI,SAAS;IAEtB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,cAAc,CAAS;gBAEnB,KAAK,GAAE,MAAiB,EAAE,MAAM,GAAE,MAAyB,EAAE,SAAS,GAAE,MAAgB;IAO9F,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA2CnE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { BaseAdapter } from "./base.js";
|
|
2
|
+
export class OpenAIApiAdapter extends BaseAdapter {
|
|
3
|
+
name = "GPT";
|
|
4
|
+
model;
|
|
5
|
+
apiKey;
|
|
6
|
+
defaultTimeout;
|
|
7
|
+
constructor(model = "gpt-4o", envKey = "OPENAI_API_KEY", timeoutMs = 120_000) {
|
|
8
|
+
super();
|
|
9
|
+
this.model = model;
|
|
10
|
+
this.apiKey = process.env[envKey];
|
|
11
|
+
this.defaultTimeout = timeoutMs;
|
|
12
|
+
}
|
|
13
|
+
async isAvailable() {
|
|
14
|
+
return typeof this.apiKey === "string" && this.apiKey.length > 0;
|
|
15
|
+
}
|
|
16
|
+
async execute(prompt, timeoutMs) {
|
|
17
|
+
if (!this.apiKey) {
|
|
18
|
+
throw new Error("OpenAI API key not set. Set the OPENAI_API_KEY environment variable.");
|
|
19
|
+
}
|
|
20
|
+
const timeout = timeoutMs ?? this.defaultTimeout;
|
|
21
|
+
const controller = new AbortController();
|
|
22
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
23
|
+
try {
|
|
24
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: {
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
29
|
+
},
|
|
30
|
+
body: JSON.stringify({
|
|
31
|
+
model: this.model,
|
|
32
|
+
messages: [{ role: "user", content: prompt }],
|
|
33
|
+
max_tokens: 2048,
|
|
34
|
+
}),
|
|
35
|
+
signal: controller.signal,
|
|
36
|
+
});
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
const errorBody = await response.text();
|
|
39
|
+
throw new Error(`OpenAI API error (${response.status}): ${errorBody}`);
|
|
40
|
+
}
|
|
41
|
+
const data = (await response.json());
|
|
42
|
+
const content = data.choices?.[0]?.message?.content;
|
|
43
|
+
if (!content) {
|
|
44
|
+
throw new Error("OpenAI API returned empty response");
|
|
45
|
+
}
|
|
46
|
+
return content;
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
clearTimeout(timer);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=openai-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-api.js","sourceRoot":"","sources":["../../src/adapters/openai-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,OAAO,gBAAiB,SAAQ,WAAW;IACtC,IAAI,GAAG,KAAK,CAAC;IAEd,KAAK,CAAS;IACd,MAAM,CAAqB;IAC3B,cAAc,CAAS;IAE/B,YAAY,QAAgB,QAAQ,EAAE,SAAiB,gBAAgB,EAAE,YAAoB,OAAO;QAClG,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,SAAkB;QAC9C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;QAC1F,CAAC;QAED,MAAM,OAAO,GAAG,SAAS,IAAI,IAAI,CAAC,cAAc,CAAC;QACjD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAE5D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,4CAA4C,EAAE;gBACzE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;iBACvC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;oBAC7C,UAAU,EAAE,IAAI;iBACjB,CAAC;gBACF,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACxC,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,CAAC,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;YACzE,CAAC;YAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAElC,CAAC;YAEF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;YACpD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;YACxD,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BaseAdapter } from "./base.js";
|
|
2
|
+
export declare class OpenAICliAdapter extends BaseAdapter {
|
|
3
|
+
readonly name = "GPT";
|
|
4
|
+
private command;
|
|
5
|
+
private defaultTimeout;
|
|
6
|
+
constructor(command?: string, timeoutMs?: number);
|
|
7
|
+
isAvailable(): Promise<boolean>;
|
|
8
|
+
execute(prompt: string, timeoutMs?: number): Promise<string>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=openai-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-cli.d.ts","sourceRoot":"","sources":["../../src/adapters/openai-cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,QAAQ,CAAC,IAAI,SAAS;IAEtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,GAAE,MAAgB,EAAE,SAAS,GAAE,MAAgB;IAM5D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAsBnE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
import { BaseAdapter } from "./base.js";
|
|
3
|
+
export class OpenAICliAdapter extends BaseAdapter {
|
|
4
|
+
name = "GPT";
|
|
5
|
+
command;
|
|
6
|
+
defaultTimeout;
|
|
7
|
+
constructor(command = "codex", timeoutMs = 120_000) {
|
|
8
|
+
super();
|
|
9
|
+
this.command = command;
|
|
10
|
+
this.defaultTimeout = timeoutMs;
|
|
11
|
+
}
|
|
12
|
+
async isAvailable() {
|
|
13
|
+
try {
|
|
14
|
+
await execa(this.command, ["--version"]);
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async execute(prompt, timeoutMs) {
|
|
22
|
+
const timeout = timeoutMs ?? this.defaultTimeout;
|
|
23
|
+
// Codex docs: "If not provided as an argument (or if `-` is used),
|
|
24
|
+
// instructions are read from stdin"
|
|
25
|
+
const result = await execa(this.command, ["exec", "-", "--sandbox", "read-only", "-o", "-"], {
|
|
26
|
+
input: prompt,
|
|
27
|
+
timeout,
|
|
28
|
+
reject: false,
|
|
29
|
+
});
|
|
30
|
+
if (result.exitCode !== 0) {
|
|
31
|
+
const errorMsg = result.stderr || result.stdout || "Unknown error";
|
|
32
|
+
throw new Error(`Codex CLI failed (exit ${result.exitCode}): ${errorMsg}`);
|
|
33
|
+
}
|
|
34
|
+
return result.stdout;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=openai-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-cli.js","sourceRoot":"","sources":["../../src/adapters/openai-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,OAAO,gBAAiB,SAAQ,WAAW;IACtC,IAAI,GAAG,KAAK,CAAC;IAEd,OAAO,CAAS;IAChB,cAAc,CAAS;IAE/B,YAAY,UAAkB,OAAO,EAAE,YAAoB,OAAO;QAChE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc,EAAE,SAAkB;QAC9C,MAAM,OAAO,GAAG,SAAS,IAAI,IAAI,CAAC,cAAc,CAAC;QAEjD,mEAAmE;QACnE,oCAAoC;QACpC,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB,IAAI,CAAC,OAAO,EACZ,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC,EAClD;YACE,KAAK,EAAE,MAAM;YACb,OAAO;YACP,MAAM,EAAE,KAAK;SACd,CACF,CAAC;QAEF,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,eAAe,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,CAAC,QAAQ,MAAM,QAAQ,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `roundtable apply` command.
|
|
3
|
+
* Reads the latest session's decision and executes it via the Lead Knight.
|
|
4
|
+
* Now actually writes files to disk instead of just printing text.
|
|
5
|
+
*
|
|
6
|
+
* Modes:
|
|
7
|
+
* --parley (default) — shows each file, asks for confirmation
|
|
8
|
+
* --noparley — writes everything directly ("dangerous mode")
|
|
9
|
+
*/
|
|
10
|
+
export declare function applyCommand(initialNoparley?: boolean): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=apply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/commands/apply.ts"],"names":[],"mappings":"AAiBA;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,eAAe,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA4MzE"}
|