@cliangdev/conductor 0.1.2
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 +141 -0
- package/assets/claude/agents/researcher.md +147 -0
- package/assets/claude/commands/conductor/implement.md +393 -0
- package/assets/claude/commands/conductor/prd.md +291 -0
- package/assets/claude/skills/conductor-coder/SKILL.md +214 -0
- package/assets/claude/skills/ux-ui-design/SKILL.md +346 -0
- package/assets/claude/skills/ux-ui-design/references/design-tokens.md +359 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +106 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/dashboard.d.ts +9 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +159 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/doctor.d.ts +6 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +126 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +19 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +276 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +161 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +14 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +10 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/start.d.ts +7 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +74 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +126 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +4 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +30 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/daemon/poller.d.ts +18 -0
- package/dist/daemon/poller.d.ts.map +1 -0
- package/dist/daemon/poller.js +96 -0
- package/dist/daemon/poller.js.map +1 -0
- package/dist/daemon/run-lifecycle.d.ts +21 -0
- package/dist/daemon/run-lifecycle.d.ts.map +1 -0
- package/dist/daemon/run-lifecycle.js +53 -0
- package/dist/daemon/run-lifecycle.js.map +1 -0
- package/dist/daemon/run-queue.d.ts +12 -0
- package/dist/daemon/run-queue.d.ts.map +1 -0
- package/dist/daemon/run-queue.js +59 -0
- package/dist/daemon/run-queue.js.map +1 -0
- package/dist/daemon/runner.d.ts +31 -0
- package/dist/daemon/runner.d.ts.map +1 -0
- package/dist/daemon/runner.js +91 -0
- package/dist/daemon/runner.js.map +1 -0
- package/dist/daemon/state.d.ts +22 -0
- package/dist/daemon/state.d.ts.map +1 -0
- package/dist/daemon/state.js +29 -0
- package/dist/daemon/state.js.map +1 -0
- package/dist/daemon/watcher.d.ts +26 -0
- package/dist/daemon/watcher.d.ts.map +1 -0
- package/dist/daemon/watcher.js +330 -0
- package/dist/daemon/watcher.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +8 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +55 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/config.d.ts +16 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +48 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/next-steps.d.ts +2 -0
- package/dist/lib/next-steps.d.ts.map +1 -0
- package/dist/lib/next-steps.js +11 -0
- package/dist/lib/next-steps.js.map +1 -0
- package/dist/lib/oauth-server.d.ts +10 -0
- package/dist/lib/oauth-server.d.ts.map +1 -0
- package/dist/lib/oauth-server.js +67 -0
- package/dist/lib/oauth-server.js.map +1 -0
- package/dist/lib/plugin-assets.d.ts +19 -0
- package/dist/lib/plugin-assets.d.ts.map +1 -0
- package/dist/lib/plugin-assets.js +121 -0
- package/dist/lib/plugin-assets.js.map +1 -0
- package/dist/mcp/api.d.ts +7 -0
- package/dist/mcp/api.d.ts.map +1 -0
- package/dist/mcp/api.js +36 -0
- package/dist/mcp/api.js.map +1 -0
- package/dist/mcp/config.d.ts +11 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +31 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/files.d.ts +9 -0
- package/dist/mcp/files.d.ts.map +1 -0
- package/dist/mcp/files.js +43 -0
- package/dist/mcp/files.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +234 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/queue.d.ts +8 -0
- package/dist/mcp/queue.d.ts.map +1 -0
- package/dist/mcp/queue.js +19 -0
- package/dist/mcp/queue.js.map +1 -0
- package/dist/mcp/tools/comments.d.ts +6 -0
- package/dist/mcp/tools/comments.d.ts.map +1 -0
- package/dist/mcp/tools/comments.js +21 -0
- package/dist/mcp/tools/comments.js.map +1 -0
- package/dist/mcp/tools/documents.d.ts +11 -0
- package/dist/mcp/tools/documents.d.ts.map +1 -0
- package/dist/mcp/tools/documents.js +44 -0
- package/dist/mcp/tools/documents.js.map +1 -0
- package/dist/mcp/tools/issues.d.ts +23 -0
- package/dist/mcp/tools/issues.d.ts.map +1 -0
- package/dist/mcp/tools/issues.js +141 -0
- package/dist/mcp/tools/issues.js.map +1 -0
- package/package.json +40 -0
- package/scripts/postinstall.js +81 -0
- package/scripts/preuninstall.js +175 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
import * as readline from 'readline';
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import ora from 'ora';
|
|
8
|
+
import { readConfig, writeConfig } from '../lib/config.js';
|
|
9
|
+
import { apiGet, apiPost } from '../lib/api.js';
|
|
10
|
+
import { findAvailablePort, waitForOAuthCallback } from '../lib/oauth-server.js';
|
|
11
|
+
import { startDaemon } from './start.js';
|
|
12
|
+
import { installPluginAssets, getAssetSrcDir } from '../lib/plugin-assets.js';
|
|
13
|
+
import { printNextSteps } from '../lib/next-steps.js';
|
|
14
|
+
const CONDUCTOR_MCP_ENTRY = {
|
|
15
|
+
command: 'conductor',
|
|
16
|
+
args: ['mcp'],
|
|
17
|
+
};
|
|
18
|
+
export function getIssuesDir(projectId) {
|
|
19
|
+
return path.join(os.homedir(), '.conductor', projectId, 'issues');
|
|
20
|
+
}
|
|
21
|
+
export function getProjectRoot(workingDir) {
|
|
22
|
+
try {
|
|
23
|
+
return execSync('git rev-parse --show-toplevel', {
|
|
24
|
+
cwd: workingDir,
|
|
25
|
+
encoding: 'utf8',
|
|
26
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
27
|
+
}).trim();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return workingDir;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function ensureGitignore(projectRoot) {
|
|
34
|
+
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
35
|
+
const entry = '.conductor/';
|
|
36
|
+
let content = '';
|
|
37
|
+
try {
|
|
38
|
+
content = fs.readFileSync(gitignorePath, 'utf8');
|
|
39
|
+
}
|
|
40
|
+
catch { /* doesn't exist */ }
|
|
41
|
+
if (content.split('\n').some(line => line.trim() === entry))
|
|
42
|
+
return;
|
|
43
|
+
const newContent = content && !content.endsWith('\n') ? `${content}\n${entry}\n` : `${content}${entry}\n`;
|
|
44
|
+
fs.writeFileSync(gitignorePath, newContent, 'utf8');
|
|
45
|
+
}
|
|
46
|
+
export function readMcpJson(workingDir) {
|
|
47
|
+
const mcpPath = path.join(workingDir, '.mcp.json');
|
|
48
|
+
try {
|
|
49
|
+
const raw = fs.readFileSync(mcpPath, 'utf8');
|
|
50
|
+
return JSON.parse(raw);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function writeMcpJson(workingDir, content) {
|
|
57
|
+
const mcpPath = path.join(workingDir, '.mcp.json');
|
|
58
|
+
fs.writeFileSync(mcpPath, JSON.stringify(content, null, 2) + '\n', 'utf8');
|
|
59
|
+
}
|
|
60
|
+
export function buildMcpJson(existing) {
|
|
61
|
+
return {
|
|
62
|
+
...existing,
|
|
63
|
+
mcpServers: {
|
|
64
|
+
...(existing.mcpServers ?? {}),
|
|
65
|
+
conductor: CONDUCTOR_MCP_ENTRY,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
async function askYesNo(question) {
|
|
70
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
71
|
+
return new Promise(resolve => {
|
|
72
|
+
rl.question(question, answer => {
|
|
73
|
+
rl.close();
|
|
74
|
+
resolve(answer.trim().toLowerCase() !== 'n');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async function isKeyValid(apiUrl, apiKey) {
|
|
79
|
+
try {
|
|
80
|
+
const res = await fetch(`${apiUrl}/api/v1/projects`, {
|
|
81
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
82
|
+
});
|
|
83
|
+
return res.status === 200;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function performBrowserLogin(apiUrl, frontendUrl) {
|
|
90
|
+
const spinner = ora('Opening browser for authentication... (Ctrl+C to cancel)').start();
|
|
91
|
+
const port = await findAvailablePort();
|
|
92
|
+
const { default: open } = await import('open');
|
|
93
|
+
const loginUrl = `${frontendUrl}/auth/cli-login?port=${port}`;
|
|
94
|
+
await open(loginUrl);
|
|
95
|
+
const payload = await waitForOAuthCallback(port, spinner);
|
|
96
|
+
spinner.succeed(chalk.green(`Logged in as ${payload.email}`));
|
|
97
|
+
return { apiKey: payload.apiKey, email: payload.email };
|
|
98
|
+
}
|
|
99
|
+
async function selectOption(promptText, choices) {
|
|
100
|
+
console.log(promptText);
|
|
101
|
+
choices.forEach((c, i) => console.log(` [${i + 1}] ${c}`));
|
|
102
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
103
|
+
return new Promise(resolve => {
|
|
104
|
+
const ask = () => {
|
|
105
|
+
rl.question(`Select (1-${choices.length}): `, answer => {
|
|
106
|
+
const n = parseInt(answer.trim(), 10);
|
|
107
|
+
if (!isNaN(n) && n >= 1 && n <= choices.length) {
|
|
108
|
+
rl.close();
|
|
109
|
+
resolve(n - 1);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
console.log(chalk.red(` Please enter a number between 1 and ${choices.length}`));
|
|
113
|
+
ask();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
ask();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
async function askText(question) {
|
|
121
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
122
|
+
return new Promise(resolve => {
|
|
123
|
+
rl.question(question, answer => {
|
|
124
|
+
rl.close();
|
|
125
|
+
resolve(answer.trim());
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
export function registerInit(program) {
|
|
130
|
+
program
|
|
131
|
+
.command('init')
|
|
132
|
+
.description('Initialize Conductor in the current project')
|
|
133
|
+
.option('--project-id <id>', 'Project ID to connect to (for new members or switching projects)')
|
|
134
|
+
.option('--path <dir>', 'Working directory', process.cwd())
|
|
135
|
+
.addHelpText('after', `
|
|
136
|
+
Examples:
|
|
137
|
+
conductor init
|
|
138
|
+
conductor init --project-id proj_abc123
|
|
139
|
+
conductor init --path /workspace/my-project`)
|
|
140
|
+
.action(async (options) => {
|
|
141
|
+
const workingDir = path.resolve(options.path);
|
|
142
|
+
const apiUrl = process.env['CONDUCTOR_API_URL'] ?? 'https://conductor-backend-199707291514.us-central1.run.app';
|
|
143
|
+
const frontendUrl = process.env['CONDUCTOR_FRONTEND_URL'] ?? 'https://conductor-frontend-199707291514.us-central1.run.app';
|
|
144
|
+
let config = readConfig();
|
|
145
|
+
if (config) {
|
|
146
|
+
const authSpinner = ora('Checking authentication...').start();
|
|
147
|
+
const valid = await isKeyValid(config.apiUrl ?? apiUrl, config.apiKey);
|
|
148
|
+
if (!valid) {
|
|
149
|
+
authSpinner.warn('Session expired. Opening browser for authentication...');
|
|
150
|
+
const { apiKey, email } = await performBrowserLogin(apiUrl, frontendUrl);
|
|
151
|
+
config = { apiKey, email, projectId: '', projectName: '', apiUrl, frontendUrl };
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
authSpinner.succeed(chalk.green(`Logged in as ${config.email}`));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
console.log('Not logged in. Opening browser for authentication...');
|
|
159
|
+
const { apiKey, email } = await performBrowserLogin(apiUrl, frontendUrl);
|
|
160
|
+
config = { apiKey, email, projectId: '', projectName: '', apiUrl, frontendUrl };
|
|
161
|
+
}
|
|
162
|
+
if (options.projectId && options.projectId !== config.projectId) {
|
|
163
|
+
const projectSpinner = ora(`Fetching project "${options.projectId}"...`).start();
|
|
164
|
+
try {
|
|
165
|
+
const project = await apiGet(`/api/v1/projects/${options.projectId}`, config.apiKey, config.apiUrl ?? apiUrl);
|
|
166
|
+
config = { ...config, projectId: project.id, projectName: project.name };
|
|
167
|
+
writeConfig(config);
|
|
168
|
+
projectSpinner.succeed(chalk.green(`Connected to "${config.projectName}"`));
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
const status = err.statusCode;
|
|
172
|
+
if (status === 403 || status === 404) {
|
|
173
|
+
projectSpinner.fail('Access denied');
|
|
174
|
+
console.error(chalk.red(`✗ You don't have access to project "${options.projectId}".`));
|
|
175
|
+
console.error(` Ask your admin to invite you, then run this command again.`);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
throw err;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
else if (!options.projectId) {
|
|
183
|
+
const listSpinner = ora('Fetching your projects...').start();
|
|
184
|
+
const projects = await apiGet('/api/v1/projects', config.apiKey, config.apiUrl ?? apiUrl);
|
|
185
|
+
listSpinner.succeed('Projects loaded');
|
|
186
|
+
let projectId;
|
|
187
|
+
let projectName;
|
|
188
|
+
if (projects.length === 0) {
|
|
189
|
+
console.log('\nNo projects found. Let\'s create one.');
|
|
190
|
+
const name = await askText('Project name: ');
|
|
191
|
+
if (!name) {
|
|
192
|
+
console.error(chalk.red('✗ Project name cannot be empty.'));
|
|
193
|
+
process.exit(1);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const spinner = ora('Creating project...').start();
|
|
197
|
+
const project = await apiPost('/api/v1/projects', { name }, config.apiKey, config.apiUrl ?? apiUrl);
|
|
198
|
+
spinner.succeed(chalk.green(`Created project "${project.name}"`));
|
|
199
|
+
projectId = project.id;
|
|
200
|
+
projectName = project.name;
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
console.log();
|
|
204
|
+
const choices = ['Create a new project', ...projects.map(p => p.name)];
|
|
205
|
+
const idx = await selectOption('Select a project to link:', choices);
|
|
206
|
+
if (idx === 0) {
|
|
207
|
+
const name = await askText('Project name: ');
|
|
208
|
+
if (!name) {
|
|
209
|
+
console.error(chalk.red('✗ Project name cannot be empty.'));
|
|
210
|
+
process.exit(1);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const spinner = ora('Creating project...').start();
|
|
214
|
+
const project = await apiPost('/api/v1/projects', { name }, config.apiKey, config.apiUrl ?? apiUrl);
|
|
215
|
+
spinner.succeed(chalk.green(`Created project "${project.name}"`));
|
|
216
|
+
projectId = project.id;
|
|
217
|
+
projectName = project.name;
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
const picked = projects[idx - 1];
|
|
221
|
+
projectId = picked.id;
|
|
222
|
+
projectName = picked.name;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
config = { ...config, projectId, projectName, apiUrl: config.apiUrl ?? apiUrl, frontendUrl: config.frontendUrl ?? frontendUrl };
|
|
226
|
+
writeConfig(config);
|
|
227
|
+
console.log(chalk.green(`✓ Connected to "${projectName}"`));
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
console.log(chalk.green(`✓ Connected to "${config.projectName}"`));
|
|
231
|
+
}
|
|
232
|
+
console.log(`\nSetting up local project directory for "${config.projectName}"...`);
|
|
233
|
+
const projectRoot = getProjectRoot(workingDir);
|
|
234
|
+
console.log(chalk.green(`✓ Detected project root: ${projectRoot}`));
|
|
235
|
+
const issuesDir = getIssuesDir(config.projectId);
|
|
236
|
+
fs.mkdirSync(issuesDir, { recursive: true });
|
|
237
|
+
fs.mkdirSync(path.join(projectRoot, '.conductor', 'issues'), { recursive: true });
|
|
238
|
+
console.log(chalk.green('✓ Created .conductor/issues/'));
|
|
239
|
+
ensureGitignore(projectRoot);
|
|
240
|
+
console.log(chalk.green('✓ Updated .gitignore'));
|
|
241
|
+
const claudeDir = path.join(projectRoot, '.claude');
|
|
242
|
+
const pluginStatus = installPluginAssets(claudeDir, getAssetSrcDir());
|
|
243
|
+
if (pluginStatus === 'installed') {
|
|
244
|
+
console.log(chalk.green('✓ Installed conductor Claude plugin'));
|
|
245
|
+
}
|
|
246
|
+
else if (pluginStatus === 'updated') {
|
|
247
|
+
console.log(chalk.green('✓ Updated conductor Claude plugin'));
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
console.log(chalk.green('✓ Conductor Claude plugin up to date'));
|
|
251
|
+
}
|
|
252
|
+
const existing = readMcpJson(workingDir);
|
|
253
|
+
writeMcpJson(workingDir, buildMcpJson(existing));
|
|
254
|
+
console.log(chalk.green('✓ Updated .mcp.json'));
|
|
255
|
+
writeConfig({ ...config, localPath: projectRoot });
|
|
256
|
+
if (process.stdin.isTTY) {
|
|
257
|
+
console.log();
|
|
258
|
+
const shouldSync = await askYesNo('Start syncing now? [Y/n] ');
|
|
259
|
+
if (shouldSync) {
|
|
260
|
+
const ok = await startDaemon();
|
|
261
|
+
if (ok) {
|
|
262
|
+
console.log(chalk.green('✓ Sync daemon started'));
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
console.log(chalk.red('✗ Daemon failed to start — run `conductor start` to retry'));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
console.log(chalk.dim(' Run `conductor start` when ready.'));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
printNextSteps();
|
|
273
|
+
process.exit(0);
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkHnC,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsEpD"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import * as readline from 'readline';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { readConfig, writeConfig } from '../lib/config.js';
|
|
5
|
+
import { findAvailablePort, waitForOAuthCallback } from '../lib/oauth-server.js';
|
|
6
|
+
const CONDUCTOR_API_URL = process.env['CONDUCTOR_API_URL'] ?? 'https://conductor-backend-199707291514.us-central1.run.app';
|
|
7
|
+
const CONDUCTOR_FRONTEND_URL = process.env['CONDUCTOR_FRONTEND_URL'] ?? 'https://conductor-frontend-199707291514.us-central1.run.app';
|
|
8
|
+
function resolveApiUrl() {
|
|
9
|
+
const cfg = readConfig();
|
|
10
|
+
return cfg?.apiUrl ?? CONDUCTOR_API_URL;
|
|
11
|
+
}
|
|
12
|
+
function resolveFrontendUrl() {
|
|
13
|
+
const cfg = readConfig();
|
|
14
|
+
return cfg?.frontendUrl ?? CONDUCTOR_FRONTEND_URL;
|
|
15
|
+
}
|
|
16
|
+
function prompt(question, hidden = false) {
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
19
|
+
if (hidden) {
|
|
20
|
+
process.stdout.write(question);
|
|
21
|
+
process.stdin.setRawMode?.(true);
|
|
22
|
+
let input = '';
|
|
23
|
+
process.stdin.resume();
|
|
24
|
+
process.stdin.setEncoding('utf8');
|
|
25
|
+
const onData = (ch) => {
|
|
26
|
+
if (ch === '\n' || ch === '\r' || ch === '\u0003') {
|
|
27
|
+
process.stdin.setRawMode?.(false);
|
|
28
|
+
process.stdin.pause();
|
|
29
|
+
process.stdin.removeListener('data', onData);
|
|
30
|
+
process.stdout.write('\n');
|
|
31
|
+
rl.close();
|
|
32
|
+
resolve(input);
|
|
33
|
+
}
|
|
34
|
+
else if (ch === '\u007f') {
|
|
35
|
+
input = input.slice(0, -1);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
input += ch;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
process.stdin.on('data', onData);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
rl.question(question, (answer) => {
|
|
45
|
+
rl.close();
|
|
46
|
+
resolve(answer);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async function loginLocal(apiUrl) {
|
|
52
|
+
const email = await prompt('Email: ');
|
|
53
|
+
const password = await prompt('Password: ', true);
|
|
54
|
+
const spinner = ora('Authenticating...').start();
|
|
55
|
+
const res = await fetch(`${apiUrl}/api/v1/auth/local`, {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers: { 'Content-Type': 'application/json' },
|
|
58
|
+
body: JSON.stringify({ email, password }),
|
|
59
|
+
});
|
|
60
|
+
if (!res.ok) {
|
|
61
|
+
spinner.fail(chalk.red('Authentication failed — check your email and password.'));
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
const { accessToken, user } = await res.json();
|
|
65
|
+
// Fetch first available project
|
|
66
|
+
const projectsRes = await fetch(`${apiUrl}/api/v1/projects`, {
|
|
67
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
68
|
+
});
|
|
69
|
+
if (!projectsRes.ok) {
|
|
70
|
+
spinner.fail(chalk.red('Authenticated but failed to fetch projects.'));
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
const projects = await projectsRes.json();
|
|
74
|
+
if (projects.length === 0) {
|
|
75
|
+
spinner.fail(chalk.red('No projects found. Create a project in the Conductor UI first.'));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
const project = projects[0];
|
|
79
|
+
writeConfig({
|
|
80
|
+
apiKey: accessToken,
|
|
81
|
+
projectId: project.id,
|
|
82
|
+
projectName: project.name,
|
|
83
|
+
email: user?.email ?? email,
|
|
84
|
+
apiUrl,
|
|
85
|
+
});
|
|
86
|
+
spinner.succeed(chalk.green(`Logged in as ${email} (project: ${project.name})`));
|
|
87
|
+
}
|
|
88
|
+
async function isKeyValid(apiUrl, apiKey) {
|
|
89
|
+
try {
|
|
90
|
+
const res = await fetch(`${apiUrl}/api/v1/projects`, {
|
|
91
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
92
|
+
});
|
|
93
|
+
return res.status === 200;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export function registerLogin(program) {
|
|
100
|
+
program
|
|
101
|
+
.command('login')
|
|
102
|
+
.description('Authenticate with Conductor via browser')
|
|
103
|
+
.option('--force', 'Re-authenticate even if already logged in')
|
|
104
|
+
.option('--local', 'Use email/password login (local dev only)')
|
|
105
|
+
.addHelpText('after', `
|
|
106
|
+
Examples:
|
|
107
|
+
conductor login
|
|
108
|
+
conductor login --force
|
|
109
|
+
conductor login --local`)
|
|
110
|
+
.action(async (options) => {
|
|
111
|
+
const existing = readConfig();
|
|
112
|
+
if (existing && existing.apiKey && !options.force) {
|
|
113
|
+
const apiUrl = resolveApiUrl();
|
|
114
|
+
const valid = await isKeyValid(apiUrl, existing.apiKey);
|
|
115
|
+
if (valid) {
|
|
116
|
+
console.log(`Already logged in as ${existing.email}. Use --force to re-authenticate.`);
|
|
117
|
+
process.exit(0);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
console.log('Stored credentials are invalid — re-authenticating...');
|
|
121
|
+
}
|
|
122
|
+
const apiUrl = resolveApiUrl();
|
|
123
|
+
if (options.local) {
|
|
124
|
+
await loginLocal(apiUrl);
|
|
125
|
+
process.exit(0);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
let port;
|
|
129
|
+
try {
|
|
130
|
+
port = await findAvailablePort();
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
console.error(chalk.red(err.message));
|
|
134
|
+
process.exit(1);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const spinner = ora('Opening browser for authentication...').start();
|
|
138
|
+
try {
|
|
139
|
+
const { default: open } = await import('open');
|
|
140
|
+
const frontendUrl = resolveFrontendUrl();
|
|
141
|
+
const loginUrl = `${frontendUrl}/auth/cli-login?port=${port}`;
|
|
142
|
+
await open(loginUrl);
|
|
143
|
+
const payload = await waitForOAuthCallback(port, spinner);
|
|
144
|
+
const existingConfig = readConfig();
|
|
145
|
+
const config = {
|
|
146
|
+
...payload,
|
|
147
|
+
apiUrl,
|
|
148
|
+
frontendUrl,
|
|
149
|
+
...(existingConfig?.localPath ? { localPath: existingConfig.localPath } : {}),
|
|
150
|
+
};
|
|
151
|
+
writeConfig(config);
|
|
152
|
+
spinner.succeed(chalk.green(`Logged in as ${config.email} (project: ${config.projectName})`));
|
|
153
|
+
process.exit(0);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
spinner.fail(chalk.red(err.message));
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGnC,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAWrD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { clearConfig } from '../lib/config.js';
|
|
2
|
+
export function registerLogout(program) {
|
|
3
|
+
program
|
|
4
|
+
.command('logout')
|
|
5
|
+
.description('Clear saved Conductor credentials')
|
|
6
|
+
.addHelpText('after', `
|
|
7
|
+
Examples:
|
|
8
|
+
conductor logout`)
|
|
9
|
+
.action(() => {
|
|
10
|
+
clearConfig();
|
|
11
|
+
console.log('Logged out.');
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,mCAAmC,CAAC;SAChD,WAAW,CAAC,OAAO,EAAE;;mBAEP,CAAC;SACf,MAAM,CAAC,GAAG,EAAE;QACX,WAAW,EAAE,CAAA;QACb,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAQlD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function registerMcp(program) {
|
|
2
|
+
program
|
|
3
|
+
.command('mcp')
|
|
4
|
+
.description('Start the MCP stdio server for Claude Code integration')
|
|
5
|
+
.action(async () => {
|
|
6
|
+
const { runMcpServer } = await import('../mcp/index.js');
|
|
7
|
+
await runMcpServer();
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAC,OAAgB;IAC1C,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,wDAAwD,CAAC;SACrE,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAA;QACxD,MAAM,YAAY,EAAE,CAAA;IACtB,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export declare const PID_FILE: string;
|
|
3
|
+
export declare const LOG_FILE: string;
|
|
4
|
+
/** Returns true if the daemon started and stayed alive, false otherwise. */
|
|
5
|
+
export declare function startDaemon(): Promise<boolean>;
|
|
6
|
+
export declare function registerStart(program: Command): void;
|
|
7
|
+
//# sourceMappingURL=start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC,eAAO,MAAM,QAAQ,QAAyC,CAAA;AAC9D,eAAO,MAAM,QAAQ,QAAyC,CAAA;AAoB9D,4EAA4E;AAC5E,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CA0CpD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAQpD"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as os from 'os';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { readConfig } from '../lib/config.js';
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const CONDUCTOR_DIR = path.join(os.homedir(), '.conductor');
|
|
9
|
+
export const PID_FILE = path.join(CONDUCTOR_DIR, 'daemon.pid');
|
|
10
|
+
export const LOG_FILE = path.join(CONDUCTOR_DIR, 'daemon.log');
|
|
11
|
+
function isProcessAlive(pid) {
|
|
12
|
+
try {
|
|
13
|
+
process.kill(pid, 0);
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function tailLog(lines = 5) {
|
|
21
|
+
try {
|
|
22
|
+
const content = fs.readFileSync(LOG_FILE, 'utf8');
|
|
23
|
+
return content.trim().split('\n').slice(-lines).join('\n');
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return '(no log output)';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Returns true if the daemon started and stayed alive, false otherwise. */
|
|
30
|
+
export async function startDaemon() {
|
|
31
|
+
const config = readConfig();
|
|
32
|
+
if (!config) {
|
|
33
|
+
console.error('Not authenticated — run conductor login');
|
|
34
|
+
process.exit(78);
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (fs.existsSync(PID_FILE)) {
|
|
38
|
+
const pid = parseInt(fs.readFileSync(PID_FILE, 'utf8').trim(), 10);
|
|
39
|
+
if (isProcessAlive(pid)) {
|
|
40
|
+
console.log(`Daemon already running (PID ${pid})`);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
fs.unlinkSync(PID_FILE);
|
|
44
|
+
}
|
|
45
|
+
fs.mkdirSync(CONDUCTOR_DIR, { recursive: true });
|
|
46
|
+
const logStream = fs.openSync(LOG_FILE, 'a');
|
|
47
|
+
const watcherPath = path.join(__dirname, '..', 'daemon', 'watcher.js');
|
|
48
|
+
const daemon = spawn(process.execPath, [watcherPath], {
|
|
49
|
+
detached: true,
|
|
50
|
+
stdio: ['ignore', logStream, logStream],
|
|
51
|
+
});
|
|
52
|
+
const pid = daemon.pid;
|
|
53
|
+
fs.writeFileSync(PID_FILE, String(pid), 'utf8');
|
|
54
|
+
daemon.unref();
|
|
55
|
+
// Wait briefly to catch immediate crashes
|
|
56
|
+
await new Promise(resolve => setTimeout(resolve, 600));
|
|
57
|
+
if (!isProcessAlive(pid)) {
|
|
58
|
+
fs.unlinkSync(PID_FILE);
|
|
59
|
+
console.error(`Daemon failed to start. Last log output:\n${tailLog()}`);
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
console.log(`Daemon started (PID ${pid})`);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
export function registerStart(program) {
|
|
66
|
+
program
|
|
67
|
+
.command('start')
|
|
68
|
+
.description('Start the file watcher daemon')
|
|
69
|
+
.addHelpText('after', `
|
|
70
|
+
Examples:
|
|
71
|
+
conductor start`)
|
|
72
|
+
.action(async () => { await startDaemon(); });
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export declare function formatRelativeTime(dateStr: string): string;
|
|
3
|
+
export declare const DAEMON_LOG_PATH: string;
|
|
4
|
+
export declare function isDaemonRunning(): boolean;
|
|
5
|
+
export declare function getDaemonPid(): number | null;
|
|
6
|
+
export declare function getQueueCount(): number;
|
|
7
|
+
export declare function getLogFileSizeMb(): number | null;
|
|
8
|
+
export declare function registerStatus(program: Command): void;
|
|
9
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAM1D;AAKD,eAAO,MAAM,eAAe,QAAyC,CAAA;AAErE,wBAAgB,eAAe,IAAI,OAAO,CAiBzC;AAED,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAU5C;AAED,wBAAgB,aAAa,IAAI,MAAM,CAStC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAOhD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoDrD"}
|