@mrpatronz/nexusflow 2.1.1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/core/workspace.d.ts +6 -0
- package/dist/core/workspace.d.ts.map +1 -1
- package/dist/core/workspace.js +17 -7
- package/dist/core/workspace.js.map +1 -1
- package/dist/core/workspace.test.js +12 -1
- package/dist/core/workspace.test.js.map +1 -1
- package/dist/gui/assets/{DashboardPage-BeAHHUtn.js → DashboardPage-CUspfCap.js} +1 -1
- package/dist/gui/assets/{GettingStartedPage-CFAyG0ar.js → GettingStartedPage-BqtgARZW.js} +1 -1
- package/dist/gui/assets/{ProjectsPage-C0SmbBqW.js → ProjectsPage-UBoQxI2G.js} +1 -1
- package/dist/gui/assets/{ScaffoldRepoInline-lfFwOnQu.js → ScaffoldRepoInline-DqoourJe.js} +1 -1
- package/dist/gui/assets/{SettingsPage-DIBk9fu8.js → SettingsPage-BZl24tqD.js} +1 -1
- package/dist/gui/assets/StartWorkPage-BGNFdBfj.js +1 -0
- package/dist/gui/assets/{StrategiesPage-Dcq10WZS.js → StrategiesPage-D0Y6A4Tw.js} +1 -1
- package/dist/gui/assets/WorkspaceLauncher-Cxv0O_wt.js +1 -0
- package/dist/gui/assets/WorkspacesPage-Cvb1rOeh.js +6 -0
- package/dist/gui/assets/index-CllPiiFL.js +52 -0
- package/dist/gui/assets/index-DGCBhMAn.css +2 -0
- package/dist/gui/index.html +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +114 -18
- package/dist/server.js.map +1 -1
- package/dist/server.test.js +193 -17
- package/dist/server.test.js.map +1 -1
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/detect-editors.d.ts.map +1 -1
- package/dist/utils/detect-editors.js +6 -0
- package/dist/utils/detect-editors.js.map +1 -1
- package/dist/utils/detect-editors.test.js +12 -0
- package/dist/utils/detect-editors.test.js.map +1 -1
- package/dist/utils/session-finder.d.ts +11 -0
- package/dist/utils/session-finder.d.ts.map +1 -1
- package/dist/utils/session-finder.js +73 -0
- package/dist/utils/session-finder.js.map +1 -1
- package/dist/utils/session-finder.test.js +44 -1
- package/dist/utils/session-finder.test.js.map +1 -1
- package/dist/utils/workspace-launch.d.ts +37 -0
- package/dist/utils/workspace-launch.d.ts.map +1 -0
- package/dist/utils/workspace-launch.js +221 -0
- package/dist/utils/workspace-launch.js.map +1 -0
- package/dist/utils/workspace-launch.test.d.ts +2 -0
- package/dist/utils/workspace-launch.test.d.ts.map +1 -0
- package/dist/utils/workspace-launch.test.js +128 -0
- package/dist/utils/workspace-launch.test.js.map +1 -0
- package/package.json +2 -2
- package/dist/gui/assets/StartWorkPage-CWC5OujI.js +0 -1
- package/dist/gui/assets/WorkspacesPage-BqOx6Gbe.js +0 -6
- package/dist/gui/assets/external-link-BtYhMxno.js +0 -1
- package/dist/gui/assets/index-B5IYXvr6.css +0 -2
- package/dist/gui/assets/index-BCfJkb0T.js +0 -52
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-finder.test.js","sourceRoot":"","sources":["../../src/utils/session-finder.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-finder.test.js","sourceRoot":"","sources":["../../src/utils/session-finder.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-owned workspace launch catalog.
|
|
3
|
+
*
|
|
4
|
+
* The renderer selects a stable id. It never supplies an executable, URI, or
|
|
5
|
+
* filesystem path, which keeps process construction on this trusted boundary.
|
|
6
|
+
*/
|
|
7
|
+
import type { Feature, WorkspaceLaunchIcon, WorkspaceLaunchTarget } from '../types.js';
|
|
8
|
+
interface DesktopDefinition {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
scheme: 'codex' | 'claude';
|
|
12
|
+
icon: WorkspaceLaunchIcon;
|
|
13
|
+
description: string;
|
|
14
|
+
macAppNames: string[];
|
|
15
|
+
buildNewUri(workspacePath: string, prompt?: string): string;
|
|
16
|
+
buildResumeUri?(sessionId: string): string;
|
|
17
|
+
}
|
|
18
|
+
export type WorkspaceLaunchIntent = {
|
|
19
|
+
kind: 'new-workspace';
|
|
20
|
+
prompt?: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'resume-session';
|
|
23
|
+
sessionId: string;
|
|
24
|
+
};
|
|
25
|
+
/** Build a concise, server-owned kickoff for a provider Desktop composer. */
|
|
26
|
+
export declare function buildWorkspaceLaunchPrompt(feature: Pick<Feature, 'description'>): string;
|
|
27
|
+
/** Check whether the OS can activate a provider-owned desktop URI scheme. */
|
|
28
|
+
export declare function hasDesktopProtocol(definition: Pick<DesktopDefinition, 'scheme' | 'macAppNames'>, platform?: NodeJS.Platform): Promise<boolean>;
|
|
29
|
+
/** Return every known target so unavailable choices can be explained in the UI. */
|
|
30
|
+
export declare function detectWorkspaceLaunchTargets(platform?: NodeJS.Platform): Promise<WorkspaceLaunchTarget[]>;
|
|
31
|
+
export declare function openDesktopUri(uri: string, platform?: NodeJS.Platform): Promise<void>;
|
|
32
|
+
/** Launch one closed target at a validated absolute workspace directory. */
|
|
33
|
+
export declare function launchWorkspaceTarget(targetId: string, workspacePath: string, intent?: WorkspaceLaunchIntent, platform?: NodeJS.Platform): Promise<void>;
|
|
34
|
+
/** Convert a legacy editor command to its closed target id. */
|
|
35
|
+
export declare function launchTargetIdForEditorCommand(command: string): string | null;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=workspace-launch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-launch.d.ts","sourceRoot":"","sources":["../../src/utils/workspace-launch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EACV,OAAO,EACP,mBAAmB,EACnB,qBAAqB,EAEtB,MAAM,aAAa,CAAC;AAarB,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC3B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5D,cAAc,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5C;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAmBlD,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,GAAG,MAAM,CAOxF;AA0DD,6EAA6E;AAC7E,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,GAAG,aAAa,CAAC,EAC7D,QAAQ,kBAAmB,GAC1B,OAAO,CAAC,OAAO,CAAC,CAiClB;AAED,mFAAmF;AACnF,wBAAsB,4BAA4B,CAChD,QAAQ,kBAAmB,GAC1B,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAsClC;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,kBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuC5F;AAED,4EAA4E;AAC5E,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,MAAM,GAAE,qBAAiD,EACzD,QAAQ,kBAAmB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoCf;AAED,+DAA+D;AAC/D,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE7E"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-owned workspace launch catalog.
|
|
3
|
+
*
|
|
4
|
+
* The renderer selects a stable id. It never supplies an executable, URI, or
|
|
5
|
+
* filesystem path, which keeps process construction on this trusted boundary.
|
|
6
|
+
*/
|
|
7
|
+
import { execa } from 'execa';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { isValidSessionUuid } from '../agent/session.js';
|
|
10
|
+
import { detectEditors } from './detect-editors.js';
|
|
11
|
+
import { openInEditor } from './open-editor.js';
|
|
12
|
+
const DESKTOP_PROMPT_MAX_LENGTH = 1_600;
|
|
13
|
+
const WINDOWS_DESKTOP_URI_ENV = 'NEXUSFLOW_DESKTOP_URI';
|
|
14
|
+
const WINDOWS_DESKTOP_URI_COMMAND = `start "" "%${WINDOWS_DESKTOP_URI_ENV}%"`;
|
|
15
|
+
const DEFAULT_WORKSPACE_PROMPT = 'Read the workspace instructions and implementation plan, inspect the repository state, then begin the task described for this workspace. Ask before making a decision that materially changes scope.';
|
|
16
|
+
function truncateWellFormed(value, maxCodeUnits) {
|
|
17
|
+
let result = '';
|
|
18
|
+
for (const character of value) {
|
|
19
|
+
const codePoint = character.codePointAt(0);
|
|
20
|
+
const safeCharacter = codePoint >= 0xD800 && codePoint <= 0xDFFF ? '\uFFFD' : character;
|
|
21
|
+
if (result.length + safeCharacter.length > maxCodeUnits)
|
|
22
|
+
break;
|
|
23
|
+
result += safeCharacter;
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
/** Build a concise, server-owned kickoff for a provider Desktop composer. */
|
|
28
|
+
export function buildWorkspaceLaunchPrompt(feature) {
|
|
29
|
+
const description = feature.description?.trim();
|
|
30
|
+
if (!description)
|
|
31
|
+
return DEFAULT_WORKSPACE_PROMPT;
|
|
32
|
+
const prefix = `${DEFAULT_WORKSPACE_PROMPT}\n\nWorkspace task: `;
|
|
33
|
+
const remaining = Math.max(0, DESKTOP_PROMPT_MAX_LENGTH - prefix.length);
|
|
34
|
+
return `${prefix}${truncateWellFormed(description, remaining)}`;
|
|
35
|
+
}
|
|
36
|
+
const DESKTOP_TARGETS = [
|
|
37
|
+
{
|
|
38
|
+
id: 'codex-desktop',
|
|
39
|
+
name: 'Codex Desktop',
|
|
40
|
+
scheme: 'codex',
|
|
41
|
+
icon: 'codex',
|
|
42
|
+
description: 'Start a new Codex chat with this folder as its workspace.',
|
|
43
|
+
macAppNames: ['Codex', 'ChatGPT'],
|
|
44
|
+
buildNewUri: (workspacePath, prompt) => `codex://threads/new?path=${encodeURIComponent(workspacePath)}`
|
|
45
|
+
+ (prompt ? `&prompt=${encodeURIComponent(prompt)}` : ''),
|
|
46
|
+
buildResumeUri: (sessionId) => `codex://threads/${encodeURIComponent(sessionId)}`,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'claude-desktop',
|
|
50
|
+
name: 'Claude Desktop',
|
|
51
|
+
scheme: 'claude',
|
|
52
|
+
icon: 'claude',
|
|
53
|
+
description: 'Open Claude Code with this folder selected (Claude asks you to confirm it).',
|
|
54
|
+
macAppNames: ['Claude'],
|
|
55
|
+
buildNewUri: (workspacePath, prompt) => `claude://code/new?folder=${encodeURIComponent(workspacePath)}`
|
|
56
|
+
+ (prompt ? `&q=${encodeURIComponent(prompt)}` : ''),
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
const EDITOR_TARGETS = [
|
|
60
|
+
{ id: 'vscode', name: 'VS Code', command: 'code', icon: 'vscode', description: 'Open the generated VS Code workspace.' },
|
|
61
|
+
{ id: 'vscode-insiders', name: 'VS Code Insiders', command: 'code-insiders', icon: 'vscode-insiders', description: 'Open the generated workspace in Insiders.' },
|
|
62
|
+
{ id: 'cursor', name: 'Cursor', command: 'cursor', icon: 'cursor', description: 'Open the generated workspace in Cursor.' },
|
|
63
|
+
{ id: 'antigravity', name: 'Antigravity', command: 'antigravity', icon: 'antigravity', description: 'Open the workspace in Antigravity.' },
|
|
64
|
+
{ id: 'intellij', name: 'IntelliJ IDEA', command: 'idea', icon: 'intellij', description: 'Open the workspace folder in IntelliJ IDEA.' },
|
|
65
|
+
{ id: 'webstorm', name: 'WebStorm', command: 'webstorm', icon: 'webstorm', description: 'Open the workspace folder in WebStorm.' },
|
|
66
|
+
{ id: 'pycharm', name: 'PyCharm', command: 'charm', icon: 'pycharm', description: 'Open the workspace folder in PyCharm.' },
|
|
67
|
+
{ id: 'sublime', name: 'Sublime Text', command: 'subl', icon: 'sublime', description: 'Open the workspace folder in Sublime Text.' },
|
|
68
|
+
{ id: 'zed', name: 'Zed', command: 'zed', icon: 'zed', description: 'Open the workspace folder in Zed.' },
|
|
69
|
+
{ id: 'windsurf', name: 'Windsurf', command: 'windsurf', icon: 'windsurf', description: 'Open the workspace folder in Windsurf.' },
|
|
70
|
+
];
|
|
71
|
+
function unavailableTarget(definition, kind, unavailableReason) {
|
|
72
|
+
return { ...definition, kind, available: false, unavailableReason };
|
|
73
|
+
}
|
|
74
|
+
async function commandSucceeds(command, args) {
|
|
75
|
+
try {
|
|
76
|
+
const result = await execa(command, args, { reject: false, shell: false });
|
|
77
|
+
return result.exitCode === 0;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Check whether the OS can activate a provider-owned desktop URI scheme. */
|
|
84
|
+
export async function hasDesktopProtocol(definition, platform = process.platform) {
|
|
85
|
+
if (platform === 'win32') {
|
|
86
|
+
const keys = [
|
|
87
|
+
`HKCU\\Software\\Classes\\${definition.scheme}`,
|
|
88
|
+
`HKCR\\${definition.scheme}`,
|
|
89
|
+
];
|
|
90
|
+
for (const key of keys) {
|
|
91
|
+
if (await commandSucceeds('reg.exe', ['query', key]))
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (platform === 'darwin') {
|
|
97
|
+
for (const appName of definition.macAppNames) {
|
|
98
|
+
if (await commandSucceeds('/usr/bin/open', ['-Ra', appName]))
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
if (platform === 'linux' && definition.scheme === 'claude') {
|
|
104
|
+
try {
|
|
105
|
+
const result = await execa('xdg-mime', ['query', 'default', 'x-scheme-handler/claude'], { reject: false, shell: false });
|
|
106
|
+
return result.exitCode === 0 && Boolean(result.stdout?.trim());
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
/** Return every known target so unavailable choices can be explained in the UI. */
|
|
115
|
+
export async function detectWorkspaceLaunchTargets(platform = process.platform) {
|
|
116
|
+
const [desktopAvailability, detectedEditors] = await Promise.all([
|
|
117
|
+
Promise.all(DESKTOP_TARGETS.map((target) => hasDesktopProtocol(target, platform))),
|
|
118
|
+
detectEditors(),
|
|
119
|
+
]);
|
|
120
|
+
const editorAvailability = new Map(detectedEditors.map((editor) => [editor.command, editor.detected]));
|
|
121
|
+
const desktops = DESKTOP_TARGETS.map((target, index) => {
|
|
122
|
+
const base = {
|
|
123
|
+
id: target.id,
|
|
124
|
+
name: target.name,
|
|
125
|
+
icon: target.icon,
|
|
126
|
+
description: target.description,
|
|
127
|
+
};
|
|
128
|
+
return desktopAvailability[index]
|
|
129
|
+
? { ...base, kind: 'ai-app', available: true }
|
|
130
|
+
: unavailableTarget(base, 'ai-app', platform === 'linux' && target.scheme === 'codex'
|
|
131
|
+
? 'Codex Desktop launch is currently supported on Windows and macOS.'
|
|
132
|
+
: `${target.name} is not installed or its link handler is unavailable.`);
|
|
133
|
+
});
|
|
134
|
+
const editors = EDITOR_TARGETS.map((target) => {
|
|
135
|
+
const base = {
|
|
136
|
+
id: target.id,
|
|
137
|
+
name: target.name,
|
|
138
|
+
icon: target.icon,
|
|
139
|
+
description: target.description,
|
|
140
|
+
};
|
|
141
|
+
return editorAvailability.get(target.command)
|
|
142
|
+
? { ...base, kind: 'editor', available: true }
|
|
143
|
+
: unavailableTarget(base, 'editor', `${target.name} was not detected on PATH.`);
|
|
144
|
+
});
|
|
145
|
+
return [...desktops, ...editors];
|
|
146
|
+
}
|
|
147
|
+
export async function openDesktopUri(uri, platform = process.platform) {
|
|
148
|
+
if (platform === 'win32') {
|
|
149
|
+
const parsed = new URL(uri);
|
|
150
|
+
if (!['claude:', 'codex:'].includes(parsed.protocol) || /["\r\n\0]/.test(uri)) {
|
|
151
|
+
throw new Error('Unsupported desktop URI.');
|
|
152
|
+
}
|
|
153
|
+
// Anthropic documents `start "" "claude://..."` as the Windows launcher.
|
|
154
|
+
// Pass the URI through one environment expansion so cmd.exe cannot reinterpret
|
|
155
|
+
// its percent-encoded values as environment-variable references.
|
|
156
|
+
try {
|
|
157
|
+
await execa('cmd.exe', ['/d', '/v:off', '/s', '/c', WINDOWS_DESKTOP_URI_COMMAND], {
|
|
158
|
+
env: { [WINDOWS_DESKTOP_URI_ENV]: uri },
|
|
159
|
+
shell: false,
|
|
160
|
+
windowsHide: true,
|
|
161
|
+
windowsVerbatimArguments: true,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Do not return execa's command string: it contains the local workspace
|
|
166
|
+
// path and the task kickoff embedded in the deep link.
|
|
167
|
+
throw new Error('Windows could not open the selected desktop app. Update or reinstall the app, then try again.');
|
|
168
|
+
}
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (platform === 'darwin') {
|
|
172
|
+
await execa('/usr/bin/open', [uri], { shell: false });
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (platform === 'linux') {
|
|
176
|
+
await execa('xdg-open', [uri], { shell: false });
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
throw new Error('Desktop app launching is not supported on this platform.');
|
|
180
|
+
}
|
|
181
|
+
/** Launch one closed target at a validated absolute workspace directory. */
|
|
182
|
+
export async function launchWorkspaceTarget(targetId, workspacePath, intent = { kind: 'new-workspace' }, platform = process.platform) {
|
|
183
|
+
const absolutePath = path.resolve(workspacePath);
|
|
184
|
+
if (!path.isAbsolute(workspacePath)) {
|
|
185
|
+
throw new Error('Workspace path must be an absolute directory.');
|
|
186
|
+
}
|
|
187
|
+
const desktop = DESKTOP_TARGETS.find((target) => target.id === targetId);
|
|
188
|
+
if (desktop) {
|
|
189
|
+
if (!(await hasDesktopProtocol(desktop, platform))) {
|
|
190
|
+
throw new Error(`${desktop.name} is not available on this computer.`);
|
|
191
|
+
}
|
|
192
|
+
if (intent.kind === 'resume-session') {
|
|
193
|
+
if (!desktop.buildResumeUri) {
|
|
194
|
+
throw new Error(`${desktop.name} does not support opening an existing coding session.`);
|
|
195
|
+
}
|
|
196
|
+
if (!isValidSessionUuid(intent.sessionId)) {
|
|
197
|
+
throw new Error('Invalid desktop session id.');
|
|
198
|
+
}
|
|
199
|
+
await openDesktopUri(desktop.buildResumeUri(intent.sessionId), platform);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
await openDesktopUri(desktop.buildNewUri(absolutePath, intent.prompt), platform);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const editor = EDITOR_TARGETS.find((target) => target.id === targetId);
|
|
206
|
+
if (!editor)
|
|
207
|
+
throw new Error('Unknown workspace launch target.');
|
|
208
|
+
if (intent.kind === 'resume-session') {
|
|
209
|
+
throw new Error('Editors cannot resume an AI coding session.');
|
|
210
|
+
}
|
|
211
|
+
const detected = await detectEditors();
|
|
212
|
+
if (!detected.some((candidate) => candidate.command === editor.command && candidate.detected)) {
|
|
213
|
+
throw new Error(`${editor.name} is not available on this computer.`);
|
|
214
|
+
}
|
|
215
|
+
await openInEditor(editor.command, absolutePath);
|
|
216
|
+
}
|
|
217
|
+
/** Convert a legacy editor command to its closed target id. */
|
|
218
|
+
export function launchTargetIdForEditorCommand(command) {
|
|
219
|
+
return EDITOR_TARGETS.find((target) => target.command === command)?.id ?? null;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=workspace-launch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-launch.js","sourceRoot":"","sources":["../../src/utils/workspace-launch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-launch.test.d.ts","sourceRoot":"","sources":["../../src/utils/workspace-launch.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { execa } from 'execa';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { buildWorkspaceLaunchPrompt, detectWorkspaceLaunchTargets, hasDesktopProtocol, launchTargetIdForEditorCommand, launchWorkspaceTarget, openDesktopUri, } from './workspace-launch.js';
|
|
5
|
+
vi.mock('execa');
|
|
6
|
+
vi.mock('./detect-editors.js', () => ({
|
|
7
|
+
detectEditors: vi.fn().mockResolvedValue([
|
|
8
|
+
{ name: 'VS Code', command: 'code', detected: true },
|
|
9
|
+
{ name: 'VS Code Insiders', command: 'code-insiders', detected: false },
|
|
10
|
+
]),
|
|
11
|
+
}));
|
|
12
|
+
vi.mock('./open-editor.js', () => ({ openInEditor: vi.fn().mockResolvedValue(undefined) }));
|
|
13
|
+
describe('workspace launch catalog', () => {
|
|
14
|
+
beforeEach(() => vi.clearAllMocks());
|
|
15
|
+
it('detects a Windows protocol association without using a shell', async () => {
|
|
16
|
+
vi.mocked(execa).mockResolvedValue({ exitCode: 0 });
|
|
17
|
+
await expect(hasDesktopProtocol({ scheme: 'codex', macAppNames: [] }, 'win32')).resolves.toBe(true);
|
|
18
|
+
expect(execa).toHaveBeenCalledWith('reg.exe', ['query', 'HKCU\\Software\\Classes\\codex'], { reject: false, shell: false });
|
|
19
|
+
});
|
|
20
|
+
it('detects and activates Claude Desktop links on Linux', async () => {
|
|
21
|
+
vi.mocked(execa).mockResolvedValue({ exitCode: 0, stdout: 'claude.desktop\n' });
|
|
22
|
+
await expect(hasDesktopProtocol({ scheme: 'claude', macAppNames: [] }, 'linux')).resolves.toBe(true);
|
|
23
|
+
expect(execa).toHaveBeenCalledWith('xdg-mime', ['query', 'default', 'x-scheme-handler/claude'], { reject: false, shell: false });
|
|
24
|
+
await openDesktopUri('claude://code/new?folder=%2Ftmp%2Fworkspace', 'linux');
|
|
25
|
+
expect(execa).toHaveBeenCalledWith('xdg-open', ['claude://code/new?folder=%2Ftmp%2Fworkspace'], { shell: false });
|
|
26
|
+
});
|
|
27
|
+
it('does not advertise Codex Desktop on Linux', async () => {
|
|
28
|
+
await expect(hasDesktopProtocol({ scheme: 'codex', macAppNames: [] }, 'linux')).resolves.toBe(false);
|
|
29
|
+
expect(execa).not.toHaveBeenCalled();
|
|
30
|
+
});
|
|
31
|
+
it('returns unavailable targets with useful reasons', async () => {
|
|
32
|
+
vi.mocked(execa).mockResolvedValue({ exitCode: 1 });
|
|
33
|
+
const targets = await detectWorkspaceLaunchTargets();
|
|
34
|
+
expect(targets.find((target) => target.id === 'codex-desktop')).toMatchObject({
|
|
35
|
+
kind: 'ai-app',
|
|
36
|
+
available: false,
|
|
37
|
+
});
|
|
38
|
+
expect(targets.find((target) => target.id === 'vscode')).toMatchObject({
|
|
39
|
+
kind: 'editor',
|
|
40
|
+
available: true,
|
|
41
|
+
});
|
|
42
|
+
expect(targets.find((target) => target.id === 'vscode-insiders')).toMatchObject({
|
|
43
|
+
available: false,
|
|
44
|
+
unavailableReason: expect.stringMatching(/not detected/i),
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
it('builds a once-encoded Codex URI and activates it without a shell', async () => {
|
|
48
|
+
vi.mocked(execa).mockImplementation((async (command) => ({
|
|
49
|
+
exitCode: command === 'reg.exe' ? 0 : 0,
|
|
50
|
+
})));
|
|
51
|
+
const workspacePath = path.resolve('work spaces', 'one & two');
|
|
52
|
+
const prompt = buildWorkspaceLaunchPrompt({ description: 'Fix launch & resume' });
|
|
53
|
+
await launchWorkspaceTarget('codex-desktop', workspacePath, { kind: 'new-workspace', prompt }, 'win32');
|
|
54
|
+
expect(execa).toHaveBeenCalledWith('cmd.exe', ['/d', '/v:off', '/s', '/c', 'start "" "%NEXUSFLOW_DESKTOP_URI%"'], {
|
|
55
|
+
env: {
|
|
56
|
+
NEXUSFLOW_DESKTOP_URI: `codex://threads/new?path=${encodeURIComponent(workspacePath)}&prompt=${encodeURIComponent(prompt)}`,
|
|
57
|
+
},
|
|
58
|
+
shell: false,
|
|
59
|
+
windowsHide: true,
|
|
60
|
+
windowsVerbatimArguments: true,
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
it('uses the documented Windows URI dispatcher without reparsing encoded values', async () => {
|
|
64
|
+
vi.mocked(execa).mockResolvedValue({ exitCode: 0 });
|
|
65
|
+
const uri = 'claude://code/new?folder=C%3A%5Cwork%5Cnexus&q=Fix%20one%20%26%20two';
|
|
66
|
+
await openDesktopUri(uri, 'win32');
|
|
67
|
+
expect(execa).toHaveBeenCalledWith('cmd.exe', ['/d', '/v:off', '/s', '/c', 'start "" "%NEXUSFLOW_DESKTOP_URI%"'], {
|
|
68
|
+
env: { NEXUSFLOW_DESKTOP_URI: uri },
|
|
69
|
+
shell: false,
|
|
70
|
+
windowsHide: true,
|
|
71
|
+
windowsVerbatimArguments: true,
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
it('rejects an unsafe Windows desktop URI before invoking cmd.exe', async () => {
|
|
75
|
+
await expect(openDesktopUri('https://example.com', 'win32')).rejects.toThrow('Unsupported desktop URI');
|
|
76
|
+
expect(execa).not.toHaveBeenCalled();
|
|
77
|
+
});
|
|
78
|
+
it('does not expose a Windows desktop URI when activation fails', async () => {
|
|
79
|
+
const uri = 'claude://code/new?folder=C%3A%5Cprivate-workspace&q=Private%20task';
|
|
80
|
+
vi.mocked(execa).mockRejectedValue(new Error(`Command failed: cmd.exe ${uri}`));
|
|
81
|
+
const result = openDesktopUri(uri, 'win32');
|
|
82
|
+
await expect(result).rejects.toThrow('Windows could not open the selected desktop app');
|
|
83
|
+
await expect(result).rejects.not.toThrow(/claude:\/\/|private-workspace|Private%20task/);
|
|
84
|
+
});
|
|
85
|
+
it('builds a once-encoded Claude URI with the workspace kickoff', async () => {
|
|
86
|
+
vi.mocked(execa).mockResolvedValue({ exitCode: 0, stdout: 'claude.desktop\n' });
|
|
87
|
+
const workspacePath = path.resolve('work spaces', 'claude & nexusflow');
|
|
88
|
+
const prompt = buildWorkspaceLaunchPrompt({ description: 'Continue the integration' });
|
|
89
|
+
await launchWorkspaceTarget('claude-desktop', workspacePath, { kind: 'new-workspace', prompt }, 'linux');
|
|
90
|
+
expect(execa).toHaveBeenCalledWith('xdg-open', [`claude://code/new?folder=${encodeURIComponent(workspacePath)}&q=${encodeURIComponent(prompt)}`], { shell: false });
|
|
91
|
+
});
|
|
92
|
+
it('keeps a truncated emoji-bearing kickoff well-formed for URI encoding', () => {
|
|
93
|
+
const basePrompt = buildWorkspaceLaunchPrompt({ description: '' });
|
|
94
|
+
const marker = '\n\nWorkspace task: ';
|
|
95
|
+
const remaining = 1_600 - basePrompt.length - marker.length;
|
|
96
|
+
const description = `${'a'.repeat(remaining - 1)}😀tail`;
|
|
97
|
+
const prompt = buildWorkspaceLaunchPrompt({ description });
|
|
98
|
+
expect(prompt.length).toBeLessThanOrEqual(1_600);
|
|
99
|
+
expect(() => encodeURIComponent(prompt)).not.toThrow();
|
|
100
|
+
expect(prompt.endsWith('a')).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
it('opens an existing Codex thread by its validated technical id', async () => {
|
|
103
|
+
vi.mocked(execa).mockResolvedValue({ exitCode: 0 });
|
|
104
|
+
const workspacePath = path.resolve('workspace');
|
|
105
|
+
const sessionId = '0199a213-81c0-7800-8aa1-bbab2a035a53';
|
|
106
|
+
await launchWorkspaceTarget('codex-desktop', workspacePath, { kind: 'resume-session', sessionId }, 'win32');
|
|
107
|
+
expect(execa).toHaveBeenCalledWith('cmd.exe', ['/d', '/v:off', '/s', '/c', 'start "" "%NEXUSFLOW_DESKTOP_URI%"'], {
|
|
108
|
+
env: { NEXUSFLOW_DESKTOP_URI: `codex://threads/${sessionId}` },
|
|
109
|
+
shell: false,
|
|
110
|
+
windowsHide: true,
|
|
111
|
+
windowsVerbatimArguments: true,
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
it('does not claim that Claude Desktop can resume a local Code session', async () => {
|
|
115
|
+
vi.mocked(execa).mockResolvedValue({ exitCode: 0, stdout: 'claude.desktop\n' });
|
|
116
|
+
await expect(launchWorkspaceTarget('claude-desktop', path.resolve('workspace'), { kind: 'resume-session', sessionId: '0199a213-81c0-7800-8aa1-bbab2a035a53' }, 'linux')).rejects.toThrow(/does not support/i);
|
|
117
|
+
expect(execa).not.toHaveBeenCalledWith('xdg-open', expect.anything(), expect.anything());
|
|
118
|
+
});
|
|
119
|
+
it('never maps arbitrary commands to launch targets', () => {
|
|
120
|
+
expect(launchTargetIdForEditorCommand('code')).toBe('vscode');
|
|
121
|
+
expect(launchTargetIdForEditorCommand('code && calc.exe')).toBeNull();
|
|
122
|
+
});
|
|
123
|
+
it('rejects unknown targets before launching anything', async () => {
|
|
124
|
+
await expect(launchWorkspaceTarget('editor:../../calc', path.resolve('workspace'))).rejects.toThrow('Unknown workspace launch target');
|
|
125
|
+
expect(execa).not.toHaveBeenCalled();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
//# sourceMappingURL=workspace-launch.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-launch.test.js","sourceRoot":"","sources":["../../src/utils/workspace-launch.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrpatronz/nexusflow",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Combine multiple repos into a workspace with rich AI assistant context",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"license": "MIT",
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@agentclientprotocol/sdk": "1.3.0",
|
|
51
|
-
"@anthropic-ai/sdk": "^0.
|
|
51
|
+
"@anthropic-ai/sdk": "^0.116.0",
|
|
52
52
|
"@google/genai": "^2.10.0",
|
|
53
53
|
"@hono/node-server": "^2.0.8",
|
|
54
54
|
"@hono/node-ws": "^1.3.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{_ as e,b as t,g as n,h as r,m as i,t as a}from"./button-cPldH5S4.js";import{St as o,t as s}from"./spinner-DXt6mnJk.js";import{S as ee}from"./useCompositeListItem-DWGFLKqA.js";import{t as te}from"./external-link-BtYhMxno.js";import{n as ne,r as re,t as ie}from"./ScaffoldRepoInline-lfFwOnQu.js";import{t as c}from"./git-branch-Dw55pQWa.js";import{$ as l,A as u,G as ae,H as oe,K as d,M as se,N as f,R as ce,X as le,at as p,et as ue,ft as m,gt as h,i as de,j as fe,k as g,n as pe,nt as me,pt as _,q as he,r as ge,rt as _e,s as ve,ut as ye,z as be}from"./index-BCfJkb0T.js";import{t as v}from"./textarea-BLU5HXmZ.js";var y=r(`zap`,[[`path`,{d:`M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z`,key:`1xq2db`}]]),b=t(e(),1),x={status:`idle`,steps:[]};function xe(){let[e,t]=(0,b.useState)(x),n=(0,b.useRef)(null),r=h(),i=(0,b.useCallback)(()=>{n.current?.close(),n.current=null},[]);return(0,b.useEffect)(()=>i,[i]),{progress:e,start:(0,b.useCallback)(e=>{i(),t({status:`running`,steps:[]});let a=new EventSource(`/api/workspace/create-stream/${encodeURIComponent(e)}`);n.current=a;let o=0;a.addEventListener(`progress`,n=>{o=0;try{let a=JSON.parse(n.data);t({status:a.status===`completed`||a.status===`failed`?a.status:`running`,steps:a.steps??[],error:a.error,workspacePath:a.workspacePath,workspaceId:a.feature?.id??e}),(a.status===`completed`||a.status===`failed`)&&(i(),r.invalidateQueries({queryKey:[`workspaces`]}),r.invalidateQueries({queryKey:[`workspaces-status`]}))}catch{}}),a.onerror=()=>{o+=1,!(a.readyState!==EventSource.CLOSED&&o<5)&&(t(e=>e.status===`running`?{...e,status:`failed`,error:e.error??`Lost connection to the creation stream.`}:e),i())}},[i,r]),reset:(0,b.useCallback)(()=>{i(),t(x)},[i])}}var S=n(),C=`__ad-hoc__`,w=new URLSearchParams(window.location.search).get(`env`)===`vscode`,Se=[{value:`in-place`,icon:y,title:`In-place`,body:`Work directly in the source repos. No branches or worktrees — fastest start.`},{value:`worktree`,icon:c,title:`Isolated worktrees`,body:`A feature branch and worktree per repo. Your source checkouts stay untouched.`}];function Ce({repo:e,value:t,onChange:n,enabled:r}){let i=d(e.path,r),a=(0,b.useMemo)(()=>[...new Set([...i.data?.local??[],...i.data?.remote??[]])],[i.data]),s=`branches-${e.path.replace(/[^a-zA-Z0-9]/g,`-`)}`;return(0,S.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(`span`,{className:`w-40 shrink-0 truncate text-xs`,children:e.name}),(0,S.jsx)(o,{list:s,value:t,onChange:e=>n(e.target.value),placeholder:`existing branch (must exist)`,className:`h-7 font-mono text-xs`}),(0,S.jsx)(`datalist`,{id:s,children:a.map(e=>(0,S.jsx)(`option`,{value:e},e))})]})}function we({step:e}){return(0,S.jsxs)(`li`,{className:`flex items-center gap-3 py-2`,children:[(0,S.jsx)(`span`,{className:i(`grid size-5 shrink-0 place-items-center rounded-full border`,e.status===`completed`&&`border-success bg-success/15 text-success-foreground`,e.status===`running`&&`border-primary text-primary`,e.status===`failed`&&`border-destructive bg-destructive/15 text-destructive-foreground`,e.status===`pending`&&`border-border text-muted-foreground`),children:e.status===`completed`?(0,S.jsx)(_,{className:`size-3`}):e.status===`running`?(0,S.jsx)(s,{className:`size-3`}):e.status===`failed`?(0,S.jsx)(m,{className:`size-3`}):null}),(0,S.jsxs)(`div`,{className:`min-w-0`,children:[(0,S.jsx)(`p`,{className:`text-sm font-medium`,children:e.name}),(0,S.jsx)(`p`,{className:`truncate text-xs text-muted-foreground`,children:e.message})]})]})}function T(){let e=me(),[t]=_e(),n=ae(),r=he(),c=ce(),d=le(),m=be().data?.config,h=oe(),{progress:_,start:y}=xe(),[x,T]=(0,b.useState)(t.get(`project`)??C),[E,Te]=(0,b.useState)(`in-place`),[D,Ee]=(0,b.useState)(``),[O,De]=(0,b.useState)(``),[k,Oe]=(0,b.useState)(``),[A,j]=(0,b.useState)([]),[M,ke]=(0,b.useState)(!1),[N,P]=(0,b.useState)([]),[F,I]=(0,b.useState)(``),[L,R]=(0,b.useState)(``),[z,B]=(0,b.useState)(!1),[V,H]=(0,b.useState)(null),[U,Ae]=(0,b.useState)({}),[je,Me]=(0,b.useState)(!1),[W,G]=(0,b.useState)(null),[K,q]=(0,b.useState)(!1),J=(0,b.useRef)(!1);(0,b.useEffect)(()=>{!J.current&&c.data&&(J.current=!0,P(c.data.filter(e=>e.detected).map(e=>e.name)))},[c.data]);let Y=(0,b.useMemo)(()=>(n.data??[]).find(e=>e.id===x)??null,[n.data,x]),X=(0,b.useMemo)(()=>Y?Y.repos.map(e=>({name:ve(e.path),path:e.path,defaultBranch:e.defaultBranch})):(r.data??[]).filter(e=>A.includes(e.path)),[Y,r.data,A]),Z=E===`in-place`,Ne=(Z?O.trim().length>0:D.trim().length>0)&&X.length>0&&k.trim().length>0,Pe=e=>{I(e),H(null);let t=(d.data??[]).find(t=>t.id===e);R(t?.content??``)},Fe=async()=>{if(!k.trim()){G(`Describe what you are building first — the suggestion is based on it.`);return}G(null),B(!0);try{let e=await l(`/api/workspace/suggest-workflow`,{method:`POST`,body:JSON.stringify({description:k,repos:X})});I(e.suggestedWorkflowId),R(e.customInstructions),H(e.difficulty)}catch(e){G(e instanceof Error?e.message:String(e))}finally{B(!1)}},Ie=async()=>{G(null);let e={mode:E,projectId:Y?.id,...Z?{name:O.trim()}:{branchName:D.trim()},description:k.trim(),repos:X.map(e=>({...e,existingBranch:!Z&&U[e.path]?.trim()?U[e.path].trim():void 0})),assistants:N,teamworkInstructions:L.trim()||void 0};try{let{jobId:t}=await h.mutateAsync(e);y(t)}catch(e){G(e instanceof Error?e.message:String(e))}},Q=m?.defaultEditor&&m.defaultEditor!==`none`?m.defaultEditor:null,$=N.find(e=>de(e)!==null),Le=async()=>{if(_.workspacePath){if(w){window.parent.postMessage({type:`openWorkspaceFolder`,workspacePath:_.workspacePath},`*`);return}if(Q){q(!0);try{await l(`/api/open-editor`,{method:`POST`,body:JSON.stringify({workspacePath:_.workspacePath,command:Q})})}catch(e){G(e instanceof Error?e.message:String(e))}finally{q(!1)}}}};if(_.status!==`idle`){let t=_.steps.find(e=>e.status===`failed`),n=w||!!Q;return(0,S.jsxs)(`div`,{className:`mx-auto max-w-xl animate-fade-in`,children:[(0,S.jsx)(`h1`,{className:`text-xl font-semibold`,children:_.status===`running`?`Setting up your workspace…`:_.status===`completed`?`Workspace ready`:`Workspace creation failed`}),(0,S.jsx)(`ul`,{className:`mt-6 divide-y divide-border rounded-xl border border-border bg-card px-4`,children:_.steps.map(e=>(0,S.jsx)(we,{step:e},e.id))}),_.status===`failed`&&(0,S.jsx)(`p`,{className:`mt-4 text-sm text-destructive-foreground`,children:t?.message??_.error??`Something went wrong.`}),_.status===`completed`&&_.workspacePath&&(0,S.jsx)(`p`,{className:`mt-4 truncate font-mono text-xs text-muted-foreground`,children:_.workspacePath}),_.status===`completed`&&$&&(0,S.jsx)(`p`,{className:`mt-2 text-xs text-muted-foreground`,children:`Embedded start allows edits inside this workspace; you can switch to Review only in chat.`}),W&&(0,S.jsx)(`p`,{className:`mt-2 text-sm text-destructive-foreground`,children:W}),(0,S.jsxs)(`div`,{className:`mt-6 flex gap-2`,children:[_.status===`completed`&&_.workspaceId&&(0,S.jsxs)(S.Fragment,{children:[$&&(0,S.jsxs)(a,{onClick:()=>e(`/workspaces/${encodeURIComponent(_.workspaceId)}`,{state:{chatLaunch:ge($,{kickoff:`Read the workspace instructions and implementation plan, inspect the repository state, then begin the task described for this workspace. Ask before making a decision that materially changes scope.`,executionProfile:`workspace-write`})}}),children:[(0,S.jsx)(p,{}),`Start editing with `,pe($)]}),(0,S.jsx)(a,{variant:$?`outline`:void 0,onClick:()=>e(`/workspaces/${encodeURIComponent(_.workspaceId)}`),children:`Open workspace`}),n&&(0,S.jsxs)(a,{variant:`outline`,onClick:Le,disabled:K,children:[K?(0,S.jsx)(s,{}):(0,S.jsx)(te,{}),`Open in editor`]})]}),_.status===`failed`&&(0,S.jsx)(a,{variant:`outline`,onClick:()=>window.location.reload(),children:`Start over`}),_.status===`running`&&(0,S.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`This can take a moment for large repositories.`})]})]})}return(0,S.jsxs)(`div`,{className:`mx-auto max-w-xl animate-fade-in`,children:[(0,S.jsxs)(`header`,{className:`mb-6`,children:[(0,S.jsx)(`h1`,{className:`text-xl font-semibold`,children:`Start work`}),(0,S.jsx)(`p`,{className:`mt-1 text-sm text-muted-foreground`,children:`Pick where the work happens and how isolated it should be.`})]}),(0,S.jsxs)(`div`,{className:`flex flex-col gap-6`,children:[(0,S.jsxs)(`section`,{children:[(0,S.jsx)(`span`,{className:`mb-1.5 block text-sm font-medium`,children:`Project`}),(0,S.jsxs)(g,{value:x,onValueChange:e=>typeof e==`string`&&T(e),children:[(0,S.jsx)(se,{className:`w-full`,"aria-label":`Project`,children:(0,S.jsx)(f,{children:Y?Y.name:`Ad-hoc — pick repositories manually`})}),(0,S.jsxs)(fe,{alignItemWithTrigger:!1,children:[(n.data??[]).map(e=>(0,S.jsx)(u,{value:e.id,children:e.name},e.id)),(0,S.jsx)(u,{value:C,children:`Ad-hoc — pick repositories manually`})]})]}),Y?(0,S.jsx)(`ul`,{className:`mt-2 flex flex-col gap-0.5`,children:Y.repos.map(e=>(0,S.jsx)(`li`,{className:`truncate font-mono text-xs text-muted-foreground`,children:e.path},e.path))}):(0,S.jsxs)(`div`,{className:`mt-2`,children:[(0,S.jsx)(ne,{repos:r.data??[],selectedPaths:A,onToggle:e=>j(t=>t.includes(e.path)?t.filter(t=>t!==e.path):[...t,e.path]),loading:r.isLoading}),(0,S.jsx)(ie,{onCreated:e=>j(t=>[...t,e.path])})]}),(n.data??[]).length===0&&!n.isLoading&&(0,S.jsxs)(`p`,{className:`mt-2 text-xs text-muted-foreground`,children:[`Tip: `,(0,S.jsx)(ue,{to:`/projects`,className:`text-primary hover:underline`,children:`register a project`}),` to skip repo picking next time.`]})]}),(0,S.jsxs)(`section`,{children:[(0,S.jsx)(`span`,{className:`mb-1.5 block text-sm font-medium`,children:`How do you want to work?`}),(0,S.jsx)(`div`,{role:`radiogroup`,"aria-label":`Work mode`,className:`grid gap-3 sm:grid-cols-2`,onKeyDown:e=>{if([`ArrowRight`,`ArrowDown`,`ArrowLeft`,`ArrowUp`].includes(e.key)){e.preventDefault();let t=E===`in-place`?`worktree`:`in-place`;Te(t),document.getElementById(`mode-${t}`)?.focus()}},children:Se.map(e=>(0,S.jsxs)(`button`,{id:`mode-${e.value}`,type:`button`,role:`radio`,"aria-checked":E===e.value,tabIndex:E===e.value?0:-1,onClick:()=>Te(e.value),className:i(`cursor-pointer rounded-xl border p-4 text-left outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring`,E===e.value?`border-primary bg-primary/5 ring-1 ring-primary`:`border-border bg-card hover:border-foreground/20`),children:[(0,S.jsx)(e.icon,{className:i(`size-4`,E===e.value?`text-primary`:`text-muted-foreground`)}),(0,S.jsx)(`p`,{className:`mt-2 text-sm font-semibold`,children:e.title}),(0,S.jsx)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:e.body})]},e.value))})]}),(0,S.jsx)(`section`,{children:Z?(0,S.jsxs)(`label`,{className:`block`,children:[(0,S.jsx)(`span`,{className:`mb-1 block text-sm font-medium`,children:`Workspace name`}),(0,S.jsx)(o,{value:O,onChange:e=>De(e.target.value),placeholder:`e.g. Fix invoice rounding`})]}):(0,S.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,S.jsxs)(`label`,{className:`block`,children:[(0,S.jsx)(`span`,{className:`mb-1 block text-sm font-medium`,children:`Feature branch`}),(0,S.jsx)(o,{value:D,onChange:e=>Ee(e.target.value),placeholder:`e.g. feature/invoice-rounding`,className:`font-mono`})]}),X.length>0&&(0,S.jsxs)(`details`,{className:`rounded-lg border border-border px-3 py-2`,onToggle:e=>Me(e.target.open),children:[(0,S.jsx)(`summary`,{className:`cursor-pointer text-xs font-medium text-muted-foreground`,children:`Use an existing branch for specific repos (optional)`}),(0,S.jsx)(`div`,{className:`mt-2 flex flex-col gap-2`,children:X.map(e=>(0,S.jsx)(Ce,{repo:e,enabled:je,value:U[e.path]??``,onChange:t=>Ae(n=>({...n,[e.path]:t}))},e.path))})]})]})}),(0,S.jsx)(`section`,{children:(0,S.jsxs)(`label`,{className:`block`,children:[(0,S.jsx)(`span`,{className:`mb-1 block text-sm font-medium`,children:`What are you building?`}),(0,S.jsx)(v,{value:k,onChange:e=>Oe(e.target.value),placeholder:`A short description — your AI assistant reads this to plan the work.`,rows:3})]})}),(0,S.jsxs)(`section`,{className:`rounded-xl border border-border`,children:[(0,S.jsxs)(`button`,{type:`button`,onClick:()=>ke(e=>!e),className:`flex w-full items-center justify-between px-4 py-3 text-sm font-medium hover:bg-accent`,"aria-expanded":M,children:[`Advanced`,(0,S.jsx)(ee,{className:i(`size-4 text-muted-foreground transition-transform`,M&&`rotate-180`)})]}),M&&(0,S.jsxs)(`div`,{className:`flex flex-col gap-4 border-t border-border p-4`,children:[(0,S.jsxs)(`div`,{children:[(0,S.jsx)(`span`,{className:`mb-1.5 block text-sm font-medium`,children:`AI assistants`}),(0,S.jsx)(`div`,{className:`flex flex-wrap gap-3`,children:(c.data??[]).map(e=>(0,S.jsxs)(`label`,{className:i(`flex cursor-pointer items-center gap-2 rounded-lg border border-border px-3 py-1.5 text-sm`,!e.detected&&`opacity-50`),children:[(0,S.jsx)(re,{checked:N.includes(e.name),onCheckedChange:()=>P(t=>t.includes(e.name)?t.filter(t=>t!==e.name):[...t,e.name])}),e.displayName]},e.name))})]}),(0,S.jsxs)(`div`,{children:[(0,S.jsxs)(`div`,{className:`mb-1.5 flex items-center justify-between`,children:[(0,S.jsx)(`span`,{className:`text-sm font-medium`,children:`Teamwork strategy`}),(0,S.jsxs)(a,{size:`xs`,variant:`outline`,onClick:Fe,disabled:z,children:[z?(0,S.jsx)(s,{}):(0,S.jsx)(p,{}),`Suggest with AI`]})]}),(0,S.jsxs)(g,{value:F,onValueChange:e=>typeof e==`string`&&Pe(e),children:[(0,S.jsx)(se,{className:`w-full`,"aria-label":`Teamwork strategy`,children:(0,S.jsx)(f,{children:(d.data??[]).find(e=>e.id===F)?.name??`None`})}),(0,S.jsxs)(fe,{alignItemWithTrigger:!1,children:[(0,S.jsx)(u,{value:``,children:`None`}),(d.data??[]).map(e=>(0,S.jsx)(u,{value:e.id,children:e.name},e.id))]})]}),V&&(0,S.jsxs)(`p`,{className:`mt-1.5 text-xs text-muted-foreground`,children:[`AI classified this task as `,(0,S.jsx)(`span`,{className:`font-medium`,children:V}),` difficulty.`]}),(0,S.jsx)(v,{value:L,onChange:e=>R(e.target.value),placeholder:`Cooperation instructions for the agent team (editable — prefilled by the strategy pick or AI suggestion).`,rows:4,className:`mt-2 font-mono text-xs`})]})]})]}),W&&(0,S.jsx)(`p`,{className:`text-sm text-destructive-foreground`,children:W}),(0,S.jsxs)(`div`,{className:`flex items-center justify-between gap-4 border-t border-border pt-4`,children:[(0,S.jsxs)(`p`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,S.jsx)(ye,{className:`size-3.5`}),X.length,` repositor`,X.length===1?`y`:`ies`,` selected`]}),(0,S.jsxs)(a,{onClick:Ie,disabled:!Ne||h.isPending,children:[h.isPending?(0,S.jsx)(s,{}):null,Z?`Start working`:`Create workspace`]})]})]})]})}export{T as StartWorkPage};
|