@sylphx/flow 1.0.0 → 1.0.1
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/CHANGELOG.md +133 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +59554 -0
- package/dist/lancedb.linux-x64-gnu-b7f0jgsz.node +0 -0
- package/dist/lancedb.linux-x64-musl-tgcv22rx.node +0 -0
- package/dist/shared/chunk-25dwp0dp.js +89 -0
- package/dist/shared/chunk-3pjb6063.js +208 -0
- package/dist/shared/chunk-4d6ydpw7.js +2854 -0
- package/dist/shared/chunk-4wjcadjk.js +225 -0
- package/dist/shared/chunk-5j4w74t6.js +30 -0
- package/dist/shared/chunk-5j8m3dh3.js +58 -0
- package/dist/shared/chunk-5thh3qem.js +91 -0
- package/dist/shared/chunk-6g9xy73m.js +252 -0
- package/dist/shared/chunk-7eq34c42.js +23 -0
- package/dist/shared/chunk-c2gwgx3r.js +115 -0
- package/dist/shared/chunk-cjd3mk4c.js +1320 -0
- package/dist/shared/chunk-g5cv6703.js +368 -0
- package/dist/shared/chunk-hpkhykhq.js +574 -0
- package/dist/shared/chunk-m2322pdk.js +122 -0
- package/dist/shared/chunk-nd5fdvaq.js +26 -0
- package/dist/shared/chunk-pgd3m6zf.js +108 -0
- package/dist/shared/chunk-qk8n91hw.js +494 -0
- package/dist/shared/chunk-rkkn8szp.js +16855 -0
- package/dist/shared/chunk-t16rfxh0.js +61 -0
- package/dist/shared/chunk-t4fbfa5v.js +19 -0
- package/dist/shared/chunk-t77h86w6.js +276 -0
- package/dist/shared/chunk-v0ez4aef.js +71 -0
- package/dist/shared/chunk-v29j2r3s.js +32051 -0
- package/dist/shared/chunk-vfbc6ew5.js +765 -0
- package/dist/shared/chunk-vmeqwm1c.js +204 -0
- package/dist/shared/chunk-x66eh37x.js +137 -0
- package/package.json +3 -2
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/core/functional/result.ts
|
|
2
|
+
var success = (value) => ({
|
|
3
|
+
_tag: "Success",
|
|
4
|
+
value
|
|
5
|
+
});
|
|
6
|
+
var failure = (error) => ({
|
|
7
|
+
_tag: "Failure",
|
|
8
|
+
error
|
|
9
|
+
});
|
|
10
|
+
var tryCatch = (fn, onError = (error) => error) => {
|
|
11
|
+
try {
|
|
12
|
+
return success(fn());
|
|
13
|
+
} catch (error) {
|
|
14
|
+
return failure(onError(error));
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var tryCatchAsync = async (fn, onError = (error) => error) => {
|
|
18
|
+
try {
|
|
19
|
+
const value = await fn();
|
|
20
|
+
return success(value);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
return failure(onError(error));
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { success, failure, tryCatch, tryCatchAsync };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {
|
|
2
|
+
configError
|
|
3
|
+
} from "./chunk-t4fbfa5v.js";
|
|
4
|
+
import {
|
|
5
|
+
failure,
|
|
6
|
+
success,
|
|
7
|
+
tryCatch
|
|
8
|
+
} from "./chunk-nd5fdvaq.js";
|
|
9
|
+
import"./chunk-5j4w74t6.js";
|
|
10
|
+
|
|
11
|
+
// src/targets/functional/claude-code-logic.ts
|
|
12
|
+
var generateHookCommands = async (targetId) => {
|
|
13
|
+
return {
|
|
14
|
+
sessionCommand: `sylphx-flow hook --type session --target ${targetId}`,
|
|
15
|
+
notificationCommand: `sylphx-flow hook --type notification --target ${targetId}`
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
var DEFAULT_HOOKS = {
|
|
19
|
+
sessionCommand: "sylphx-flow hook --type session --target claude-code",
|
|
20
|
+
notificationCommand: "sylphx-flow hook --type notification --target claude-code"
|
|
21
|
+
};
|
|
22
|
+
var parseSettings = (content) => {
|
|
23
|
+
return tryCatch(() => JSON.parse(content), (error) => configError("Failed to parse Claude Code settings", {
|
|
24
|
+
cause: error instanceof Error ? error : undefined
|
|
25
|
+
}));
|
|
26
|
+
};
|
|
27
|
+
var buildHookConfiguration = (config = DEFAULT_HOOKS) => {
|
|
28
|
+
const sessionCommand = config.sessionCommand || DEFAULT_HOOKS.sessionCommand;
|
|
29
|
+
const notificationCommand = config.notificationCommand || DEFAULT_HOOKS.notificationCommand;
|
|
30
|
+
return {
|
|
31
|
+
SessionStart: [
|
|
32
|
+
{
|
|
33
|
+
hooks: [
|
|
34
|
+
{
|
|
35
|
+
type: "command",
|
|
36
|
+
command: sessionCommand
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
Notification: [
|
|
42
|
+
{
|
|
43
|
+
matcher: "",
|
|
44
|
+
hooks: [
|
|
45
|
+
{
|
|
46
|
+
type: "command",
|
|
47
|
+
command: notificationCommand
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
var mergeSettings = (existingSettings, hookConfig = DEFAULT_HOOKS) => {
|
|
55
|
+
const newHooks = buildHookConfiguration(hookConfig);
|
|
56
|
+
return {
|
|
57
|
+
...existingSettings,
|
|
58
|
+
hooks: {
|
|
59
|
+
...existingSettings.hooks || {},
|
|
60
|
+
...newHooks
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
var createSettings = (hookConfig = DEFAULT_HOOKS) => {
|
|
65
|
+
return {
|
|
66
|
+
hooks: buildHookConfiguration(hookConfig)
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
var serializeSettings = (settings) => {
|
|
70
|
+
return JSON.stringify(settings, null, 2);
|
|
71
|
+
};
|
|
72
|
+
var getSuccessMessage = () => {
|
|
73
|
+
return "Claude Code hooks configured: SessionStart (static info) + UserPromptSubmit (dynamic info)";
|
|
74
|
+
};
|
|
75
|
+
var processSettings = (existingContent, hookConfig = DEFAULT_HOOKS) => {
|
|
76
|
+
if (existingContent === null || existingContent.trim() === "") {
|
|
77
|
+
const settings = createSettings(hookConfig);
|
|
78
|
+
return success(serializeSettings(settings));
|
|
79
|
+
}
|
|
80
|
+
const parseResult = parseSettings(existingContent);
|
|
81
|
+
if (parseResult._tag === "Failure") {
|
|
82
|
+
const settings = createSettings(hookConfig);
|
|
83
|
+
return success(serializeSettings(settings));
|
|
84
|
+
}
|
|
85
|
+
const merged = mergeSettings(parseResult.value, hookConfig);
|
|
86
|
+
return success(serializeSettings(merged));
|
|
87
|
+
};
|
|
88
|
+
var validateHookConfig = (config) => {
|
|
89
|
+
if (config.sessionCommand !== undefined && config.sessionCommand.trim() === "") {
|
|
90
|
+
return failure(configError("Session command cannot be empty"));
|
|
91
|
+
}
|
|
92
|
+
if (config.messageCommand !== undefined && config.messageCommand.trim() === "") {
|
|
93
|
+
return failure(configError("Message command cannot be empty"));
|
|
94
|
+
}
|
|
95
|
+
return success(config);
|
|
96
|
+
};
|
|
97
|
+
export {
|
|
98
|
+
validateHookConfig,
|
|
99
|
+
serializeSettings,
|
|
100
|
+
processSettings,
|
|
101
|
+
parseSettings,
|
|
102
|
+
mergeSettings,
|
|
103
|
+
getSuccessMessage,
|
|
104
|
+
generateHookCommands,
|
|
105
|
+
createSettings,
|
|
106
|
+
buildHookConfiguration,
|
|
107
|
+
DEFAULT_HOOKS
|
|
108
|
+
};
|
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLIError,
|
|
3
|
+
FileInstaller,
|
|
4
|
+
MCPInstaller,
|
|
5
|
+
opencodeTarget
|
|
6
|
+
} from "./chunk-cjd3mk4c.js";
|
|
7
|
+
import {
|
|
8
|
+
getAgentsDir,
|
|
9
|
+
getSlashCommandsDir
|
|
10
|
+
} from "./chunk-t16rfxh0.js";
|
|
11
|
+
import {
|
|
12
|
+
fileUtils,
|
|
13
|
+
generateHelpText,
|
|
14
|
+
pathUtils,
|
|
15
|
+
sanitize,
|
|
16
|
+
yamlUtils
|
|
17
|
+
} from "./chunk-hpkhykhq.js";
|
|
18
|
+
import {
|
|
19
|
+
__require,
|
|
20
|
+
__toESM
|
|
21
|
+
} from "./chunk-5j4w74t6.js";
|
|
22
|
+
|
|
23
|
+
// src/core/functional/option.ts
|
|
24
|
+
var some = (value) => ({
|
|
25
|
+
_tag: "Some",
|
|
26
|
+
value
|
|
27
|
+
});
|
|
28
|
+
var none = {
|
|
29
|
+
_tag: "None"
|
|
30
|
+
};
|
|
31
|
+
var isSome = (option) => option._tag === "Some";
|
|
32
|
+
var getOrElse = (defaultValue) => (option) => {
|
|
33
|
+
if (isSome(option)) {
|
|
34
|
+
return option.value;
|
|
35
|
+
}
|
|
36
|
+
return defaultValue;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/targets/claude-code.ts
|
|
40
|
+
import { spawn } from "node:child_process";
|
|
41
|
+
import fs from "node:fs";
|
|
42
|
+
import fsPromises from "node:fs/promises";
|
|
43
|
+
import path from "node:path";
|
|
44
|
+
var claudeCodeTarget = {
|
|
45
|
+
id: "claude-code",
|
|
46
|
+
name: "Claude Code",
|
|
47
|
+
description: "Claude Code CLI with YAML front matter agents (.claude/agents/*.md)",
|
|
48
|
+
category: "cli",
|
|
49
|
+
isImplemented: true,
|
|
50
|
+
isDefault: false,
|
|
51
|
+
mcpServerConfig: {
|
|
52
|
+
disableTime: true,
|
|
53
|
+
disableKnowledge: false,
|
|
54
|
+
disableCodebase: true
|
|
55
|
+
},
|
|
56
|
+
config: {
|
|
57
|
+
agentDir: ".claude/agents",
|
|
58
|
+
agentExtension: ".md",
|
|
59
|
+
agentFormat: "yaml-frontmatter",
|
|
60
|
+
stripYaml: false,
|
|
61
|
+
flatten: false,
|
|
62
|
+
configFile: ".mcp.json",
|
|
63
|
+
configSchema: null,
|
|
64
|
+
mcpConfigPath: "mcpServers",
|
|
65
|
+
rulesFile: undefined,
|
|
66
|
+
outputStylesDir: undefined,
|
|
67
|
+
slashCommandsDir: ".claude/commands",
|
|
68
|
+
installation: {
|
|
69
|
+
createAgentDir: true,
|
|
70
|
+
createConfigFile: true,
|
|
71
|
+
useSecretFiles: false
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
async transformAgentContent(content, metadata, sourcePath) {
|
|
75
|
+
const { metadata: existingMetadata, content: baseContent } = await yamlUtils.extractFrontMatter(content);
|
|
76
|
+
const claudeCodeMetadata = convertToClaudeCodeFormat(existingMetadata, baseContent, sourcePath);
|
|
77
|
+
if (metadata) {
|
|
78
|
+
Object.assign(claudeCodeMetadata, metadata);
|
|
79
|
+
}
|
|
80
|
+
return yamlUtils.addFrontMatter(baseContent, claudeCodeMetadata);
|
|
81
|
+
},
|
|
82
|
+
transformMCPConfig(config, _serverId) {
|
|
83
|
+
if (config.type === "local") {
|
|
84
|
+
const [command, ...args] = config.command;
|
|
85
|
+
return {
|
|
86
|
+
type: "stdio",
|
|
87
|
+
command,
|
|
88
|
+
...args && args.length > 0 && { args },
|
|
89
|
+
...config.environment && { env: config.environment }
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (config.type === "stdio") {
|
|
93
|
+
return {
|
|
94
|
+
type: "stdio",
|
|
95
|
+
command: config.command,
|
|
96
|
+
...config.args && config.args.length > 0 && { args: config.args },
|
|
97
|
+
...config.env && { env: config.env }
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (config.type === "remote") {
|
|
101
|
+
return {
|
|
102
|
+
type: "http",
|
|
103
|
+
url: config.url,
|
|
104
|
+
...config.headers && { headers: config.headers }
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (config.type === "http") {
|
|
108
|
+
return {
|
|
109
|
+
type: "http",
|
|
110
|
+
url: config.url,
|
|
111
|
+
...config.headers && { headers: config.headers }
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
return config;
|
|
115
|
+
},
|
|
116
|
+
getConfigPath: (cwd) => Promise.resolve(fileUtils.getConfigPath(claudeCodeTarget.config, cwd)),
|
|
117
|
+
async readConfig(cwd) {
|
|
118
|
+
const config = await fileUtils.readConfig(claudeCodeTarget.config, cwd);
|
|
119
|
+
if (!config.mcpServers) {
|
|
120
|
+
config.mcpServers = {};
|
|
121
|
+
}
|
|
122
|
+
return config;
|
|
123
|
+
},
|
|
124
|
+
async writeConfig(cwd, config) {
|
|
125
|
+
if (!config.mcpServers) {
|
|
126
|
+
config.mcpServers = {};
|
|
127
|
+
}
|
|
128
|
+
await fileUtils.writeConfig(claudeCodeTarget.config, cwd, config);
|
|
129
|
+
},
|
|
130
|
+
validateRequirements: (cwd) => fileUtils.validateRequirements(claudeCodeTarget.config, cwd),
|
|
131
|
+
getHelpText() {
|
|
132
|
+
let help = generateHelpText(claudeCodeTarget.config);
|
|
133
|
+
help += `Claude Code-Specific Information:
|
|
134
|
+
`;
|
|
135
|
+
help += ` Configuration File: .mcp.json
|
|
136
|
+
`;
|
|
137
|
+
help += ` Agent Format: Markdown with YAML front matter
|
|
138
|
+
`;
|
|
139
|
+
help += ` MCP Integration: Full server support
|
|
140
|
+
|
|
141
|
+
`;
|
|
142
|
+
help += `Example Agent Structure:
|
|
143
|
+
`;
|
|
144
|
+
help += ` ---
|
|
145
|
+
`;
|
|
146
|
+
help += ` name: "code-reviewer"
|
|
147
|
+
`;
|
|
148
|
+
help += ` description: "Expert code review specialist"
|
|
149
|
+
`;
|
|
150
|
+
help += ` ---
|
|
151
|
+
|
|
152
|
+
`;
|
|
153
|
+
help += ` Agent content here...
|
|
154
|
+
|
|
155
|
+
`;
|
|
156
|
+
help += `Note: Only 'name' and 'description' fields are supported.
|
|
157
|
+
`;
|
|
158
|
+
help += `Tools field omitted to allow all tools by default (whitelist model limitation).
|
|
159
|
+
`;
|
|
160
|
+
help += `Unsupported fields (mode, temperature, etc.) are automatically removed.
|
|
161
|
+
|
|
162
|
+
`;
|
|
163
|
+
help += `Example MCP Configuration:
|
|
164
|
+
`;
|
|
165
|
+
help += ` {
|
|
166
|
+
`;
|
|
167
|
+
help += ` "mcpServers": {
|
|
168
|
+
`;
|
|
169
|
+
help += ` "filesystem": {
|
|
170
|
+
`;
|
|
171
|
+
help += ` "type": "stdio",
|
|
172
|
+
`;
|
|
173
|
+
help += ` "command": "npx",
|
|
174
|
+
`;
|
|
175
|
+
help += ` "args": ["@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
|
|
176
|
+
`;
|
|
177
|
+
help += ` },
|
|
178
|
+
`;
|
|
179
|
+
help += ` "git": {
|
|
180
|
+
`;
|
|
181
|
+
help += ` "type": "stdio",
|
|
182
|
+
`;
|
|
183
|
+
help += ` "command": "npx",
|
|
184
|
+
`;
|
|
185
|
+
help += ` "args": ["@modelcontextprotocol/server-git", "."],
|
|
186
|
+
`;
|
|
187
|
+
help += ` "env": {
|
|
188
|
+
`;
|
|
189
|
+
help += ` "GIT_TRACE": "1"
|
|
190
|
+
`;
|
|
191
|
+
help += ` }
|
|
192
|
+
`;
|
|
193
|
+
help += ` },
|
|
194
|
+
`;
|
|
195
|
+
help += ` "api-server": {
|
|
196
|
+
`;
|
|
197
|
+
help += ` "type": "http",
|
|
198
|
+
`;
|
|
199
|
+
help += ` "url": "https://api.example.com/mcp",
|
|
200
|
+
`;
|
|
201
|
+
help += ` "headers": {
|
|
202
|
+
`;
|
|
203
|
+
help += ` "Authorization": "Bearer $API_KEY"
|
|
204
|
+
`;
|
|
205
|
+
help += ` }
|
|
206
|
+
`;
|
|
207
|
+
help += ` }
|
|
208
|
+
`;
|
|
209
|
+
help += ` }
|
|
210
|
+
`;
|
|
211
|
+
help += ` }
|
|
212
|
+
|
|
213
|
+
`;
|
|
214
|
+
help += `Note: Environment variables can be expanded in command, args, env, url, and headers.
|
|
215
|
+
|
|
216
|
+
`;
|
|
217
|
+
return help;
|
|
218
|
+
},
|
|
219
|
+
async executeCommand(systemPrompt, userPrompt, options = {}) {
|
|
220
|
+
const sanitizedSystemPrompt = sanitize.yamlContent(systemPrompt);
|
|
221
|
+
const sanitizedUserPrompt = userPrompt.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, "");
|
|
222
|
+
const enhancedSystemPrompt = `${sanitizedSystemPrompt}
|
|
223
|
+
|
|
224
|
+
Please begin your response with a comprehensive summary of all the instructions and context provided above.`;
|
|
225
|
+
if (options.dryRun) {
|
|
226
|
+
const dryRunArgs = ["claude", "--dangerously-skip-permissions"];
|
|
227
|
+
if (options.print)
|
|
228
|
+
dryRunArgs.push("-p");
|
|
229
|
+
if (options.continue)
|
|
230
|
+
dryRunArgs.push("-c");
|
|
231
|
+
dryRunArgs.push("--system-prompt", '"<agent content>"');
|
|
232
|
+
if (sanitizedUserPrompt.trim() !== "") {
|
|
233
|
+
dryRunArgs.push(`"${sanitizedUserPrompt}"`);
|
|
234
|
+
}
|
|
235
|
+
console.log(chalk.cyan("Dry run - Would execute:"));
|
|
236
|
+
console.log(chalk.bold(dryRunArgs.join(" ")));
|
|
237
|
+
console.log(chalk.dim(`System prompt: ${enhancedSystemPrompt.length} characters`));
|
|
238
|
+
console.log(chalk.dim(`User prompt: ${sanitizedUserPrompt.length} characters`));
|
|
239
|
+
console.log("✓ Dry run completed successfully");
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
try {
|
|
243
|
+
const args = ["--dangerously-skip-permissions"];
|
|
244
|
+
if (options.print) {
|
|
245
|
+
args.push("-p");
|
|
246
|
+
}
|
|
247
|
+
if (options.continue) {
|
|
248
|
+
args.push("-c");
|
|
249
|
+
}
|
|
250
|
+
args.push("--system-prompt", enhancedSystemPrompt);
|
|
251
|
+
if (options.verbose) {
|
|
252
|
+
console.log("\uD83D\uDE80 Executing Claude Code");
|
|
253
|
+
console.log(`\uD83D\uDCDD System prompt length: ${enhancedSystemPrompt.length} characters`);
|
|
254
|
+
}
|
|
255
|
+
if (sanitizedUserPrompt.trim() !== "") {
|
|
256
|
+
args.push(sanitizedUserPrompt);
|
|
257
|
+
}
|
|
258
|
+
if (options.verbose) {
|
|
259
|
+
console.log(`\uD83D\uDCDD User prompt length: ${sanitizedUserPrompt.length} characters`);
|
|
260
|
+
}
|
|
261
|
+
if (options.verbose) {
|
|
262
|
+
console.log(`\uD83D\uDE80 Executing: claude ${args.join(" ")}`);
|
|
263
|
+
console.log("");
|
|
264
|
+
}
|
|
265
|
+
await new Promise((resolve, reject) => {
|
|
266
|
+
const child = spawn("claude", args, {
|
|
267
|
+
stdio: "inherit",
|
|
268
|
+
shell: false,
|
|
269
|
+
env: process.env
|
|
270
|
+
});
|
|
271
|
+
child.on("spawn", () => {
|
|
272
|
+
if (options.verbose) {
|
|
273
|
+
console.log("✓ Claude Code started");
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
child.on("close", (code) => {
|
|
277
|
+
if (code === 0) {
|
|
278
|
+
resolve();
|
|
279
|
+
} else {
|
|
280
|
+
const error = new Error(`Claude Code exited with code ${code}`);
|
|
281
|
+
error.code = code;
|
|
282
|
+
reject(error);
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
child.on("error", (error) => {
|
|
286
|
+
if (options.verbose) {
|
|
287
|
+
console.error("✗ Error spawning Claude:", error);
|
|
288
|
+
}
|
|
289
|
+
reject(error);
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
} catch (error) {
|
|
293
|
+
if (error.code === "ENOENT") {
|
|
294
|
+
throw new CLIError("Claude Code not found. Please install it first.", "CLAUDE_NOT_FOUND");
|
|
295
|
+
}
|
|
296
|
+
if (error.code) {
|
|
297
|
+
throw new CLIError(`Claude Code exited with code ${error.code}`, "CLAUDE_ERROR");
|
|
298
|
+
}
|
|
299
|
+
throw new CLIError(`Failed to execute Claude Code: ${error.message}`, "CLAUDE_ERROR");
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
detectFromEnvironment() {
|
|
303
|
+
try {
|
|
304
|
+
const cwd = process.cwd();
|
|
305
|
+
return fs.existsSync(path.join(cwd, ".mcp.json"));
|
|
306
|
+
} catch {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
async approveMCPServers(cwd, serverNames) {
|
|
311
|
+
const settingsPath = path.join(cwd, ".claude", "settings.local.json");
|
|
312
|
+
try {
|
|
313
|
+
let settings = {};
|
|
314
|
+
try {
|
|
315
|
+
const content = await fsPromises.readFile(settingsPath, "utf8");
|
|
316
|
+
settings = JSON.parse(content);
|
|
317
|
+
} catch (error) {
|
|
318
|
+
if (error.code !== "ENOENT") {
|
|
319
|
+
throw error;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
const existingServers = Array.isArray(settings.enabledMcpjsonServers) ? settings.enabledMcpjsonServers : [];
|
|
323
|
+
const allServers = [...new Set([...existingServers, ...serverNames])];
|
|
324
|
+
settings.enabledMcpjsonServers = allServers;
|
|
325
|
+
await fsPromises.mkdir(path.dirname(settingsPath), { recursive: true });
|
|
326
|
+
await fsPromises.writeFile(settingsPath, `${JSON.stringify(settings, null, 2)}
|
|
327
|
+
`, "utf8");
|
|
328
|
+
} catch (error) {
|
|
329
|
+
throw new Error(`Failed to approve MCP servers: ${error instanceof Error ? error.message : String(error)}`);
|
|
330
|
+
}
|
|
331
|
+
},
|
|
332
|
+
async transformRulesContent(content) {
|
|
333
|
+
return yamlUtils.stripFrontMatter(content);
|
|
334
|
+
},
|
|
335
|
+
async setupHooks(cwd, _options) {
|
|
336
|
+
const { processSettings, generateHookCommands } = await import("./chunk-pgd3m6zf.js");
|
|
337
|
+
const { pathExists, createDirectory, readFile, writeFile } = await import("./chunk-25dwp0dp.js");
|
|
338
|
+
const claudeConfigDir = path.join(cwd, ".claude");
|
|
339
|
+
const settingsPath = path.join(claudeConfigDir, "settings.json");
|
|
340
|
+
const dirExistsResult = await pathExists(claudeConfigDir);
|
|
341
|
+
if (dirExistsResult._tag === "Success" && !dirExistsResult.value) {
|
|
342
|
+
const createResult = await createDirectory(claudeConfigDir, { recursive: true });
|
|
343
|
+
if (createResult._tag === "Failure") {
|
|
344
|
+
throw new Error(`Failed to create .claude directory: ${createResult.error.message}`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
let existingContent = null;
|
|
348
|
+
const fileExistsResult = await pathExists(settingsPath);
|
|
349
|
+
if (fileExistsResult._tag === "Success" && fileExistsResult.value) {
|
|
350
|
+
const readResult = await readFile(settingsPath);
|
|
351
|
+
if (readResult._tag === "Success") {
|
|
352
|
+
existingContent = readResult.value;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const hookCommands = await generateHookCommands("claude-code");
|
|
356
|
+
const settingsResult = processSettings(existingContent, hookCommands);
|
|
357
|
+
if (settingsResult._tag === "Failure") {
|
|
358
|
+
throw new Error(`Failed to process settings: ${settingsResult.error.message}`);
|
|
359
|
+
}
|
|
360
|
+
const writeResult = await writeFile(settingsPath, settingsResult.value);
|
|
361
|
+
if (writeResult._tag === "Failure") {
|
|
362
|
+
throw new Error(`Failed to write settings: ${writeResult.error.message}`);
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
count: 3,
|
|
366
|
+
message: "Configured session, message, and notification hooks"
|
|
367
|
+
};
|
|
368
|
+
},
|
|
369
|
+
async setupAgents(cwd, options) {
|
|
370
|
+
const { enhanceAgentContent } = await import("./chunk-5thh3qem.js");
|
|
371
|
+
const installer = new FileInstaller;
|
|
372
|
+
const agentsDir = path.join(cwd, this.config.agentDir);
|
|
373
|
+
const results = await installer.installToDirectory(getAgentsDir(), agentsDir, async (content, sourcePath) => {
|
|
374
|
+
const transformed = await this.transformAgentContent(content, undefined, sourcePath);
|
|
375
|
+
const { metadata } = await yamlUtils.extractFrontMatter(transformed);
|
|
376
|
+
const rules = metadata.rules;
|
|
377
|
+
const enhanced = await enhanceAgentContent(transformed, rules);
|
|
378
|
+
return enhanced;
|
|
379
|
+
}, {
|
|
380
|
+
...options,
|
|
381
|
+
showProgress: false
|
|
382
|
+
});
|
|
383
|
+
return { count: results.length };
|
|
384
|
+
},
|
|
385
|
+
async setupOutputStyles(_cwd, _options) {
|
|
386
|
+
return {
|
|
387
|
+
count: 0,
|
|
388
|
+
message: "Output styles included in agent files"
|
|
389
|
+
};
|
|
390
|
+
},
|
|
391
|
+
async setupRules(_cwd, _options) {
|
|
392
|
+
return {
|
|
393
|
+
count: 0,
|
|
394
|
+
message: "Rules included in agent files"
|
|
395
|
+
};
|
|
396
|
+
},
|
|
397
|
+
async setupMCP(cwd, options) {
|
|
398
|
+
const installer = new MCPInstaller(this);
|
|
399
|
+
const result = await installer.setupMCP({ ...options, quiet: true });
|
|
400
|
+
if (result.selectedServers.length > 0 && !options.dryRun) {
|
|
401
|
+
if (this.approveMCPServers) {
|
|
402
|
+
await this.approveMCPServers(cwd, result.selectedServers);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return { count: result.selectedServers.length };
|
|
406
|
+
},
|
|
407
|
+
async setupSlashCommands(cwd, options) {
|
|
408
|
+
if (!this.config.slashCommandsDir) {
|
|
409
|
+
return { count: 0 };
|
|
410
|
+
}
|
|
411
|
+
const installer = new FileInstaller;
|
|
412
|
+
const slashCommandsDir = path.join(cwd, this.config.slashCommandsDir);
|
|
413
|
+
const results = await installer.installToDirectory(getSlashCommandsDir(), slashCommandsDir, async (content) => {
|
|
414
|
+
return content;
|
|
415
|
+
}, {
|
|
416
|
+
...options,
|
|
417
|
+
showProgress: false
|
|
418
|
+
});
|
|
419
|
+
return { count: results.length };
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
function convertToClaudeCodeFormat(openCodeMetadata, content, sourcePath) {
|
|
423
|
+
const agentName = openCodeMetadata.name || pathUtils.extractAgentName(content, openCodeMetadata, sourcePath);
|
|
424
|
+
const description = openCodeMetadata.description || pathUtils.extractDescription(content);
|
|
425
|
+
const result = {
|
|
426
|
+
name: agentName,
|
|
427
|
+
description
|
|
428
|
+
};
|
|
429
|
+
if (openCodeMetadata.model && openCodeMetadata.model !== "inherit") {
|
|
430
|
+
result.model = openCodeMetadata.model;
|
|
431
|
+
}
|
|
432
|
+
return result;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// src/config/targets.ts
|
|
436
|
+
var cachedTargets = null;
|
|
437
|
+
var initializeTargets = () => {
|
|
438
|
+
if (cachedTargets) {
|
|
439
|
+
return cachedTargets;
|
|
440
|
+
}
|
|
441
|
+
cachedTargets = Object.freeze([opencodeTarget, claudeCodeTarget]);
|
|
442
|
+
return cachedTargets;
|
|
443
|
+
};
|
|
444
|
+
var getAllTargets = () => initializeTargets();
|
|
445
|
+
var getImplementedTargets = () => getAllTargets().filter((target) => target.isImplemented);
|
|
446
|
+
var getAllTargetIDs = () => getAllTargets().map((target) => target.id);
|
|
447
|
+
var getImplementedTargetIDs = () => getImplementedTargets().map((target) => target.id);
|
|
448
|
+
var getTarget = (id) => {
|
|
449
|
+
const target = getAllTargets().find((t) => t.id === id);
|
|
450
|
+
return target ? some(target) : none;
|
|
451
|
+
};
|
|
452
|
+
var getTargetUnsafe = (id) => {
|
|
453
|
+
const target = getAllTargets().find((t) => t.id === id);
|
|
454
|
+
if (!target) {
|
|
455
|
+
throw new Error(`Target not found: ${id}`);
|
|
456
|
+
}
|
|
457
|
+
return target;
|
|
458
|
+
};
|
|
459
|
+
var getDefaultTarget = () => {
|
|
460
|
+
const target = getAllTargets().find((t) => t.isDefault);
|
|
461
|
+
return target ? some(target) : none;
|
|
462
|
+
};
|
|
463
|
+
var getDefaultTargetUnsafe = () => {
|
|
464
|
+
const target = getAllTargets().find((t) => t.isDefault);
|
|
465
|
+
if (!target) {
|
|
466
|
+
throw new Error("No default target configured");
|
|
467
|
+
}
|
|
468
|
+
return target;
|
|
469
|
+
};
|
|
470
|
+
var getTargetsWithMCPSupport = () => getImplementedTargets().filter((target) => !!target.setupMCP);
|
|
471
|
+
var getTargetsWithCommandSupport = () => getImplementedTargets().filter((target) => !!target.executeCommand);
|
|
472
|
+
var isTargetImplemented = (id) => {
|
|
473
|
+
const target = getAllTargets().find((t) => t.id === id);
|
|
474
|
+
return target?.isImplemented ?? false;
|
|
475
|
+
};
|
|
476
|
+
var ALL_TARGETS = getAllTargets;
|
|
477
|
+
var IMPLEMENTED_TARGETS = getImplementedTargets;
|
|
478
|
+
export {
|
|
479
|
+
isTargetImplemented,
|
|
480
|
+
getTargetsWithMCPSupport,
|
|
481
|
+
getTargetsWithCommandSupport,
|
|
482
|
+
getTargetUnsafe,
|
|
483
|
+
getTarget,
|
|
484
|
+
getImplementedTargets,
|
|
485
|
+
getImplementedTargetIDs,
|
|
486
|
+
getDefaultTargetUnsafe,
|
|
487
|
+
getDefaultTarget,
|
|
488
|
+
getAllTargets,
|
|
489
|
+
getAllTargetIDs,
|
|
490
|
+
IMPLEMENTED_TARGETS,
|
|
491
|
+
ALL_TARGETS
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
export { isSome, getOrElse, getAllTargets, getImplementedTargets, getAllTargetIDs, getImplementedTargetIDs, getTarget, getDefaultTargetUnsafe, getTargetsWithMCPSupport, isTargetImplemented };
|