upfynai-code 2.9.0 → 2.9.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 +91 -66
- package/client/dist/api-docs.html +838 -0
- package/client/dist/assets/AppContent-BXZDeSIC.js +545 -0
- package/client/dist/assets/CanvasFullScreen-mnpCnLZ9.js +1 -0
- package/client/dist/assets/CanvasWorkspace-4CqmjAVQ.js +163 -0
- package/client/dist/assets/DashboardPanel-zFIFlw56.js +1 -0
- package/client/dist/assets/FileTree-B0c_GaB3.js +1 -0
- package/client/dist/assets/GitPanel-DUP4zVU4.js +2 -0
- package/client/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/client/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/client/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/client/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/client/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/client/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/client/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/client/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/client/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/client/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/client/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/client/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/client/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/client/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/client/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/client/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/client/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/client/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/client/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/client/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/client/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/client/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/client/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/client/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/client/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/client/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/client/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/client/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/client/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/client/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/client/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/client/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/client/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/client/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/client/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/client/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/client/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/client/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/client/dist/assets/LoginModal-BRycfsyD.js +13 -0
- package/client/dist/assets/MarkdownPreview-DHmk3qzu.js +1 -0
- package/client/dist/assets/MermaidBlock-BuBc_G-F.js +2 -0
- package/client/dist/assets/Onboarding-BcnaZZ0o.js +1 -0
- package/client/dist/assets/PreviewPanel-CqCa92Tf.js +32 -0
- package/client/dist/assets/SetupForm-S0g6u5yT.js +1 -0
- package/client/dist/assets/WorkflowsPanel-CouH9JDO.js +1 -0
- package/client/dist/assets/index-BFuqS0tY.css +1 -0
- package/client/dist/assets/index-CNDcVl2g.js +68 -0
- package/client/dist/assets/pdf-CE_K4jFx.js +12 -0
- package/client/dist/assets/vendor-canvas-BZV40eAE.css +1 -0
- package/client/dist/assets/vendor-canvas-D39yWul6.js +49 -0
- package/client/dist/assets/vendor-codemirror-CbtmxxaB.js +35 -0
- package/client/dist/assets/vendor-diff-DNQpbhrT.js +69 -0
- package/client/dist/assets/vendor-i18n-DCFGyhQR.js +1 -0
- package/client/dist/assets/vendor-icons-BaD0x9SL.js +711 -0
- package/client/dist/assets/vendor-markdown-CimbIo6Y.js +296 -0
- package/client/dist/assets/vendor-mermaid-CH7SGc99.js +2556 -0
- package/client/dist/assets/vendor-react-96lCPsRK.js +67 -0
- package/client/dist/assets/vendor-syntax-DuHI9Ok6.js +16 -0
- package/client/dist/assets/vendor-xterm-CZq1hqo1.js +66 -0
- package/client/dist/assets/vendor-xterm-qxJ8_QYu.css +32 -0
- package/client/dist/clear-cache.html +85 -0
- package/client/dist/convert-icons.md +53 -0
- package/client/dist/favicon.png +0 -0
- package/client/dist/favicon.svg +5 -0
- package/client/dist/generate-icons.js +49 -0
- package/client/dist/icons/claude-ai-icon.svg +1 -0
- package/client/dist/icons/codex-white.svg +3 -0
- package/client/dist/icons/codex.svg +3 -0
- package/client/dist/icons/cursor-white.svg +12 -0
- package/client/dist/icons/cursor.svg +1 -0
- package/client/dist/icons/icon-128x128.png +0 -0
- package/client/dist/icons/icon-128x128.svg +5 -0
- package/client/dist/icons/icon-144x144.png +0 -0
- package/client/dist/icons/icon-144x144.svg +5 -0
- package/client/dist/icons/icon-152x152.png +0 -0
- package/client/dist/icons/icon-152x152.svg +5 -0
- package/client/dist/icons/icon-192x192.png +0 -0
- package/client/dist/icons/icon-192x192.svg +5 -0
- package/client/dist/icons/icon-384x384.png +0 -0
- package/client/dist/icons/icon-384x384.svg +5 -0
- package/client/dist/icons/icon-512x512.png +0 -0
- package/client/dist/icons/icon-512x512.svg +5 -0
- package/client/dist/icons/icon-72x72.png +0 -0
- package/client/dist/icons/icon-72x72.svg +5 -0
- package/client/dist/icons/icon-96x96.png +0 -0
- package/client/dist/icons/icon-96x96.svg +5 -0
- package/client/dist/icons/icon-template.svg +5 -0
- package/client/dist/index.html +119 -0
- package/client/dist/logo-128.png +0 -0
- package/client/dist/logo-256.png +0 -0
- package/client/dist/logo-32.png +0 -0
- package/client/dist/logo-512.png +0 -0
- package/client/dist/logo-64.png +0 -0
- package/client/dist/logo.svg +14 -0
- package/client/dist/manifest.json +61 -0
- package/client/dist/mcp-docs.html +108 -0
- package/client/dist/offline.html +84 -0
- package/client/dist/screenshots/cli-selection.png +0 -0
- package/client/dist/screenshots/desktop-main.png +0 -0
- package/client/dist/screenshots/mobile-chat.png +0 -0
- package/client/dist/screenshots/tools-modal.png +0 -0
- package/client/dist/sw.js +82 -0
- package/commands/upfynai-connect.md +59 -0
- package/commands/upfynai-disconnect.md +31 -0
- package/commands/upfynai-doctor.md +99 -0
- package/commands/upfynai-export.md +49 -0
- package/commands/upfynai-local.md +82 -0
- package/commands/upfynai-status.md +75 -0
- package/commands/upfynai-stop.md +49 -0
- package/commands/upfynai-uninstall.md +58 -0
- package/commands/upfynai.md +69 -0
- package/package.json +143 -82
- package/scripts/build-client.js +17 -0
- package/scripts/fix-node-pty.js +67 -0
- package/scripts/install-commands.js +78 -0
- package/server/agent-loop.js +242 -0
- package/server/auto-compact.js +99 -0
- package/server/claude-sdk.js +797 -0
- package/server/cli-ui.js +785 -0
- package/server/cli.js +596 -0
- package/server/constants/config.js +31 -0
- package/server/cursor-cli.js +270 -0
- package/server/database/auth.db +0 -0
- package/server/database/db.js +1391 -0
- package/server/database/init.sql +70 -0
- package/server/index.js +3799 -0
- package/server/load-env.js +26 -0
- package/server/mcp-server.js +621 -0
- package/server/middleware/auth.js +176 -0
- package/server/middleware/relayHelpers.js +44 -0
- package/server/middleware/sandboxRouter.js +174 -0
- package/server/openai-codex.js +403 -0
- package/server/openrouter.js +137 -0
- package/server/projects.js +1807 -0
- package/server/provider-factory.js +174 -0
- package/server/relay-client.js +379 -0
- package/server/routes/agent.js +1226 -0
- package/server/routes/auth.js +554 -0
- package/server/routes/canvas.js +53 -0
- package/server/routes/cli-auth.js +263 -0
- package/server/routes/codex.js +396 -0
- package/server/routes/commands.js +707 -0
- package/server/routes/composio.js +176 -0
- package/server/routes/cursor.js +770 -0
- package/server/routes/dashboard.js +295 -0
- package/server/routes/git.js +1208 -0
- package/server/routes/keys.js +34 -0
- package/server/routes/mcp-utils.js +48 -0
- package/server/routes/mcp.js +661 -0
- package/server/routes/payments.js +227 -0
- package/server/routes/projects.js +655 -0
- package/server/routes/sessions.js +146 -0
- package/server/routes/settings.js +261 -0
- package/server/routes/taskmaster.js +1928 -0
- package/server/routes/user.js +106 -0
- package/server/routes/vapi-chat.js +624 -0
- package/server/routes/voice.js +235 -0
- package/server/routes/webhooks.js +166 -0
- package/server/routes/workflows.js +312 -0
- package/server/sandbox.js +120 -0
- package/server/services/composio.js +204 -0
- package/server/services/sessionRegistry.js +139 -0
- package/server/services/whisperService.js +84 -0
- package/server/services/workflowScheduler.js +206 -0
- package/server/tests/relay-flow.test.js +570 -0
- package/server/tests/sessions.test.js +259 -0
- package/server/utils/commandParser.js +303 -0
- package/server/utils/email.js +61 -0
- package/server/utils/gitConfig.js +24 -0
- package/server/utils/mcp-detector.js +198 -0
- package/server/utils/taskmaster-websocket.js +129 -0
- package/shared/integrationCatalog.d.ts +12 -0
- package/shared/integrationCatalog.js +172 -0
- package/shared/modelConstants.js +96 -0
- package/bin/cli.js +0 -97
- package/dist/agents/claude.js +0 -229
- package/dist/agents/codex.js +0 -48
- package/dist/agents/cursor.js +0 -48
- package/dist/agents/detect.js +0 -51
- package/dist/agents/exec.js +0 -31
- package/dist/agents/files.js +0 -105
- package/dist/agents/git.js +0 -18
- package/dist/agents/gitagent.js +0 -67
- package/dist/agents/index.js +0 -88
- package/dist/agents/shell.js +0 -38
- package/dist/agents/utils.js +0 -136
- package/scripts/postinstall.js +0 -9
- package/scripts/prepublish.js +0 -58
- package/src/animation.js +0 -228
- package/src/auth.js +0 -122
- package/src/config.js +0 -40
- package/src/connect.js +0 -416
- package/src/launch.js +0 -78
- package/src/mcp.js +0 -57
- package/src/permissions.js +0 -140
- package/src/persistent-shell.js +0 -261
- package/src/server.js +0 -54
- /package/{dist → shared}/gitagent/index.js +0 -0
- /package/{dist → shared}/gitagent/parser.js +0 -0
- /package/{dist → shared}/gitagent/prompt-builder.js +0 -0
package/bin/cli.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { readFileSync } from 'fs';
|
|
5
|
-
import { dirname, join } from 'path';
|
|
6
|
-
import { fileURLToPath } from 'url';
|
|
7
|
-
import { login, logout, status } from '../src/auth.js';
|
|
8
|
-
import { openHosted, startLocal } from '../src/launch.js';
|
|
9
|
-
import { connect } from '../src/connect.js';
|
|
10
|
-
import { mcp } from '../src/mcp.js';
|
|
11
|
-
import { readConfig, writeConfig, clearConfig, DEFAULTS, displayUrl } from '../src/config.js';
|
|
12
|
-
import chalk from 'chalk';
|
|
13
|
-
|
|
14
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
-
const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
|
|
16
|
-
|
|
17
|
-
const program = new Command();
|
|
18
|
-
|
|
19
|
-
program
|
|
20
|
-
.name('upfynai-code')
|
|
21
|
-
.description('Launch Upfyn AI coding environment from your terminal')
|
|
22
|
-
.version(pkg.version)
|
|
23
|
-
.option('--local', 'Start a local server instead of opening the hosted app')
|
|
24
|
-
.action(async (options) => {
|
|
25
|
-
if (options.local) {
|
|
26
|
-
await startLocal();
|
|
27
|
-
} else {
|
|
28
|
-
await openHosted();
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
program
|
|
33
|
-
.command('login')
|
|
34
|
-
.description('Authenticate with your Upfyn account')
|
|
35
|
-
.option('--server <url>', 'Server URL to authenticate against')
|
|
36
|
-
.action(async (options) => {
|
|
37
|
-
await login(options);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
program
|
|
41
|
-
.command('logout')
|
|
42
|
-
.description('Clear saved credentials')
|
|
43
|
-
.action(async () => {
|
|
44
|
-
await logout();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
program
|
|
48
|
-
.command('status')
|
|
49
|
-
.description('Show current auth status and config')
|
|
50
|
-
.action(async () => {
|
|
51
|
-
await status();
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
program
|
|
55
|
-
.command('connect')
|
|
56
|
-
.description('Connect local machine to the remote server (bridges Claude Code, shell, files, git)')
|
|
57
|
-
.option('--server <url>', 'Server URL to connect to')
|
|
58
|
-
.option('--key <token>', 'Connection token — get from Settings > Keys & Connect')
|
|
59
|
-
.action(async (options) => {
|
|
60
|
-
await connect(options);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
program
|
|
64
|
-
.command('mcp')
|
|
65
|
-
.description('Show MCP integration config for Claude / Cursor')
|
|
66
|
-
.option('--server <url>', 'Server URL')
|
|
67
|
-
.option('--key <token>', 'Relay token')
|
|
68
|
-
.action(async (options) => {
|
|
69
|
-
await mcp(options);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
program
|
|
73
|
-
.command('config')
|
|
74
|
-
.description('View or update CLI configuration')
|
|
75
|
-
.option('--server <url>', 'Set the server URL')
|
|
76
|
-
.option('--reset', 'Reset config to defaults')
|
|
77
|
-
.action((options) => {
|
|
78
|
-
if (options.reset) {
|
|
79
|
-
clearConfig();
|
|
80
|
-
console.log(chalk.green('\n Config reset to defaults.\n'));
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
if (options.server) {
|
|
84
|
-
const cleaned = options.server.replace(/\/+$/, '');
|
|
85
|
-
writeConfig({ serverUrl: cleaned });
|
|
86
|
-
console.log(chalk.green(`\n Server set to: ${displayUrl(cleaned)}\n`));
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
// Show current config
|
|
90
|
-
const config = readConfig();
|
|
91
|
-
console.log(chalk.bold('\n Upfyn Code — Config\n'));
|
|
92
|
-
console.log(` Server: ${chalk.cyan(displayUrl(config.serverUrl))}`);
|
|
93
|
-
console.log(` Local port: ${chalk.cyan(config.localPort)}`);
|
|
94
|
-
console.log(` Logged in: ${config.token ? chalk.green('Yes') : chalk.yellow('No')}\n`);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
program.parse();
|
package/dist/agents/claude.js
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Claude Agent
|
|
3
|
-
* Handles: claude-query, claude-task-query
|
|
4
|
-
*
|
|
5
|
-
* These are STREAMING actions — they use ctx.stream() to send chunks
|
|
6
|
-
* and return a Promise that resolves when the process completes.
|
|
7
|
-
*
|
|
8
|
-
* Three modes:
|
|
9
|
-
* - sdk (connect.js default) — full SDK streaming with rich messages (tool_use, text, result)
|
|
10
|
-
* - simple --print (relay-client.js) — basic stdout streaming
|
|
11
|
-
*
|
|
12
|
-
* The caller chooses the mode via ctx.streamMode ('structured' | 'simple').
|
|
13
|
-
* 'structured' now maps to SDK mode for rich message forwarding.
|
|
14
|
-
*/
|
|
15
|
-
import { query } from '@anthropic-ai/claude-agent-sdk';
|
|
16
|
-
import { spawn } from 'child_process';
|
|
17
|
-
import os from 'os';
|
|
18
|
-
|
|
19
|
-
export default {
|
|
20
|
-
name: 'claude',
|
|
21
|
-
actions: {
|
|
22
|
-
'claude-query': async (params, ctx) => {
|
|
23
|
-
const { command, options } = params;
|
|
24
|
-
const mode = ctx.streamMode || 'structured';
|
|
25
|
-
|
|
26
|
-
if (mode === 'simple') {
|
|
27
|
-
const resolveBinary = ctx.resolveBinary || ((name) => name);
|
|
28
|
-
return runSimpleClaudeQuery(command, options, ctx, resolveBinary);
|
|
29
|
-
}
|
|
30
|
-
return runSDKClaudeQuery(command, options, ctx);
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
'claude-task-query': async (params, ctx) => {
|
|
34
|
-
const { command, options } = params;
|
|
35
|
-
return runSDKClaudeTaskQuery(command, options, ctx);
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Build SDK options from relay command options.
|
|
42
|
-
* Maps the relay format to SDK Options type.
|
|
43
|
-
*/
|
|
44
|
-
function buildSDKOptions(options = {}) {
|
|
45
|
-
const sdkOptions = {
|
|
46
|
-
cwd: options.projectPath || os.homedir(),
|
|
47
|
-
systemPrompt: { type: 'preset', preset: 'claude_code' },
|
|
48
|
-
settingSources: ['project', 'user', 'local'],
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
if (options.sessionId) {
|
|
52
|
-
sdkOptions.resume = options.sessionId;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (options.model) {
|
|
56
|
-
sdkOptions.model = options.model;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (options.maxBudgetUsd) {
|
|
60
|
-
sdkOptions.maxBudgetUsd = options.maxBudgetUsd;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (options.permissionMode && options.permissionMode !== 'default') {
|
|
64
|
-
sdkOptions.permissionMode = options.permissionMode;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (options.allowedTools && options.allowedTools.length > 0) {
|
|
68
|
-
sdkOptions.allowedTools = options.allowedTools;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (options.disallowedTools && options.disallowedTools.length > 0) {
|
|
72
|
-
sdkOptions.disallowedTools = options.disallowedTools;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (options.maxTurns) {
|
|
76
|
-
sdkOptions.maxTurns = options.maxTurns;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Pass through tools preset to make all Claude Code tools available
|
|
80
|
-
sdkOptions.tools = { type: 'preset', preset: 'claude_code' };
|
|
81
|
-
|
|
82
|
-
return sdkOptions;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* SDK-based structured streaming mode.
|
|
87
|
-
* Forwards rich SDK messages (tool_use, tool_result, text, system, result)
|
|
88
|
-
* through ctx.stream() for the relay to forward to the frontend.
|
|
89
|
-
*/
|
|
90
|
-
async function runSDKClaudeQuery(command, options, ctx) {
|
|
91
|
-
const sdkOptions = buildSDKOptions(options);
|
|
92
|
-
|
|
93
|
-
// Set stream-close timeout for interactive tools
|
|
94
|
-
const prevStreamTimeout = process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT;
|
|
95
|
-
process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT = '300000';
|
|
96
|
-
|
|
97
|
-
let queryInstance;
|
|
98
|
-
try {
|
|
99
|
-
queryInstance = query({
|
|
100
|
-
prompt: command || '',
|
|
101
|
-
options: sdkOptions,
|
|
102
|
-
});
|
|
103
|
-
} finally {
|
|
104
|
-
// Restore immediately — Query constructor already captured the value
|
|
105
|
-
if (prevStreamTimeout !== undefined) {
|
|
106
|
-
process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT = prevStreamTimeout;
|
|
107
|
-
} else {
|
|
108
|
-
delete process.env.CLAUDE_CODE_STREAM_CLOSE_TIMEOUT;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Track the query instance for abort support (uses .interrupt() instead of .kill())
|
|
113
|
-
if (ctx.trackProcess) {
|
|
114
|
-
ctx.trackProcess(ctx.requestId, { instance: queryInstance, action: 'claude-query' });
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
let capturedSessionId = null;
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
for await (const message of queryInstance) {
|
|
121
|
-
// Capture session ID from first message that has one
|
|
122
|
-
if (message.session_id && !capturedSessionId) {
|
|
123
|
-
capturedSessionId = message.session_id;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Forward the full SDK message — the backend routeViaRelay() will
|
|
127
|
-
// detect 'claude-sdk-message' type and forward directly to frontend,
|
|
128
|
-
// matching the same format as queryClaudeSDK() in claude-sdk.js
|
|
129
|
-
ctx.stream({
|
|
130
|
-
type: 'claude-sdk-message',
|
|
131
|
-
data: message,
|
|
132
|
-
sessionId: capturedSessionId,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return { exitCode: 0, sessionId: capturedSessionId };
|
|
137
|
-
} catch (error) {
|
|
138
|
-
ctx.stream({ type: 'claude-error', content: error.message || 'SDK query failed' });
|
|
139
|
-
return { exitCode: 1, sessionId: capturedSessionId };
|
|
140
|
-
} finally {
|
|
141
|
-
if (ctx.untrackProcess) ctx.untrackProcess(ctx.requestId);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* SDK-based sub-agent for read-only research tasks.
|
|
147
|
-
* Restricts tools to read-only operations.
|
|
148
|
-
*/
|
|
149
|
-
async function runSDKClaudeTaskQuery(command, options, ctx) {
|
|
150
|
-
const sdkOptions = buildSDKOptions(options);
|
|
151
|
-
|
|
152
|
-
// Restrict to read-only tools
|
|
153
|
-
sdkOptions.allowedTools = ['View', 'Glob', 'Grep', 'LS', 'Read'];
|
|
154
|
-
|
|
155
|
-
let queryInstance;
|
|
156
|
-
try {
|
|
157
|
-
queryInstance = query({
|
|
158
|
-
prompt: command || '',
|
|
159
|
-
options: sdkOptions,
|
|
160
|
-
});
|
|
161
|
-
} catch (error) {
|
|
162
|
-
ctx.stream({ type: 'claude-error', content: error.message || 'SDK task query failed' });
|
|
163
|
-
return { exitCode: 1 };
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (ctx.trackProcess) {
|
|
167
|
-
ctx.trackProcess(ctx.requestId, { instance: queryInstance, action: 'claude-task-query' });
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
let capturedSessionId = null;
|
|
171
|
-
|
|
172
|
-
try {
|
|
173
|
-
for await (const message of queryInstance) {
|
|
174
|
-
if (message.session_id && !capturedSessionId) {
|
|
175
|
-
capturedSessionId = message.session_id;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
ctx.stream({
|
|
179
|
-
type: 'claude-sdk-message',
|
|
180
|
-
data: message,
|
|
181
|
-
sessionId: capturedSessionId,
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return { exitCode: 0, sessionId: capturedSessionId };
|
|
186
|
-
} catch (error) {
|
|
187
|
-
ctx.stream({ type: 'claude-error', content: error.message || 'SDK task query failed' });
|
|
188
|
-
return { exitCode: 1, sessionId: capturedSessionId };
|
|
189
|
-
} finally {
|
|
190
|
-
if (ctx.untrackProcess) ctx.untrackProcess(ctx.requestId);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Simple streaming mode (--print).
|
|
196
|
-
* Just pipes stdout/stderr chunks. Kept for backward compat with relay-client.js.
|
|
197
|
-
*/
|
|
198
|
-
function runSimpleClaudeQuery(command, options, ctx, resolveBinary) {
|
|
199
|
-
return new Promise((resolve) => {
|
|
200
|
-
const args = ['--print'];
|
|
201
|
-
if (options?.sessionId) args.push('--continue', options.sessionId);
|
|
202
|
-
|
|
203
|
-
const proc = spawn(resolveBinary('claude'), [...args, command || ''], {
|
|
204
|
-
shell: true,
|
|
205
|
-
cwd: options?.projectPath || os.homedir(),
|
|
206
|
-
env: process.env,
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
if (ctx.trackProcess) ctx.trackProcess(ctx.requestId, { proc, action: 'claude-query' });
|
|
210
|
-
|
|
211
|
-
proc.stdout.on('data', (chunk) => {
|
|
212
|
-
ctx.stream({ type: 'claude-response', content: chunk.toString() });
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
proc.stderr.on('data', (chunk) => {
|
|
216
|
-
ctx.stream({ type: 'claude-error', content: chunk.toString() });
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
proc.on('close', (code) => {
|
|
220
|
-
if (ctx.untrackProcess) ctx.untrackProcess(ctx.requestId);
|
|
221
|
-
resolve({ exitCode: code });
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
proc.on('error', () => {
|
|
225
|
-
if (ctx.untrackProcess) ctx.untrackProcess(ctx.requestId);
|
|
226
|
-
resolve({ exitCode: 1 });
|
|
227
|
-
});
|
|
228
|
-
});
|
|
229
|
-
}
|
package/dist/agents/codex.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Codex Agent
|
|
3
|
-
* Handles: codex-query
|
|
4
|
-
* Spawns the OpenAI Codex CLI and streams output.
|
|
5
|
-
*/
|
|
6
|
-
import { spawn } from 'child_process';
|
|
7
|
-
import os from 'os';
|
|
8
|
-
|
|
9
|
-
export default {
|
|
10
|
-
name: 'codex',
|
|
11
|
-
actions: {
|
|
12
|
-
'codex-query': async (params, ctx) => {
|
|
13
|
-
const { command, options } = params;
|
|
14
|
-
const resolveBinary = ctx.resolveBinary || ((name) => name);
|
|
15
|
-
|
|
16
|
-
return new Promise((resolve) => {
|
|
17
|
-
const args = ['--quiet'];
|
|
18
|
-
if (options?.model) args.push('--model', options.model);
|
|
19
|
-
|
|
20
|
-
const proc = spawn(resolveBinary('codex'), [...args, command || ''], {
|
|
21
|
-
shell: true,
|
|
22
|
-
cwd: options?.projectPath || options?.cwd || os.homedir(),
|
|
23
|
-
env: process.env,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
if (ctx.trackProcess) ctx.trackProcess(ctx.requestId, { proc, action: 'codex-query' });
|
|
27
|
-
|
|
28
|
-
proc.stdout.on('data', (chunk) => {
|
|
29
|
-
ctx.stream({ type: 'codex-response', content: chunk.toString() });
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
proc.stderr.on('data', (chunk) => {
|
|
33
|
-
ctx.stream({ type: 'codex-error', content: chunk.toString() });
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
proc.on('close', (code) => {
|
|
37
|
-
if (ctx.untrackProcess) ctx.untrackProcess(ctx.requestId);
|
|
38
|
-
resolve({ exitCode: code });
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
proc.on('error', () => {
|
|
42
|
-
if (ctx.untrackProcess) ctx.untrackProcess(ctx.requestId);
|
|
43
|
-
resolve({ exitCode: 1 });
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
};
|
package/dist/agents/cursor.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cursor Agent
|
|
3
|
-
* Handles: cursor-query
|
|
4
|
-
* Spawns the Cursor Agent CLI and streams output.
|
|
5
|
-
*/
|
|
6
|
-
import { spawn } from 'child_process';
|
|
7
|
-
import os from 'os';
|
|
8
|
-
|
|
9
|
-
export default {
|
|
10
|
-
name: 'cursor',
|
|
11
|
-
actions: {
|
|
12
|
-
'cursor-query': async (params, ctx) => {
|
|
13
|
-
const { command, options } = params;
|
|
14
|
-
const resolveBinary = ctx.resolveBinary || ((name) => name);
|
|
15
|
-
|
|
16
|
-
return new Promise((resolve) => {
|
|
17
|
-
const args = [];
|
|
18
|
-
if (options?.model) args.push('--model', options.model);
|
|
19
|
-
|
|
20
|
-
const proc = spawn(resolveBinary('cursor-agent'), [...args, command || ''], {
|
|
21
|
-
shell: true,
|
|
22
|
-
cwd: options?.projectPath || options?.cwd || os.homedir(),
|
|
23
|
-
env: process.env,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
if (ctx.trackProcess) ctx.trackProcess(ctx.requestId, { proc, action: 'cursor-query' });
|
|
27
|
-
|
|
28
|
-
proc.stdout.on('data', (chunk) => {
|
|
29
|
-
ctx.stream({ type: 'cursor-response', content: chunk.toString() });
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
proc.stderr.on('data', (chunk) => {
|
|
33
|
-
ctx.stream({ type: 'cursor-error', content: chunk.toString() });
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
proc.on('close', (code) => {
|
|
37
|
-
if (ctx.untrackProcess) ctx.untrackProcess(ctx.requestId);
|
|
38
|
-
resolve({ exitCode: code });
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
proc.on('error', () => {
|
|
42
|
-
if (ctx.untrackProcess) ctx.untrackProcess(ctx.requestId);
|
|
43
|
-
resolve({ exitCode: 1 });
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
};
|
package/dist/agents/detect.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Detect Agent
|
|
3
|
-
* Handles: detect-agents
|
|
4
|
-
* Checks which AI CLI agents are installed on the local machine.
|
|
5
|
-
*/
|
|
6
|
-
import { execSync } from 'child_process';
|
|
7
|
-
import fs from 'fs';
|
|
8
|
-
import path from 'path';
|
|
9
|
-
|
|
10
|
-
const AGENT_DEFINITIONS = [
|
|
11
|
-
{ name: 'claude', binary: 'claude', label: 'Claude Code' },
|
|
12
|
-
{ name: 'codex', binary: 'codex', label: 'OpenAI Codex' },
|
|
13
|
-
{ name: 'cursor', binary: 'cursor-agent', label: 'Cursor Agent' },
|
|
14
|
-
];
|
|
15
|
-
|
|
16
|
-
export default {
|
|
17
|
-
name: 'detect',
|
|
18
|
-
actions: {
|
|
19
|
-
'detect-agents': async (params, ctx) => {
|
|
20
|
-
const isWindows = process.platform === 'win32';
|
|
21
|
-
const whichCmd = isWindows ? 'where' : 'which';
|
|
22
|
-
const localBinDir = ctx.localBinDir || null;
|
|
23
|
-
|
|
24
|
-
const agents = {};
|
|
25
|
-
for (const agent of AGENT_DEFINITIONS) {
|
|
26
|
-
try {
|
|
27
|
-
const result = execSync(`${whichCmd} ${agent.binary}`, {
|
|
28
|
-
stdio: 'pipe',
|
|
29
|
-
timeout: 5000,
|
|
30
|
-
}).toString().trim();
|
|
31
|
-
agents[agent.name] = {
|
|
32
|
-
installed: true,
|
|
33
|
-
path: result.split('\n')[0].trim(),
|
|
34
|
-
label: agent.label,
|
|
35
|
-
};
|
|
36
|
-
} catch {
|
|
37
|
-
// Check local node_modules/.bin as fallback
|
|
38
|
-
if (localBinDir) {
|
|
39
|
-
const localPath = path.join(localBinDir, agent.binary + (isWindows ? '.cmd' : ''));
|
|
40
|
-
if (fs.existsSync(localPath)) {
|
|
41
|
-
agents[agent.name] = { installed: true, path: localPath, label: agent.label };
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
agents[agent.name] = { installed: false, label: agent.label };
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return { agents };
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
};
|
package/dist/agents/exec.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Exec Agent
|
|
3
|
-
* Handles: exec (arbitrary command execution)
|
|
4
|
-
*/
|
|
5
|
-
import { execSync } from 'child_process';
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
name: 'exec',
|
|
9
|
-
actions: {
|
|
10
|
-
'exec': async (params) => {
|
|
11
|
-
const { command, timeout: cmdTimeout = 60000, cwd } = params;
|
|
12
|
-
if (!command) throw new Error('No command provided');
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
const output = execSync(command, {
|
|
16
|
-
encoding: 'utf8',
|
|
17
|
-
timeout: cmdTimeout,
|
|
18
|
-
cwd: cwd || process.cwd(),
|
|
19
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
20
|
-
});
|
|
21
|
-
return { output, exitCode: 0 };
|
|
22
|
-
} catch (execErr) {
|
|
23
|
-
return {
|
|
24
|
-
output: execErr.stdout || '',
|
|
25
|
-
stderr: execErr.stderr || '',
|
|
26
|
-
exitCode: execErr.status || 1,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
};
|
package/dist/agents/files.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* File System Agent
|
|
3
|
-
* Handles: file-read, file-write, file-tree, browse-dirs, validate-path, create-folder
|
|
4
|
-
*/
|
|
5
|
-
import { promises as fsPromises } from 'fs';
|
|
6
|
-
import os from 'os';
|
|
7
|
-
import path from 'path';
|
|
8
|
-
import {
|
|
9
|
-
buildFileTree,
|
|
10
|
-
resolveTildePath,
|
|
11
|
-
isBlockedPath,
|
|
12
|
-
BLOCKED_READ_PATTERNS,
|
|
13
|
-
BLOCKED_WRITE_PATTERNS,
|
|
14
|
-
} from './utils.js';
|
|
15
|
-
|
|
16
|
-
export default {
|
|
17
|
-
name: 'files',
|
|
18
|
-
actions: {
|
|
19
|
-
'file-read': async (params) => {
|
|
20
|
-
let { filePath, encoding } = params;
|
|
21
|
-
if (!filePath || typeof filePath !== 'string') throw new Error('Invalid file path');
|
|
22
|
-
|
|
23
|
-
filePath = resolveTildePath(filePath);
|
|
24
|
-
const normalizedPath = path.resolve(filePath);
|
|
25
|
-
if (isBlockedPath(normalizedPath, BLOCKED_READ_PATTERNS)) throw new Error('Access denied');
|
|
26
|
-
|
|
27
|
-
const content = await fsPromises.readFile(normalizedPath, encoding === 'base64' ? null : 'utf8');
|
|
28
|
-
const result = encoding === 'base64' ? content.toString('base64') : content;
|
|
29
|
-
return { content: result };
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
'file-write': async (params) => {
|
|
33
|
-
let { filePath, content } = params;
|
|
34
|
-
if (!filePath || typeof filePath !== 'string') throw new Error('Invalid file path');
|
|
35
|
-
|
|
36
|
-
filePath = resolveTildePath(filePath);
|
|
37
|
-
const normalizedPath = path.resolve(filePath);
|
|
38
|
-
if (isBlockedPath(normalizedPath, BLOCKED_WRITE_PATTERNS)) throw new Error('Access denied');
|
|
39
|
-
|
|
40
|
-
const parentDir = path.dirname(normalizedPath);
|
|
41
|
-
await fsPromises.mkdir(parentDir, { recursive: true }).catch(() => {});
|
|
42
|
-
await fsPromises.writeFile(normalizedPath, content, 'utf8');
|
|
43
|
-
return { success: true };
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
'file-tree': async (params) => {
|
|
47
|
-
const { dirPath, depth, maxDepth } = params;
|
|
48
|
-
const treeDepth = depth || maxDepth || 3;
|
|
49
|
-
const resolvedDir = dirPath ? path.resolve(dirPath) : process.cwd();
|
|
50
|
-
const tree = await buildFileTree(resolvedDir, treeDepth, 0, {
|
|
51
|
-
maxEntries: 200,
|
|
52
|
-
includeStats: true,
|
|
53
|
-
skipDotfilesAtRoot: true,
|
|
54
|
-
});
|
|
55
|
-
return { files: tree };
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
'browse-dirs': async (params) => {
|
|
59
|
-
const { dirPath: browsePath } = params;
|
|
60
|
-
let targetDir = resolveTildePath(browsePath);
|
|
61
|
-
targetDir = path.resolve(targetDir);
|
|
62
|
-
|
|
63
|
-
let drives = [];
|
|
64
|
-
// On Windows, detect available drives
|
|
65
|
-
if (process.platform === 'win32') {
|
|
66
|
-
try {
|
|
67
|
-
const { execSync } = await import('child_process');
|
|
68
|
-
const wmicOut = execSync('wmic logicaldisk get name', { encoding: 'utf8', timeout: 5000 });
|
|
69
|
-
drives = wmicOut.split('\n')
|
|
70
|
-
.map(l => l.trim())
|
|
71
|
-
.filter(l => /^[A-Z]:$/.test(l))
|
|
72
|
-
.map(d => ({ name: d + '\\', path: d + '\\', type: 'drive' }));
|
|
73
|
-
} catch { /* wmic not available */ }
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const entries = await fsPromises.readdir(targetDir, { withFileTypes: true });
|
|
77
|
-
const dirs = entries
|
|
78
|
-
.filter(e => e.isDirectory() && !e.name.startsWith('.'))
|
|
79
|
-
.map(e => ({ name: e.name, path: path.join(targetDir, e.name), type: 'directory' }))
|
|
80
|
-
.sort((a, b) => a.name.localeCompare(b.name));
|
|
81
|
-
|
|
82
|
-
return { path: targetDir, suggestions: dirs, drives, homedir: os.homedir() };
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
'validate-path': async (params) => {
|
|
86
|
-
const { targetPath } = params;
|
|
87
|
-
const checkPath = resolveTildePath(targetPath);
|
|
88
|
-
const resolved = path.resolve(checkPath);
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
const stats = await fsPromises.stat(resolved);
|
|
92
|
-
return { exists: true, isDirectory: stats.isDirectory(), resolvedPath: resolved };
|
|
93
|
-
} catch {
|
|
94
|
-
return { exists: false, resolvedPath: resolved };
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
'create-folder': async (params) => {
|
|
99
|
-
const { folderPath } = params;
|
|
100
|
-
const mkPath = path.resolve(resolveTildePath(folderPath));
|
|
101
|
-
await fsPromises.mkdir(mkPath, { recursive: true });
|
|
102
|
-
return { success: true, path: mkPath };
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
};
|
package/dist/agents/git.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Git Agent
|
|
3
|
-
* Handles: git-operation
|
|
4
|
-
*/
|
|
5
|
-
import path from 'path';
|
|
6
|
-
import { execCommand } from './utils.js';
|
|
7
|
-
|
|
8
|
-
export default {
|
|
9
|
-
name: 'git',
|
|
10
|
-
actions: {
|
|
11
|
-
'git-operation': async (params) => {
|
|
12
|
-
const { gitCommand, cwd } = params;
|
|
13
|
-
const resolvedCwd = cwd ? path.resolve(cwd) : process.cwd();
|
|
14
|
-
const result = await execCommand('git', [gitCommand], { cwd: resolvedCwd });
|
|
15
|
-
return { stdout: result };
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
};
|
package/dist/agents/gitagent.js
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Gitagent Agent
|
|
3
|
-
* Handles: gitagent-detect, gitagent-parse
|
|
4
|
-
*
|
|
5
|
-
* Relay-compatible actions for detecting and parsing gitagent directory structures
|
|
6
|
-
* on the user's local machine.
|
|
7
|
-
*/
|
|
8
|
-
import fs from 'fs';
|
|
9
|
-
import { promises as fsp } from 'fs';
|
|
10
|
-
import path from 'path';
|
|
11
|
-
import { detectGitagent, parseGitagentRepo } from '../gitagent/parser.js';
|
|
12
|
-
|
|
13
|
-
/** fs-backed helpers injected into the parser */
|
|
14
|
-
async function fsFileExists(filePath) {
|
|
15
|
-
try {
|
|
16
|
-
await fsp.access(filePath, fs.constants.F_OK);
|
|
17
|
-
return true;
|
|
18
|
-
} catch {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async function fsReadFile(filePath) {
|
|
24
|
-
try {
|
|
25
|
-
return await fsp.readFile(filePath, 'utf8');
|
|
26
|
-
} catch {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async function fsListDir(dirPath) {
|
|
32
|
-
try {
|
|
33
|
-
return await fsp.readdir(dirPath);
|
|
34
|
-
} catch {
|
|
35
|
-
return [];
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export default {
|
|
40
|
-
name: 'gitagent',
|
|
41
|
-
actions: {
|
|
42
|
-
/**
|
|
43
|
-
* Lightweight check for agent.yaml existence.
|
|
44
|
-
* @param {{ projectPath: string }} params
|
|
45
|
-
* @returns {{ detected: boolean }}
|
|
46
|
-
*/
|
|
47
|
-
'gitagent-detect': async (params) => {
|
|
48
|
-
const projectPath = params.projectPath;
|
|
49
|
-
if (!projectPath) return { detected: false };
|
|
50
|
-
const detected = await detectGitagent(projectPath, fsFileExists);
|
|
51
|
-
return { detected };
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Full parse — returns the complete GitagentDefinition as JSON.
|
|
56
|
-
* @param {{ projectPath: string }} params
|
|
57
|
-
* @returns {{ definition: object|null }}
|
|
58
|
-
*/
|
|
59
|
-
'gitagent-parse': async (params) => {
|
|
60
|
-
const projectPath = params.projectPath;
|
|
61
|
-
if (!projectPath) return { definition: null };
|
|
62
|
-
|
|
63
|
-
const definition = await parseGitagentRepo(projectPath, fsReadFile, fsListDir);
|
|
64
|
-
return { definition };
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
};
|