@workflow-code/cli 0.2.4-20260929001 → 0.2.4-20261010001.codex-cli-web
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/{chunk-SGW3CIWG.js → chunk-7WEXRL5A.js} +64 -22
- package/dist/{chunk-PI54SAI5.js → chunk-BP2VDZQV.js} +17 -17
- package/dist/{chunk-VMFPUXPG.js → chunk-G7PZDTYW.js} +1 -1
- package/dist/{chunk-PCNMKSS4.js → chunk-J2JMC4MZ.js} +1 -1
- package/dist/{local-ISDXTMSA.js → chunk-T4FXQ7AQ.js} +8 -7
- package/dist/index.js +12 -6
- package/dist/local-7HMZSBG2.js +28 -0
- package/dist/{mcp-O6PS2QTB.js → mcp-5H6U7H4S.js} +5 -5
- package/dist/web/codicons/codicon.css +708 -0
- package/dist/web/codicons/codicon.csv +536 -0
- package/dist/web/codicons/codicon.html +12111 -0
- package/dist/web/codicons/codicon.svg +1 -0
- package/dist/web/codicons/codicon.ttf +0 -0
- package/dist/web/codicons/codiconsLibrary.ts +659 -0
- package/dist/web/codicons/metadata.json +2682 -0
- package/dist/web/theme.css +72 -0
- package/dist/web/worker.mjs +208 -0
- package/dist/web/workflow-ui.css +1710 -0
- package/dist/web/workflow-ui.js +5337 -0
- package/dist/web-U23BFLG4.js +1523 -0
- package/dist/{workspace-I4I5VJI3.js → workspace-G7SB6MS5.js} +78 -7
- package/package.json +10 -5
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
color-scheme: light;
|
|
3
|
+
--vscode-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
4
|
+
--vscode-editor-font-family: "SFMono-Regular", Consolas, monospace;
|
|
5
|
+
--vscode-editor-foreground: #333333;
|
|
6
|
+
--vscode-editor-background: #ffffff;
|
|
7
|
+
--vscode-sideBar-background: #f8f8f8;
|
|
8
|
+
--vscode-panel-border: #e5e5e5;
|
|
9
|
+
--vscode-descriptionForeground: #777777;
|
|
10
|
+
--vscode-focusBorder: #0090f1;
|
|
11
|
+
--vscode-toolbar-hoverBackground: #e8e8e8;
|
|
12
|
+
--vscode-list-hoverBackground: #eeeeee;
|
|
13
|
+
--vscode-list-inactiveSelectionBackground: #e4e6f1;
|
|
14
|
+
--vscode-list-activeSelectionForeground: #ffffff;
|
|
15
|
+
--vscode-input-background: #ffffff;
|
|
16
|
+
--vscode-input-foreground: #333333;
|
|
17
|
+
--vscode-input-border: #dedede;
|
|
18
|
+
--vscode-input-placeholderForeground: #888888;
|
|
19
|
+
--vscode-dropdown-background: #ffffff;
|
|
20
|
+
--vscode-dropdown-foreground: #333333;
|
|
21
|
+
--vscode-textCodeBlock-background: #f5f5f5;
|
|
22
|
+
--vscode-textBlockQuote-border: #d2d2d2;
|
|
23
|
+
--vscode-textBlockQuote-background: #f6f6f6;
|
|
24
|
+
--vscode-textLink-foreground: #006ab1;
|
|
25
|
+
--vscode-errorForeground: #c72e2e;
|
|
26
|
+
--vscode-button-background: #0078d4;
|
|
27
|
+
--vscode-button-foreground: #ffffff;
|
|
28
|
+
--vscode-button-secondaryBackground: #eeeeee;
|
|
29
|
+
--vscode-button-secondaryForeground: #333333;
|
|
30
|
+
--vscode-editorWidget-background: #ffffff;
|
|
31
|
+
--vscode-progressBar-background: #16825d;
|
|
32
|
+
--vscode-menu-background: #ffffff;
|
|
33
|
+
--vscode-menu-foreground: #333333;
|
|
34
|
+
--vscode-menu-selectionBackground: #e8e8e8;
|
|
35
|
+
--vscode-menu-selectionForeground: #333333;
|
|
36
|
+
}
|
|
37
|
+
:root[data-theme=dark] {
|
|
38
|
+
color-scheme: dark;
|
|
39
|
+
--vscode-editor-foreground: #cccccc;
|
|
40
|
+
--vscode-editor-background: #1f1f1f;
|
|
41
|
+
--vscode-sideBar-background: #181818;
|
|
42
|
+
--vscode-panel-border: #303030;
|
|
43
|
+
--vscode-descriptionForeground: #999999;
|
|
44
|
+
--vscode-toolbar-hoverBackground: #333333;
|
|
45
|
+
--vscode-list-hoverBackground: #2b2b2b;
|
|
46
|
+
--vscode-list-inactiveSelectionBackground: #37373d;
|
|
47
|
+
--vscode-input-background: #252525;
|
|
48
|
+
--vscode-input-foreground: #cccccc;
|
|
49
|
+
--vscode-input-border: #3c3c3c;
|
|
50
|
+
--vscode-dropdown-background: #252525;
|
|
51
|
+
--vscode-dropdown-foreground: #cccccc;
|
|
52
|
+
--vscode-textCodeBlock-background: #292929;
|
|
53
|
+
--vscode-textBlockQuote-border: #555555;
|
|
54
|
+
--vscode-textBlockQuote-background: #252525;
|
|
55
|
+
--vscode-textLink-foreground: #4daafc;
|
|
56
|
+
--vscode-errorForeground: #f48771;
|
|
57
|
+
--vscode-button-secondaryBackground: #333333;
|
|
58
|
+
--vscode-button-secondaryForeground: #cccccc;
|
|
59
|
+
--vscode-editorWidget-background: #252525;
|
|
60
|
+
--vscode-menu-background: #252525;
|
|
61
|
+
--vscode-menu-foreground: #cccccc;
|
|
62
|
+
--vscode-menu-selectionBackground: #3c3c3c;
|
|
63
|
+
--vscode-menu-selectionForeground: #ffffff;
|
|
64
|
+
}
|
|
65
|
+
#chats { flex: 1; }
|
|
66
|
+
.web-account { display: flex; align-items: center; gap: 10px; flex-shrink: 0; margin: auto 8px 8px; padding: 10px; min-height: 44px; border: none; border-top: 1px solid var(--vscode-panel-border); background: transparent; text-align: left; }
|
|
67
|
+
.web-account > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
68
|
+
.web-account:hover { background: var(--vscode-toolbar-hoverBackground); }
|
|
69
|
+
.web-avatar { display: grid; place-items: center; width: 24px; height: 24px; flex-shrink: 0; position: relative; }
|
|
70
|
+
.web-avatar img { position: absolute; width: 24px; height: 24px; object-fit: cover; border-radius: 50%; }
|
|
71
|
+
.web-preview { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; font: 12px/1.6 var(--vscode-editor-font-family); }
|
|
72
|
+
@media (max-width: 680px) { .web-account { margin: 0 8px; min-height: 36px; padding: 6px 10px; } }
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { readFile, writeFile, readdir, rm, stat, mkdir, link } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
5
|
+
import { register } from 'tsx/esm/api';
|
|
6
|
+
import { resolve } from 'import-meta-resolve';
|
|
7
|
+
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
8
|
+
let ts;
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const write = process.stdout.write.bind(process.stdout);
|
|
12
|
+
const send = (kind, value) => write(`__WORKFLOW_WEB__${JSON.stringify({ kind, value })}\n`);
|
|
13
|
+
console.log = console.error;
|
|
14
|
+
const controller = new AbortController();
|
|
15
|
+
process.on('SIGTERM', () => controller.abort(new Error('Stopped.')));
|
|
16
|
+
process.on('SIGINT', () => controller.abort(new Error('Stopped.')));
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
async function requiresSystemAi(directory) {
|
|
20
|
+
const skipped = new Set(['node_modules', 'vendor', 'dist', 'out', 'build', 'test', 'tests', '__tests__', 'fixtures']);
|
|
21
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
22
|
+
if (entry.name.startsWith('.') || skipped.has(entry.name.toLowerCase())) { continue; }
|
|
23
|
+
const file = path.join(directory, entry.name);
|
|
24
|
+
if (entry.isDirectory()) { if (await requiresSystemAi(file)) { return true; } continue; }
|
|
25
|
+
if (!entry.isFile() || !/\.[cm]?[jt]sx?$/.test(entry.name) || /(?:\.d|\.test|\.spec)\.[cm]?[jt]sx?$/.test(entry.name) || (await stat(file)).size > 1024 * 1024) { continue; }
|
|
26
|
+
const source = ts.createSourceFile(file, await readFile(file, 'utf8'), ts.ScriptTarget.Latest, true);
|
|
27
|
+
let required = false;
|
|
28
|
+
const visit = (node) => {
|
|
29
|
+
if (required) { return; }
|
|
30
|
+
if (ts.isCallExpression(node)) {
|
|
31
|
+
const expression = node.expression;
|
|
32
|
+
const name = ts.isPropertyAccessExpression(expression) ? expression.name.text
|
|
33
|
+
: ts.isIdentifier(expression) ? expression.text
|
|
34
|
+
: ts.isElementAccessExpression(expression) && ts.isStringLiteral(expression.argumentExpression) ? expression.argumentExpression.text : undefined;
|
|
35
|
+
if (name === 'getServerLLMCredentials' || name === 'createAgentProjectParamResolver') { required = true; return; }
|
|
36
|
+
}
|
|
37
|
+
ts.forEachChild(node, visit);
|
|
38
|
+
};
|
|
39
|
+
visit(source); if (required) { return true; }
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const request = JSON.parse(readFileSync(0, 'utf8'));
|
|
46
|
+
const projectDir = path.resolve(request.project?.folderPath ?? request.paths?.[0]);
|
|
47
|
+
let coreUrl;
|
|
48
|
+
try { coreUrl = resolve('workflow-code', pathToFileURL(path.join(projectDir, 'package.json')).href); }
|
|
49
|
+
catch { throw new Error('Install workflow-code in the project before starting workflow-code web.'); }
|
|
50
|
+
const corePath = fileURLToPath(coreUrl);
|
|
51
|
+
let manifestDir = path.dirname(corePath);
|
|
52
|
+
let coreManifest;
|
|
53
|
+
for (let depth = 0; depth < 12; depth++) {
|
|
54
|
+
try {
|
|
55
|
+
const manifest = JSON.parse(readFileSync(path.join(manifestDir, 'package.json'), 'utf8'));
|
|
56
|
+
if (manifest.name === 'workflow-code') { coreManifest = manifest; break; }
|
|
57
|
+
} catch {}
|
|
58
|
+
const parent = path.dirname(manifestDir);
|
|
59
|
+
if (parent === manifestDir) break;
|
|
60
|
+
manifestDir = parent;
|
|
61
|
+
}
|
|
62
|
+
if (!coreManifest) { throw new Error('Cannot identify the project workflow-code version.'); }
|
|
63
|
+
ts = (await import(resolve('typescript', coreUrl))).default;
|
|
64
|
+
const tsconfig = path.join(projectDir, 'tsconfig.json');
|
|
65
|
+
register({ tsconfig: await stat(tsconfig).then(() => tsconfig, () => false) });
|
|
66
|
+
const { inspectLocalWorkflowStructure, resolveLocalWorkflowParams, runLocalWorkflowWithReport, createKanbanArtifactEntryPath,
|
|
67
|
+
createLocalWorkflowFileStore, createServerWorkflowFileStore, createWorkflowFileStore,
|
|
68
|
+
createLocalWorkflowKVStore, createWorkflowKVContext, createWorkflowPersistentValueContext,
|
|
69
|
+
listLocalWorkflowKVEntries, deleteLocalWorkflowKVEntry, getKnowledgeDocument, listKnowledgeDocuments,
|
|
70
|
+
} = await import(coreUrl);
|
|
71
|
+
if (request.method === 'inspect') {
|
|
72
|
+
const projects = [];
|
|
73
|
+
const errors = [];
|
|
74
|
+
for (const folderPath of request.paths) {
|
|
75
|
+
try {
|
|
76
|
+
const pkg = JSON.parse(readFileSync(path.join(folderPath, 'package.json'), 'utf8'));
|
|
77
|
+
const structure = inspectLocalWorkflowStructure({ workflowDir: folderPath });
|
|
78
|
+
const parameters = (entry) => ({ fields: entry.params ?? [], paramLayout: entry.paramLayout, paramResolver: entry.paramResolver, tools: entry.tools });
|
|
79
|
+
projects.push({
|
|
80
|
+
id: pkg.id,
|
|
81
|
+
runtime: { coreVersion: coreManifest.version, corePath },
|
|
82
|
+
folderPath,
|
|
83
|
+
name: pkg.workflowCode?.projectInfo?.localizedNames?.['zh-CN'] ?? pkg.name ?? path.basename(folderPath),
|
|
84
|
+
projectType: structure.projectType,
|
|
85
|
+
...parameters(structure),
|
|
86
|
+
entrypoints: (structure.entrypoints ?? []).map((entry) => ({ id: entry.id, title: entry.title, ...parameters(entry) })),
|
|
87
|
+
defaultEntrypoint: structure.defaultEntrypoint,
|
|
88
|
+
artifactEntry: structure.kanban ? createKanbanArtifactEntryPath(structure.kanban) : undefined,
|
|
89
|
+
conversation: structure.conversation,
|
|
90
|
+
requiresLogin: await requiresSystemAi(folderPath),
|
|
91
|
+
});
|
|
92
|
+
} catch (error) { errors.push(`${folderPath}: ${error.message}`); }
|
|
93
|
+
}
|
|
94
|
+
send('result', { projects, errors });
|
|
95
|
+
} else if (request.project?.folderPath) {
|
|
96
|
+
const projectKey = createHash('sha256').update(request.project.folderPath).digest('hex').slice(0, 24);
|
|
97
|
+
const dataDir = path.join(request.storageDir, projectKey);
|
|
98
|
+
const storage = { host: 'local', local: { kvStoreDir: path.join(dataDir, 'kv'), persistentValueStoreDir: path.join(dataDir, 'values') } };
|
|
99
|
+
const filesDir = path.join(dataDir, 'files');
|
|
100
|
+
const createdFiles = [];
|
|
101
|
+
const managed = createServerWorkflowFileStore({ rootDir: filesDir, workflowName: request.project.id, conversationId: request.conversationId });
|
|
102
|
+
const createFile = async (input) => {
|
|
103
|
+
const file = await managed.createFile(input);
|
|
104
|
+
const previewDir = path.join(filesDir, file.id, 'preview');
|
|
105
|
+
await mkdir(previewDir);
|
|
106
|
+
const previewPath = path.join(previewDir, path.basename(file.name));
|
|
107
|
+
await link(path.join(filesDir, file.id, 'content'), previewPath);
|
|
108
|
+
const reference = { ...file, storage: 'local', url: undefined, path: previewPath };
|
|
109
|
+
await writeFile(path.join(filesDir, file.id, 'metadata.json'), JSON.stringify(reference));
|
|
110
|
+
createdFiles.push(reference);
|
|
111
|
+
if (request.method === 'run') { send('event', { type: 'file_created', file: reference, runId: request.runId }); }
|
|
112
|
+
return reference;
|
|
113
|
+
};
|
|
114
|
+
const readManagedFile = async (id) => {
|
|
115
|
+
if (typeof id !== 'string' || !/^wf_[a-f0-9]{32}$/.test(id)) { throw new Error('Invalid managed file id.'); }
|
|
116
|
+
const reference = JSON.parse(await readFile(path.join(filesDir, id, 'metadata.json'), 'utf8'));
|
|
117
|
+
return { reference, path: reference.path };
|
|
118
|
+
};
|
|
119
|
+
if (request.method === 'resolve') {
|
|
120
|
+
send('result', await resolveLocalWorkflowParams({
|
|
121
|
+
workflowDir: request.project.folderPath,
|
|
122
|
+
entrypointId: request.entrypointId,
|
|
123
|
+
request: request.request,
|
|
124
|
+
storage,
|
|
125
|
+
abortSignal: controller.signal,
|
|
126
|
+
}));
|
|
127
|
+
} else if (request.method === 'run') {
|
|
128
|
+
const report = await runLocalWorkflowWithReport({
|
|
129
|
+
workflowDir: request.project.folderPath,
|
|
130
|
+
args: request.args,
|
|
131
|
+
entrypointId: request.entrypointId,
|
|
132
|
+
conversationId: request.conversationId,
|
|
133
|
+
runId: request.runId,
|
|
134
|
+
storage,
|
|
135
|
+
fileStore: createWorkflowFileStore({ resolveStore: createLocalWorkflowFileStore({ rootDir: filesDir, allowAbsolutePaths: true }), createFile }),
|
|
136
|
+
toolPermissionPolicies: request.toolPermissionPolicies,
|
|
137
|
+
userInput: {
|
|
138
|
+
__workflowResumeRuntimeEventAfterRequestId: request.resumeAfterRequestId,
|
|
139
|
+
getResolvedInput: (id) => {
|
|
140
|
+
const input = request.resolvedInputs?.find((input) => input.requestId === id);
|
|
141
|
+
return input && { ...input, submittedAt: new Date(input.submittedAt), request: input.request && { ...input.request, createdAt: new Date(input.request.createdAt) } };
|
|
142
|
+
},
|
|
143
|
+
requestInput: () => undefined,
|
|
144
|
+
},
|
|
145
|
+
abortSignal: controller.signal,
|
|
146
|
+
onRuntimeEvent: (event) => send('event', event),
|
|
147
|
+
});
|
|
148
|
+
const data = report.result?.data;
|
|
149
|
+
const items = data?.output?.items ?? data?.items ?? report.outputs?.flatMap((entry) => entry.output?.items ?? []) ?? [];
|
|
150
|
+
send('result', { ...report, output: { items }, files: createdFiles });
|
|
151
|
+
} else if (request.method === 'upload') {
|
|
152
|
+
if (!Array.isArray(request.files) || request.files.length > 32) { throw new Error('Too many attachments.'); }
|
|
153
|
+
const references = [];
|
|
154
|
+
for (const file of request.files) {
|
|
155
|
+
if (typeof file.name !== 'string') { throw new Error('Invalid attachment.'); }
|
|
156
|
+
if (typeof file.path === 'string') {
|
|
157
|
+
const info = await stat(file.path);
|
|
158
|
+
if (!info.isFile() || info.size > 50 * 1024 * 1024) { throw new Error('Attachment exceeds 50 MiB or is not a file.'); }
|
|
159
|
+
}
|
|
160
|
+
if (file.data?.length > 70 * 1024 * 1024) { throw new Error('Attachment exceeds 50 MiB.'); }
|
|
161
|
+
const buffer = typeof file.path === 'string' ? await readFile(file.path) : Buffer.from(file.data ?? '', 'base64');
|
|
162
|
+
references.push(await createFile({ name: file.name, mimeType: file.mimeType, buffer }));
|
|
163
|
+
}
|
|
164
|
+
send('result', references);
|
|
165
|
+
} else if (request.method === 'file') {
|
|
166
|
+
send('result', await readManagedFile(request.id));
|
|
167
|
+
} else if (request.method === 'delete-files') {
|
|
168
|
+
for (const id of request.ids ?? []) {
|
|
169
|
+
const file = await readManagedFile(id).catch(() => undefined);
|
|
170
|
+
if (file?.reference.conversationId === request.conversationId) { await rm(path.join(filesDir, id), { recursive: true, force: true }); }
|
|
171
|
+
}
|
|
172
|
+
send('result', { deleted: true });
|
|
173
|
+
} else if (request.method === 'resource') {
|
|
174
|
+
const target = request.target ?? {};
|
|
175
|
+
const rootDir = request.kind === 'knowledge' ? path.join(dataDir, 'values') : path.join(dataDir, 'kv');
|
|
176
|
+
const store = createLocalWorkflowKVStore({ rootDir, storageKind: request.kind === 'knowledge' ? 'persistent_value' : 'kv' });
|
|
177
|
+
const context = request.kind === 'knowledge'
|
|
178
|
+
? createWorkflowPersistentValueContext({ store, projectId: request.project.id, conversationId: request.conversationId })
|
|
179
|
+
: createWorkflowKVContext({ store, projectId: request.project.id, conversationId: request.conversationId });
|
|
180
|
+
if (request.kind === 'knowledge') {
|
|
181
|
+
send('result', target.documentId ? await getKnowledgeDocument({ persistentValue: context }, target.documentId) : await listKnowledgeDocuments({ persistentValue: context }));
|
|
182
|
+
} else if (target.key) {
|
|
183
|
+
send('result', await (target.scope === 'conversation' ? context.conversation : context).getValue(target.key) ?? null);
|
|
184
|
+
} else {
|
|
185
|
+
send('result', await listLocalWorkflowKVEntries({ rootDir, storageKind: 'kv', projectId: request.project.id, scope: target.scope === 'conversation' ? 'conversation' : 'project', conversationId: target.scope === 'conversation' ? request.conversationId : undefined, pageSize: 100 }));
|
|
186
|
+
}
|
|
187
|
+
} else if (request.method === 'delete-conversation') {
|
|
188
|
+
for (const [storageKind, rootDir] of [['kv', path.join(dataDir, 'kv')], ['persistent_value', path.join(dataDir, 'values')]]) {
|
|
189
|
+
const entries = [];
|
|
190
|
+
let cursor;
|
|
191
|
+
do {
|
|
192
|
+
const page = await listLocalWorkflowKVEntries({ rootDir, storageKind, projectId: request.project.id, scope: 'conversation', conversationId: request.conversationId, pageSize: 100, cursor });
|
|
193
|
+
entries.push(...page.items); cursor = page.nextCursor;
|
|
194
|
+
} while (cursor);
|
|
195
|
+
for (const entry of entries) { await deleteLocalWorkflowKVEntry({ ...entry, rootDir }); }
|
|
196
|
+
}
|
|
197
|
+
for (const directory of await readdir(filesDir).catch(() => [])) {
|
|
198
|
+
if (!/^wf_[a-f0-9]{32}$/.test(directory)) { continue; }
|
|
199
|
+
const file = await readManagedFile(directory).catch(() => undefined);
|
|
200
|
+
if (file?.reference.conversationId === request.conversationId) { await rm(path.join(filesDir, directory), { recursive: true, force: true }); }
|
|
201
|
+
}
|
|
202
|
+
send('result', { deleted: true });
|
|
203
|
+
} else { throw new Error('Unknown runtime method.'); }
|
|
204
|
+
} else { throw new Error('Unknown runtime method.'); }
|
|
205
|
+
} catch (error) {
|
|
206
|
+
write(`__WORKFLOW_WEB__${JSON.stringify({ kind: 'error', error: error.message, status: error.metadata?.status })}\n`);
|
|
207
|
+
process.exitCode = 1;
|
|
208
|
+
}
|