fraim 2.0.170 → 2.0.171
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/dist/src/cli/commands/add-ide.js +2 -2
- package/dist/src/cli/commands/setup.js +1 -1
- package/dist/src/cli/doctor/checks/ide-config-checks.js +2 -2
- package/dist/src/cli/mcp/ide-formats.js +10 -2
- package/dist/src/cli/setup/auto-mcp-setup.js +4 -2
- package/dist/src/cli/setup/ide-detector.js +20 -0
- package/dist/src/cli/setup/ide-global-integration.js +6 -2
- package/dist/src/cli/setup/ide-invocation-surfaces.js +12 -4
- package/dist/src/cli/setup/mcp-config-generator.js +12 -1
- package/dist/src/cli/utils/agent-adapters.js +3 -0
- package/dist/src/first-run/session-service.js +3 -3
- package/package.json +1 -1
- package/public/ai-hub/script.js +14 -13
|
@@ -384,7 +384,7 @@ const runAddIDE = async (options) => {
|
|
|
384
384
|
const detectedIDEs = (0, ide_detector_1.detectInstalledIDEs)();
|
|
385
385
|
if (detectedIDEs.length === 0) {
|
|
386
386
|
console.log(chalk_1.default.yellow('⚠️ No supported IDEs detected on your system.'));
|
|
387
|
-
console.log(chalk_1.default.gray('Supported IDEs: Claude, Claude Code, Antigravity, Gemini CLI, Kiro, Cursor, VSCode, Codex, Windsurf'));
|
|
387
|
+
console.log(chalk_1.default.gray('Supported IDEs: Claude, Claude Code, Antigravity, Gemini CLI, Kiro, Cursor, VSCode, Codex, Grok, Windsurf'));
|
|
388
388
|
console.log(chalk_1.default.blue('\n💡 Install an IDE and run this command again.'));
|
|
389
389
|
return;
|
|
390
390
|
}
|
|
@@ -446,7 +446,7 @@ const runAddIDE = async (options) => {
|
|
|
446
446
|
exports.runAddIDE = runAddIDE;
|
|
447
447
|
exports.addIDECommand = new commander_1.Command('add-ide')
|
|
448
448
|
.description('Add FRAIM configuration to additional IDEs')
|
|
449
|
-
.option('--ide <name>', 'Configure specific IDE (claude, claude-code, claude-desktop, claude-cowork, antigravity, gemini, gemini-cli, kiro, cursor, vscode, codex, windsurf)')
|
|
449
|
+
.option('--ide <name>', 'Configure specific IDE (claude, claude-code, claude-desktop, claude-cowork, antigravity, gemini, gemini-cli, kiro, cursor, vscode, codex, grok, windsurf)')
|
|
450
450
|
.option('--all', 'Configure all detected IDEs')
|
|
451
451
|
.option('--list', 'List all supported IDEs and their detection status')
|
|
452
452
|
.action(exports.runAddIDE);
|
|
@@ -677,7 +677,7 @@ const runSetup = async (options) => {
|
|
|
677
677
|
name: 'choice',
|
|
678
678
|
message: 'How would you like to work with your AI employees?',
|
|
679
679
|
choices: [
|
|
680
|
-
{ title: 'In my IDE (Claude Code, Cursor, or another AI tool)', value: 'ide' },
|
|
680
|
+
{ title: 'In my IDE (Claude Code, Cursor, Grok, or another AI tool)', value: 'ide' },
|
|
681
681
|
{ title: 'In FRAIM Hub (browser-based — no terminal needed)', value: 'hub' },
|
|
682
682
|
],
|
|
683
683
|
});
|
|
@@ -35,8 +35,8 @@ function checkIDEsDetected() {
|
|
|
35
35
|
return {
|
|
36
36
|
status: 'warning',
|
|
37
37
|
message: 'No IDEs detected',
|
|
38
|
-
suggestion: 'Install Claude Desktop, Cursor, or another supported IDE',
|
|
39
|
-
details: { supportedIDEs: ['Claude Desktop', 'Cursor', 'Windsurf', 'VS Code', 'Zed', 'Codex'] }
|
|
38
|
+
suggestion: 'Install Claude Desktop, Cursor, Grok, or another supported IDE',
|
|
39
|
+
details: { supportedIDEs: ['Claude Desktop', 'Cursor', 'Windsurf', 'VS Code', 'Zed', 'Codex', 'Grok'] }
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// IDE Format Adapters - transform logical server structure to IDE-specific formats
|
|
3
3
|
// Uses the centralized registry to determine server types
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.IDE_FORMATS = exports.CodexFormat = exports.WindsurfFormat = exports.ClaudeCodeFormat = exports.ClaudeFormat = exports.GeminiCliFormat = exports.VSCodeFormat = exports.KiroFormat = exports.StandardFormat = void 0;
|
|
5
|
+
exports.IDE_FORMATS = exports.GrokFormat = exports.CodexFormat = exports.WindsurfFormat = exports.ClaudeCodeFormat = exports.ClaudeFormat = exports.GeminiCliFormat = exports.VSCodeFormat = exports.KiroFormat = exports.StandardFormat = void 0;
|
|
6
6
|
exports.getIDEFormat = getIDEFormat;
|
|
7
7
|
const mcp_server_registry_1 = require("./mcp-server-registry");
|
|
8
8
|
const provider_registry_1 = require("../providers/provider-registry");
|
|
@@ -252,6 +252,13 @@ class CodexFormat {
|
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
exports.CodexFormat = CodexFormat;
|
|
255
|
+
class GrokFormat extends CodexFormat {
|
|
256
|
+
constructor() {
|
|
257
|
+
super(...arguments);
|
|
258
|
+
this.name = 'grok';
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
exports.GrokFormat = GrokFormat;
|
|
255
262
|
// Format registry
|
|
256
263
|
exports.IDE_FORMATS = {
|
|
257
264
|
standard: new StandardFormat(),
|
|
@@ -261,7 +268,8 @@ exports.IDE_FORMATS = {
|
|
|
261
268
|
claude: new ClaudeFormat(),
|
|
262
269
|
'claude-code': new ClaudeCodeFormat(),
|
|
263
270
|
windsurf: new WindsurfFormat(),
|
|
264
|
-
codex: new CodexFormat()
|
|
271
|
+
codex: new CodexFormat(),
|
|
272
|
+
grok: new GrokFormat()
|
|
265
273
|
};
|
|
266
274
|
function getIDEFormat(configType) {
|
|
267
275
|
const format = exports.IDE_FORMATS[configType];
|
|
@@ -187,7 +187,9 @@ const configureIDEMCP = async (ide, fraimKey, tokenInput, providerConfigs) => {
|
|
|
187
187
|
}
|
|
188
188
|
const newTomlContent = await (0, mcp_config_generator_1.generateMCPConfig)(ide.configType, fraimKey, tokens, providerConfigs);
|
|
189
189
|
const { getAllMCPServerIds } = await Promise.resolve().then(() => __importStar(require('../mcp/mcp-server-registry')));
|
|
190
|
-
const
|
|
190
|
+
const baseServerIds = getAllMCPServerIds();
|
|
191
|
+
const providerServerIds = Object.keys(tokens).filter(id => tokens[id]);
|
|
192
|
+
const serversToAdd = [...baseServerIds, ...providerServerIds];
|
|
191
193
|
const mergeResult = (0, mcp_config_generator_1.mergeTomlMCPServers)(existingTomlContent, newTomlContent, serversToAdd);
|
|
192
194
|
fs_1.default.writeFileSync(configPath, mergeResult.content);
|
|
193
195
|
mergeResult.addedServers.forEach(server => {
|
|
@@ -254,7 +256,7 @@ const autoConfigureMCP = async (fraimKey, tokenInput, selectedIDEs, providerConf
|
|
|
254
256
|
const detectedIDEs = (0, ide_detector_1.detectInstalledIDEs)();
|
|
255
257
|
if (detectedIDEs.length === 0 && (!selectedIDEs || selectedIDEs.length === 0)) {
|
|
256
258
|
console.log(chalk_1.default.yellow('⚠️ No supported IDEs detected.'));
|
|
257
|
-
console.log(chalk_1.default.gray('Supported IDEs: Claude, Claude Code, Antigravity, Gemini CLI, Kiro, Cursor, VSCode, Codex, Windsurf'));
|
|
259
|
+
console.log(chalk_1.default.gray('Supported IDEs: Claude, Claude Code, Antigravity, Gemini CLI, Kiro, Cursor, VSCode, Codex, Grok, Windsurf'));
|
|
258
260
|
console.log(chalk_1.default.blue('\n💡 You can install an IDE and run setup again later.'));
|
|
259
261
|
console.log(chalk_1.default.gray(' Or continue with manual MCP configuration.'));
|
|
260
262
|
if (process.env.FRAIM_NON_INTERACTIVE) {
|
|
@@ -79,6 +79,13 @@ const detectCodexSurface = () => {
|
|
|
79
79
|
];
|
|
80
80
|
return checkMultiplePaths(paths);
|
|
81
81
|
};
|
|
82
|
+
const detectGrokSurface = () => {
|
|
83
|
+
const paths = [
|
|
84
|
+
'~/.grok',
|
|
85
|
+
'~/.grok/config.toml'
|
|
86
|
+
];
|
|
87
|
+
return checkMultiplePaths(paths);
|
|
88
|
+
};
|
|
82
89
|
exports.IDE_CONFIGS = [
|
|
83
90
|
{
|
|
84
91
|
name: 'Claude Code',
|
|
@@ -180,6 +187,17 @@ exports.IDE_CONFIGS = [
|
|
|
180
187
|
detectMethod: detectCodexSurface,
|
|
181
188
|
description: 'Codex AI development environment'
|
|
182
189
|
},
|
|
190
|
+
{
|
|
191
|
+
name: 'Grok',
|
|
192
|
+
configPath: '~/.grok/config.toml',
|
|
193
|
+
configFormat: 'toml',
|
|
194
|
+
configType: 'grok',
|
|
195
|
+
invocationProfile: 'grok-skill',
|
|
196
|
+
detectMethod: detectGrokSurface,
|
|
197
|
+
supportsConfigBootstrap: true,
|
|
198
|
+
aliases: ['grok', 'grok-cli', 'grok cli', 'grok build'],
|
|
199
|
+
description: 'xAI Grok Build CLI local settings'
|
|
200
|
+
},
|
|
183
201
|
{
|
|
184
202
|
name: 'Windsurf',
|
|
185
203
|
configPath: '~/.codeium/windsurf/mcp_config.json',
|
|
@@ -219,6 +237,8 @@ const isDetectedForMode = (ide, mode) => {
|
|
|
219
237
|
return availableByVersionProbe('claude');
|
|
220
238
|
case 'codex':
|
|
221
239
|
return availableByVersionProbe('codex');
|
|
240
|
+
case 'grok':
|
|
241
|
+
return availableByVersionProbe('grok');
|
|
222
242
|
case 'gemini-cli':
|
|
223
243
|
return detectGeminiCli();
|
|
224
244
|
default:
|
|
@@ -35,7 +35,7 @@ function describeOnboardingInvocationSurfaces(installedIDEs) {
|
|
|
35
35
|
return `${ide.name}: onboard this project`;
|
|
36
36
|
if (profile === 'instructions-only')
|
|
37
37
|
return `${ide.name}: "onboard this project"`;
|
|
38
|
-
// claude-slash, vscode-prompt, codex-skill, windsurf-command, kiro-hashtag, gemini-command
|
|
38
|
+
// claude-slash, vscode-prompt, codex-skill, grok-skill, windsurf-command, kiro-hashtag, gemini-command
|
|
39
39
|
return `${ide.name}: /fraim onboard this project`;
|
|
40
40
|
});
|
|
41
41
|
}
|
|
@@ -55,7 +55,7 @@ async function installSlashCommands(homeDir) {
|
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
57
|
* Install FRAIM invocation artifacts for non-Claude IDEs.
|
|
58
|
-
* Supports: Cursor, Codex, Gemini CLI, Windsurf, Kiro
|
|
58
|
+
* Supports: Cursor, Codex, Grok, Gemini CLI, Windsurf, Kiro
|
|
59
59
|
* Does not overwrite existing files.
|
|
60
60
|
*/
|
|
61
61
|
async function installGlobalRules(homeDir) {
|
|
@@ -68,6 +68,10 @@ async function installGlobalRules(homeDir) {
|
|
|
68
68
|
if (fs_1.default.existsSync(codexDir)) {
|
|
69
69
|
installFileIfMissing(path_1.default.join(codexDir, 'skills', 'fraim', 'SKILL.md'), (0, ide_invocation_surfaces_1.buildCodexSkillContent)(), 'Codex FRAIM skill (~/.codex/skills/fraim/SKILL.md)');
|
|
70
70
|
}
|
|
71
|
+
const grokDir = path_1.default.join(home, '.grok');
|
|
72
|
+
if (fs_1.default.existsSync(grokDir)) {
|
|
73
|
+
installFileIfMissing(path_1.default.join(grokDir, 'skills', 'fraim', 'SKILL.md'), (0, ide_invocation_surfaces_1.buildGrokSkillContent)(), 'Grok FRAIM skill (~/.grok/skills/fraim/SKILL.md)');
|
|
74
|
+
}
|
|
71
75
|
const geminiDir = path_1.default.join(home, '.gemini');
|
|
72
76
|
if (fs_1.default.existsSync(geminiDir)) {
|
|
73
77
|
installFileIfMissing(path_1.default.join(geminiDir, 'commands', 'fraim.toml'), (0, ide_invocation_surfaces_1.buildGeminiCommandContent)(), 'Gemini CLI FRAIM command (~/.gemini/commands/fraim.toml)');
|
|
@@ -7,6 +7,7 @@ exports.buildClaudeCommandShimContent = buildClaudeCommandShimContent;
|
|
|
7
7
|
exports.buildClaudeSlashCommandContent = buildClaudeSlashCommandContent;
|
|
8
8
|
exports.buildCursorMentionRuleContent = buildCursorMentionRuleContent;
|
|
9
9
|
exports.buildCodexSkillContent = buildCodexSkillContent;
|
|
10
|
+
exports.buildGrokSkillContent = buildGrokSkillContent;
|
|
10
11
|
exports.buildWindsurfCommandContent = buildWindsurfCommandContent;
|
|
11
12
|
exports.buildKiroCommandContent = buildKiroCommandContent;
|
|
12
13
|
exports.buildAntigravityCommandContent = buildAntigravityCommandContent;
|
|
@@ -95,13 +96,18 @@ ${buildFraimInvocationBody('generic-tool-discovery')}
|
|
|
95
96
|
`;
|
|
96
97
|
}
|
|
97
98
|
function buildCodexSkillContent() {
|
|
98
|
-
return `# FRAIM
|
|
99
|
-
|
|
99
|
+
return `# FRAIM
|
|
100
|
+
|
|
100
101
|
${buildFraimInvocationBody('codex-tool-search')}`;
|
|
101
102
|
}
|
|
103
|
+
function buildGrokSkillContent() {
|
|
104
|
+
return `# FRAIM
|
|
105
|
+
|
|
106
|
+
${buildFraimInvocationBody('generic-tool-discovery')}`;
|
|
107
|
+
}
|
|
102
108
|
function buildWindsurfCommandContent() {
|
|
103
|
-
return `# FRAIM
|
|
104
|
-
|
|
109
|
+
return `# FRAIM
|
|
110
|
+
|
|
105
111
|
${buildFraimInvocationBody('generic-tool-discovery')}`;
|
|
106
112
|
}
|
|
107
113
|
function buildKiroCommandContent() {
|
|
@@ -139,6 +145,8 @@ function describeInvocationSurface(ideName, invocationProfile) {
|
|
|
139
145
|
return `${ideName}: /fraim via workspace prompt`;
|
|
140
146
|
case 'codex-skill':
|
|
141
147
|
return `${ideName}: /fraim, $fraim`;
|
|
148
|
+
case 'grok-skill':
|
|
149
|
+
return `${ideName}: /fraim`;
|
|
142
150
|
case 'windsurf-command':
|
|
143
151
|
return `${ideName}: /fraim`;
|
|
144
152
|
case 'kiro-hashtag':
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateMCPConfig = exports.generateWindsurfMCPServers = exports.generateGeminiCliMCPServers = exports.generateVSCodeMCPServers = exports.generateCodexMCPServers = exports.generateKiroMCPServers = exports.generateClaudeCodeMCPServers = exports.generateClaudeMCPServers = exports.generateStandardMCPServers = exports.mergeTomlMCPServers = exports.extractTomlMcpServerBlock = void 0;
|
|
3
|
+
exports.generateMCPConfig = exports.generateWindsurfMCPServers = exports.generateGeminiCliMCPServers = exports.generateVSCodeMCPServers = exports.generateGrokMCPServers = exports.generateCodexMCPServers = exports.generateKiroMCPServers = exports.generateClaudeCodeMCPServers = exports.generateClaudeMCPServers = exports.generateStandardMCPServers = exports.mergeTomlMCPServers = exports.extractTomlMcpServerBlock = void 0;
|
|
4
4
|
const mcp_server_builder_1 = require("../mcp/mcp-server-builder");
|
|
5
5
|
const ide_formats_1 = require("../mcp/ide-formats");
|
|
6
6
|
const normalizeTokens = (tokenInput) => {
|
|
@@ -151,6 +151,15 @@ const generateCodexMCPServers = async (fraimKey, tokenInput, providerConfigs) =>
|
|
|
151
151
|
return format.transform(builder.getServers());
|
|
152
152
|
};
|
|
153
153
|
exports.generateCodexMCPServers = generateCodexMCPServers;
|
|
154
|
+
const generateGrokMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
|
|
155
|
+
const tokens = normalizeTokens(tokenInput);
|
|
156
|
+
const builder = new mcp_server_builder_1.MCPServerBuilder();
|
|
157
|
+
builder.addBaseServers(fraimKey);
|
|
158
|
+
await addProviderServers(builder, tokens, providerConfigs);
|
|
159
|
+
const format = (0, ide_formats_1.getIDEFormat)('grok');
|
|
160
|
+
return format.transform(builder.getServers());
|
|
161
|
+
};
|
|
162
|
+
exports.generateGrokMCPServers = generateGrokMCPServers;
|
|
154
163
|
const generateVSCodeMCPServers = async (fraimKey, tokenInput, providerConfigs) => {
|
|
155
164
|
const tokens = normalizeTokens(tokenInput);
|
|
156
165
|
const builder = new mcp_server_builder_1.MCPServerBuilder();
|
|
@@ -194,6 +203,8 @@ const generateMCPConfig = async (configType, fraimKey, tokenInput, providerConfi
|
|
|
194
203
|
return await (0, exports.generateGeminiCliMCPServers)(fraimKey, tokenInput, providerConfigs);
|
|
195
204
|
case 'codex':
|
|
196
205
|
return await (0, exports.generateCodexMCPServers)(fraimKey, tokenInput, providerConfigs);
|
|
206
|
+
case 'grok':
|
|
207
|
+
return await (0, exports.generateGrokMCPServers)(fraimKey, tokenInput, providerConfigs);
|
|
197
208
|
case 'windsurf':
|
|
198
209
|
return await (0, exports.generateWindsurfMCPServers)(fraimKey, tokenInput, providerConfigs);
|
|
199
210
|
default:
|
|
@@ -15,6 +15,7 @@ const CLAUDE_FRAIM_COMMAND_PATH = path_1.default.join('.claude', 'commands', 'fr
|
|
|
15
15
|
const CLAUDE_FRAIM_SKILL_PATH = path_1.default.join('.claude', 'skills', 'fraim', 'SKILL.md');
|
|
16
16
|
const VSCODE_FRAIM_PROMPT_PATH = path_1.default.join('.github', 'prompts', 'fraim.prompt.md');
|
|
17
17
|
const CODEX_FRAIM_SKILL_PATH = path_1.default.join('.codex', 'skills', 'fraim', 'SKILL.md');
|
|
18
|
+
const GROK_FRAIM_SKILL_PATH = path_1.default.join('.grok', 'skills', 'fraim', 'SKILL.md');
|
|
18
19
|
const GEMINI_FRAIM_COMMAND_PATH = path_1.default.join('.gemini', 'commands', 'fraim.toml');
|
|
19
20
|
const GEMINI_PROJECT_INSTRUCTIONS_PATH = path_1.default.join('.gemini', 'GEMINI.md');
|
|
20
21
|
const WINDSURF_FRAIM_COMMAND_PATH = path_1.default.join('.windsurf', 'commands', 'fraim.md');
|
|
@@ -118,6 +119,7 @@ ${(0, ide_invocation_surfaces_1.buildFraimInvocationBody)('generic-tool-discover
|
|
|
118
119
|
{ path: CLAUDE_FRAIM_SKILL_PATH, content: (0, ide_invocation_surfaces_1.buildClaudeSkillContent)() },
|
|
119
120
|
{ path: CLAUDE_FRAIM_COMMAND_PATH, content: (0, ide_invocation_surfaces_1.buildClaudeCommandShimContent)() },
|
|
120
121
|
{ path: CODEX_FRAIM_SKILL_PATH, content: (0, ide_invocation_surfaces_1.buildCodexSkillContent)() },
|
|
122
|
+
{ path: GROK_FRAIM_SKILL_PATH, content: (0, ide_invocation_surfaces_1.buildGrokSkillContent)() },
|
|
121
123
|
{ path: GEMINI_FRAIM_COMMAND_PATH, content: (0, ide_invocation_surfaces_1.buildGeminiCommandContent)() },
|
|
122
124
|
{ path: GEMINI_PROJECT_INSTRUCTIONS_PATH, content: geminiProjectInstructions },
|
|
123
125
|
{ path: WINDSURF_FRAIM_COMMAND_PATH, content: (0, ide_invocation_surfaces_1.buildWindsurfCommandContent)() },
|
|
@@ -140,6 +142,7 @@ function ensureAgentAdapterFiles(projectRoot) {
|
|
|
140
142
|
|| file.path === CLAUDE_FRAIM_SKILL_PATH
|
|
141
143
|
|| file.path === CLAUDE_FRAIM_COMMAND_PATH
|
|
142
144
|
|| file.path === CODEX_FRAIM_SKILL_PATH
|
|
145
|
+
|| file.path === GROK_FRAIM_SKILL_PATH
|
|
143
146
|
|| file.path === GEMINI_FRAIM_COMMAND_PATH
|
|
144
147
|
|| file.path === GEMINI_PROJECT_INSTRUCTIONS_PATH
|
|
145
148
|
|| file.path === WINDSURF_FRAIM_COMMAND_PATH
|
|
@@ -174,8 +174,8 @@ function normalizeRows(rows) {
|
|
|
174
174
|
...(existingById.get(canonical.id) || {}),
|
|
175
175
|
}));
|
|
176
176
|
}
|
|
177
|
-
function
|
|
178
|
-
const ides = (0, ide_detector_1.detectInstalledIDEs)();
|
|
177
|
+
function buildRunnableAgentSurfaces() {
|
|
178
|
+
const ides = (0, ide_detector_1.detectInstalledIDEs)('cli-runnable');
|
|
179
179
|
const hints = (0, ide_global_integration_1.describeOnboardingInvocationSurfaces)(ides);
|
|
180
180
|
return ides.map((ide, index) => ({
|
|
181
181
|
id: ide.configType,
|
|
@@ -333,7 +333,7 @@ class FirstRunSessionService {
|
|
|
333
333
|
byId.set(surface.id, surface);
|
|
334
334
|
}
|
|
335
335
|
if (this.fakeMode !== 'no-agents') {
|
|
336
|
-
for (const surface of
|
|
336
|
+
for (const surface of buildRunnableAgentSurfaces()) {
|
|
337
337
|
byId.set(surface.id, surface);
|
|
338
338
|
}
|
|
339
339
|
}
|
package/package.json
CHANGED
package/public/ai-hub/script.js
CHANGED
|
@@ -3529,8 +3529,9 @@ function rerunLastJob() {
|
|
|
3529
3529
|
openPalette();
|
|
3530
3530
|
return;
|
|
3531
3531
|
}
|
|
3532
|
-
|
|
3533
|
-
startRun(
|
|
3532
|
+
const lastRun = state.lastRun;
|
|
3533
|
+
startRun(lastRun.job, lastRun.instructions, lastRun.employeeId);
|
|
3534
|
+
showRerunToast('Re-running: ' + (lastRun.job.title || lastRun.job.id));
|
|
3534
3535
|
}
|
|
3535
3536
|
|
|
3536
3537
|
function showRerunToast(msg) {
|
|
@@ -3538,7 +3539,7 @@ function showRerunToast(msg) {
|
|
|
3538
3539
|
t.className = 'cp-rerun-toast';
|
|
3539
3540
|
t.textContent = msg;
|
|
3540
3541
|
document.body.appendChild(t);
|
|
3541
|
-
setTimeout(() => { if (t.parentNode) t.parentNode.removeChild(t); },
|
|
3542
|
+
setTimeout(() => { if (t.parentNode) t.parentNode.removeChild(t); }, 5000);
|
|
3542
3543
|
}
|
|
3543
3544
|
|
|
3544
3545
|
// ---------------------------------------------------------------------------
|
|
@@ -3976,14 +3977,14 @@ async function startRun(job, instructions, employeeId, preassignedConvId) {
|
|
|
3976
3977
|
// Issue #489: capture selection state at job-start so write-back knows insert-after vs append.
|
|
3977
3978
|
wordStartedWithSelection: document.body.dataset.surface === 'task-pane' && !!(state.wordContext && state.wordContext.hasSelection),
|
|
3978
3979
|
};
|
|
3979
|
-
upsertConversation(conv);
|
|
3980
|
-
state.activeId = conv.id;
|
|
3981
|
-
// Issue #539: make Cmd/Ctrl+Shift+R available as soon as the run is queued,
|
|
3982
|
-
// not only after the server responds with the run id.
|
|
3983
|
-
state.lastRun = { job, instructions, employeeId };
|
|
3984
|
-
persistConversations();
|
|
3985
|
-
renderRail();
|
|
3986
|
-
renderActive();
|
|
3980
|
+
upsertConversation(conv);
|
|
3981
|
+
state.activeId = conv.id;
|
|
3982
|
+
// Issue #539: make Cmd/Ctrl+Shift+R available as soon as the run is queued,
|
|
3983
|
+
// not only after the server responds with the run id.
|
|
3984
|
+
state.lastRun = { job, instructions, employeeId };
|
|
3985
|
+
persistConversations();
|
|
3986
|
+
renderRail();
|
|
3987
|
+
renderActive();
|
|
3987
3988
|
|
|
3988
3989
|
try {
|
|
3989
3990
|
const run = await requestJson('/api/ai-hub/runs', {
|
|
@@ -4011,8 +4012,8 @@ async function startRun(job, instructions, employeeId, preassignedConvId) {
|
|
|
4011
4012
|
renderRail();
|
|
4012
4013
|
renderActive();
|
|
4013
4014
|
startPolling();
|
|
4014
|
-
// Issue #539: update in-memory preferences so the next palette open shows
|
|
4015
|
-
// the correct recent section.
|
|
4015
|
+
// Issue #539: update in-memory preferences so the next palette open shows
|
|
4016
|
+
// the correct recent section.
|
|
4016
4017
|
if (state.bootstrap && state.bootstrap.preferences) {
|
|
4017
4018
|
const prefs = state.bootstrap.preferences;
|
|
4018
4019
|
const nextIds = [job.id, ...(prefs.recentJobIds || []).filter((id) => id !== job.id)].slice(0, 8);
|