f95d766f69
Memind CI / Test, build, and release guards (push) Failing after 14m36s
Parse Cursor CLI usage from stream-json output and charge through billSessionUsage so subscription quota is consumed first and wallet overage applies when needed. Co-authored-by: Cursor <cursoragent@cursor.com>
110 lines
3.3 KiB
JavaScript
110 lines
3.3 KiB
JavaScript
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
|
|
function envFlag(value, fallback = false) {
|
|
const raw = String(value ?? '').trim().toLowerCase();
|
|
if (!raw) return fallback;
|
|
return ['1', 'true', 'yes', 'on'].includes(raw);
|
|
}
|
|
|
|
export function expandHome(value) {
|
|
const text = String(value ?? '').trim();
|
|
if (!text) return text;
|
|
if (text.startsWith('~/')) return path.join(os.homedir(), text.slice(2));
|
|
if (text === '~') return os.homedir();
|
|
return text;
|
|
}
|
|
|
|
export function cursorExecutorEnabled(env = process.env) {
|
|
return envFlag(env.MEMIND_CURSOR_EXECUTOR_ENABLED, false);
|
|
}
|
|
|
|
export function resolvePreferredCodeExecutor(env = process.env) {
|
|
if (!cursorExecutorEnabled(env)) return 'aider';
|
|
if (envFlag(env.MEMIND_AIDER_SKILL_USE_CURSOR, true)) return 'cursor';
|
|
return 'aider';
|
|
}
|
|
|
|
export function cursorPageTasksDefaultEnabled(env = process.env) {
|
|
if (!cursorExecutorEnabled(env)) return false;
|
|
return envFlag(env.MEMIND_CURSOR_PAGE_TASKS_DEFAULT, true);
|
|
}
|
|
|
|
/** @deprecated 普通 Agent 编排不再默认走 Cursor;仅页面/问卷/Excel 等代码任务使用 enforcePageGenerationCursorRuntime */
|
|
export function cursorAgentTasksDefaultEnabled(env = process.env) {
|
|
if (!cursorExecutorEnabled(env)) return false;
|
|
return envFlag(env.MEMIND_CURSOR_AGENT_TASKS_DEFAULT, false);
|
|
}
|
|
|
|
/** 智趣执行失败时回退 DeepSeek / Goose 会话 */
|
|
export function cursorDeepseekFallbackEnabled(env = process.env) {
|
|
return envFlag(env.MEMIND_CURSOR_DEEPSEEK_FALLBACK, false);
|
|
}
|
|
|
|
export function resolveCursorAgentBin(env = process.env) {
|
|
const configured = expandHome(
|
|
env.MEMIND_CURSOR_EXECUTOR_AGENT_BIN
|
|
?? env.MEMIND_CURSOR_HELP_AGENT_BIN
|
|
?? '~/.local/bin/agent',
|
|
);
|
|
if (configured && fs.existsSync(configured)) return configured;
|
|
return 'agent';
|
|
}
|
|
|
|
export function buildCursorExecutorInstruction(instruction) {
|
|
const base = String(instruction ?? '').trim();
|
|
if (!base) return base;
|
|
return [
|
|
base,
|
|
'',
|
|
'执行要求:',
|
|
'- 在当前 MindSpace 工作区(cwd)内完成改动',
|
|
'- 页面产物写入 public/ 目录下的 .html 文件',
|
|
'- 直接完成可交付产物,不要等待用户确认',
|
|
'- 不要执行 git commit、git push、git checkout、git reset、生产发布或远端同步命令',
|
|
'- 不要修改当前工作区之外的文件',
|
|
'- 完成后在最终输出中简述改动文件与验证结果',
|
|
].join('\n');
|
|
}
|
|
|
|
export function buildCursorExecutorLaunchPlan({
|
|
cwd,
|
|
instruction,
|
|
env = process.env,
|
|
agentBin = resolveCursorAgentBin(env),
|
|
} = {}) {
|
|
const workspace = path.resolve(String(cwd ?? env.MEMIND_CURSOR_EXECUTOR_WORKSPACE ?? process.cwd()));
|
|
const prompt = buildCursorExecutorInstruction(instruction);
|
|
if (!prompt) {
|
|
return {
|
|
ok: false,
|
|
executor: 'cursor',
|
|
message: 'TKMind 智趣执行器需要 instruction',
|
|
};
|
|
}
|
|
return {
|
|
ok: true,
|
|
executor: 'cursor',
|
|
executorLabel: 'TKMind 智趣',
|
|
cwd: workspace,
|
|
command: agentBin,
|
|
args: [
|
|
'--print',
|
|
'--trust',
|
|
'--force',
|
|
'--approve-mcps',
|
|
'--output-format',
|
|
'stream-json',
|
|
'--workspace',
|
|
workspace,
|
|
prompt,
|
|
],
|
|
env: {},
|
|
notes: [
|
|
'TKMind 智趣执行器在 MindSpace 工作区 headless 执行。',
|
|
'Goose 仍负责对话编排,智趣只负责代码/页面落盘。',
|
|
],
|
|
};
|
|
}
|