@aion0/forge 0.5.44 → 0.5.46

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.
Files changed (58) hide show
  1. package/RELEASE_NOTES.md +3 -15
  2. package/package.json +1 -1
  3. package/tsconfig.json +3 -1
  4. package/intellij-plugin/README.md +0 -53
  5. package/intellij-plugin/build.gradle.kts +0 -60
  6. package/intellij-plugin/gradle/gradle-daemon-jvm.properties +0 -12
  7. package/intellij-plugin/gradle.properties +0 -9
  8. package/intellij-plugin/publish.sh +0 -78
  9. package/intellij-plugin/settings.gradle.kts +0 -7
  10. package/intellij-plugin/src/main/kotlin/com/aion0/forge/action/LoginAction.kt +0 -49
  11. package/intellij-plugin/src/main/kotlin/com/aion0/forge/action/LogoutAction.kt +0 -18
  12. package/intellij-plugin/src/main/kotlin/com/aion0/forge/action/OpenWebUIAction.kt +0 -13
  13. package/intellij-plugin/src/main/kotlin/com/aion0/forge/action/SwitchConnectionAction.kt +0 -26
  14. package/intellij-plugin/src/main/kotlin/com/aion0/forge/api/ForgeClient.kt +0 -115
  15. package/intellij-plugin/src/main/kotlin/com/aion0/forge/auth/Auth.kt +0 -31
  16. package/intellij-plugin/src/main/kotlin/com/aion0/forge/connection/ConnectionManager.kt +0 -95
  17. package/intellij-plugin/src/main/kotlin/com/aion0/forge/settings/ForgeConfigurable.kt +0 -81
  18. package/intellij-plugin/src/main/kotlin/com/aion0/forge/ui/toolwindow/DocsView.kt +0 -99
  19. package/intellij-plugin/src/main/kotlin/com/aion0/forge/ui/toolwindow/ForgeStatusBarWidgetFactory.kt +0 -94
  20. package/intellij-plugin/src/main/kotlin/com/aion0/forge/ui/toolwindow/ForgeToolWindowFactory.kt +0 -27
  21. package/intellij-plugin/src/main/kotlin/com/aion0/forge/ui/toolwindow/ForgeTreeView.kt +0 -176
  22. package/intellij-plugin/src/main/kotlin/com/aion0/forge/ui/toolwindow/Helpers.kt +0 -48
  23. package/intellij-plugin/src/main/kotlin/com/aion0/forge/ui/toolwindow/PipelinesView.kt +0 -226
  24. package/intellij-plugin/src/main/kotlin/com/aion0/forge/ui/toolwindow/TerminalsView.kt +0 -309
  25. package/intellij-plugin/src/main/kotlin/com/aion0/forge/ui/toolwindow/TreeNodeData.kt +0 -33
  26. package/intellij-plugin/src/main/kotlin/com/aion0/forge/ui/toolwindow/WorkspacesView.kt +0 -166
  27. package/intellij-plugin/src/main/resources/META-INF/plugin.xml +0 -88
  28. package/intellij-plugin/src/main/resources/icons/forge.svg +0 -3
  29. package/vscode-extension/.vscodeignore +0 -11
  30. package/vscode-extension/README.md +0 -48
  31. package/vscode-extension/media/icon.png +0 -0
  32. package/vscode-extension/media/icon.svg +0 -3
  33. package/vscode-extension/package-lock.json +0 -4046
  34. package/vscode-extension/package.json +0 -514
  35. package/vscode-extension/publish.sh +0 -49
  36. package/vscode-extension/src/api/client.ts +0 -217
  37. package/vscode-extension/src/auth/auth.ts +0 -32
  38. package/vscode-extension/src/commands/auth.ts +0 -44
  39. package/vscode-extension/src/commands/connection.ts +0 -113
  40. package/vscode-extension/src/commands/docs.ts +0 -40
  41. package/vscode-extension/src/commands/pipeline.ts +0 -103
  42. package/vscode-extension/src/commands/server.ts +0 -50
  43. package/vscode-extension/src/commands/smith.ts +0 -112
  44. package/vscode-extension/src/commands/task.ts +0 -43
  45. package/vscode-extension/src/commands/terminal.ts +0 -279
  46. package/vscode-extension/src/commands/workspace.ts +0 -138
  47. package/vscode-extension/src/connection/manager.ts +0 -80
  48. package/vscode-extension/src/docs/fs-provider.ts +0 -94
  49. package/vscode-extension/src/docs/result-provider.ts +0 -33
  50. package/vscode-extension/src/docs/transport.ts +0 -22
  51. package/vscode-extension/src/extension.ts +0 -314
  52. package/vscode-extension/src/statusbar.ts +0 -70
  53. package/vscode-extension/src/terminal/pseudoterm.ts +0 -123
  54. package/vscode-extension/src/views/docs.ts +0 -145
  55. package/vscode-extension/src/views/pipelines.ts +0 -222
  56. package/vscode-extension/src/views/terminals.ts +0 -91
  57. package/vscode-extension/src/views/workspaces.ts +0 -243
  58. package/vscode-extension/tsconfig.json +0 -16
@@ -1,145 +0,0 @@
1
- import * as vscode from 'vscode';
2
- import { ForgeClient } from '../api/client';
3
- import { detectDocsTransport } from '../docs/transport';
4
-
5
- interface DocFileNode {
6
- name: string;
7
- path: string;
8
- type: 'file' | 'dir';
9
- fileType?: 'md' | 'image' | 'other';
10
- children?: DocFileNode[];
11
- }
12
-
13
- export class DocsProvider implements vscode.TreeDataProvider<DocItem> {
14
- private _onDidChange = new vscode.EventEmitter<DocItem | undefined | void>();
15
- onDidChangeTreeData = this._onDidChange.event;
16
-
17
- // Cache the latest doc tree so we can resolve path → root-index lookups
18
- // for "open file" without refetching the whole tree.
19
- private cached: { roots: string[]; rootPaths: string[]; trees: DocFileNode[][] } | null = null;
20
-
21
- constructor(private client: ForgeClient) {}
22
-
23
- refresh(): void {
24
- this.cached = null;
25
- this._onDidChange.fire();
26
- }
27
-
28
- getTreeItem(el: DocItem): vscode.TreeItem {
29
- return el;
30
- }
31
-
32
- async getChildren(parent?: DocItem): Promise<DocItem[]> {
33
- if (!parent) {
34
- const r = await this.client.listDocs();
35
- if (r.status === 401 || r.status === 403) return [loginPrompt()];
36
- if (!r.ok || !r.data) return [hint('⚠ ' + (r.error || 'Not connected'))];
37
- const roots = r.data.roots || [];
38
- if (roots.length === 0) return [hint('No doc roots — add one in Settings → Doc Roots')];
39
-
40
- // /api/docs only returns the tree for ONE root at a time (the rootIdx
41
- // query). For each root, fire a separate request to get its tree.
42
- const trees: DocFileNode[][] = [];
43
- for (let i = 0; i < roots.length; i++) {
44
- if (i === 0) {
45
- // First call already happened — its tree is in r.data.tree
46
- trees.push(r.data.tree || []);
47
- } else {
48
- const sub = await this.client.request<any>(`/api/docs?root=${i}`);
49
- trees.push(sub.ok ? (sub.data?.tree || []) : []);
50
- }
51
- }
52
- const rootPaths = r.data.rootPaths || [];
53
- this.cached = { roots, rootPaths, trees };
54
-
55
- const transport = detectDocsTransport();
56
-
57
- // Always show docRoot as a parent — even if there's only one — so the
58
- // inline ⌨️ "Open Terminal" action has somewhere to live.
59
- return roots.map((name, i) => {
60
- const item = new DocItem(
61
- name,
62
- vscode.TreeItemCollapsibleState.Expanded, // expand by default
63
- 'forge.docRoot',
64
- { rootIdx: i, rootPath: rootPaths[i], rootName: name, view: 'docs' },
65
- `${rootPaths[i] || name}\nMode: ${transport === 'local' ? 'local file' : 'remote (forge HTTP)'}`,
66
- );
67
- item.iconPath = new vscode.ThemeIcon('folder-library');
68
- // Description: distinguish local vs remote at a glance.
69
- item.description = transport === 'local' ? '$(home) local' : '$(globe) remote';
70
- return item;
71
- });
72
- }
73
-
74
- if (parent.contextValue === 'forge.docRoot' && this.cached) {
75
- const idx = parent.meta.rootIdx;
76
- const tree = this.cached.trees[idx] || [];
77
- const rootPath = this.cached.rootPaths[idx];
78
- return tree.map(n => buildNode(n, idx, rootPath));
79
- }
80
-
81
- if (parent.contextValue === 'forge.docDir' && this.cached) {
82
- const children = parent.meta.children as DocFileNode[] | undefined;
83
- if (!children) return [];
84
- return children.map(n => buildNode(n, parent.meta.rootIdx, parent.meta.rootPath));
85
- }
86
-
87
- return [];
88
- }
89
- }
90
-
91
- class DocItem extends vscode.TreeItem {
92
- constructor(
93
- label: string,
94
- collapsible: vscode.TreeItemCollapsibleState,
95
- contextValue: string,
96
- public meta: any = {},
97
- tooltip?: string,
98
- ) {
99
- super(label, collapsible);
100
- this.contextValue = contextValue;
101
- if (tooltip) this.tooltip = tooltip;
102
- }
103
- }
104
-
105
- function buildNode(n: DocFileNode, rootIdx: number, rootPath: string): DocItem {
106
- if (n.type === 'dir') {
107
- const item = new DocItem(
108
- n.name,
109
- vscode.TreeItemCollapsibleState.Collapsed,
110
- 'forge.docDir',
111
- { rootIdx, rootPath, children: n.children || [], path: n.path },
112
- n.path,
113
- );
114
- item.iconPath = new vscode.ThemeIcon('folder');
115
- return item;
116
- }
117
- // File
118
- const icon = n.fileType === 'md' ? 'markdown'
119
- : n.fileType === 'image' ? 'file-media'
120
- : 'file';
121
- const item = new DocItem(
122
- n.name,
123
- vscode.TreeItemCollapsibleState.None,
124
- 'forge.docFile',
125
- { rootIdx, rootPath, path: n.path, fileType: n.fileType },
126
- n.path,
127
- );
128
- item.iconPath = new vscode.ThemeIcon(icon);
129
- item.command = {
130
- command: 'forge.openDoc',
131
- title: 'Open Doc',
132
- arguments: [{ rootIdx, rootPath, path: n.path, fileType: n.fileType, name: n.name }],
133
- };
134
- return item;
135
- }
136
-
137
- function hint(msg: string): DocItem {
138
- return new DocItem(msg, vscode.TreeItemCollapsibleState.None, 'forge.hint');
139
- }
140
-
141
- function loginPrompt(): DocItem {
142
- const item = new DocItem('🔑 Click to login', vscode.TreeItemCollapsibleState.None, 'forge.login');
143
- item.command = { command: 'forge.login', title: 'Login' };
144
- return item;
145
- }
@@ -1,222 +0,0 @@
1
- import * as vscode from 'vscode';
2
- import { ForgeClient } from '../api/client';
3
-
4
- /**
5
- * Pipelines tree:
6
- * PIPELINES
7
- * └─ 📁 <project>
8
- * ├─ ⚙ <binding> (workflow attached to project — schedule, enable/disable)
9
- * ├─ ⚙ <binding>
10
- * ├─ ─── Recent Runs ───
11
- * ├─ ✓/▶ <run> (most-recent runs of this project's workflows)
12
- * └─ ...
13
- */
14
- export class PipelinesProvider implements vscode.TreeDataProvider<PItem> {
15
- private _onDidChange = new vscode.EventEmitter<PItem | undefined | void>();
16
- onDidChangeTreeData = this._onDidChange.event;
17
-
18
- constructor(private client: ForgeClient) {}
19
-
20
- refresh(): void {
21
- this._onDidChange.fire();
22
- }
23
-
24
- getTreeItem(el: PItem): vscode.TreeItem {
25
- return el;
26
- }
27
-
28
- async getChildren(parent?: PItem): Promise<PItem[]> {
29
- if (!parent) {
30
- const r = await this.client.listProjects();
31
- if (r.status === 401 || r.status === 403) return [loginPrompt()];
32
- if (!r.ok || !Array.isArray(r.data)) return [hint('⚠ ' + (r.error || 'Not connected'))];
33
- if (r.data.length === 0) return [hint('No projects configured — add one in Settings → Project Roots')];
34
- const sorted = [...r.data].sort((a: any, b: any) => (a.name || '').localeCompare(b.name || ''));
35
- return sorted.map((p: any) => {
36
- const item = new PItem(
37
- p.name,
38
- vscode.TreeItemCollapsibleState.Collapsed,
39
- 'forge.pipelineProject',
40
- { projectPath: p.path, projectName: p.name, view: 'tasks' },
41
- p.path,
42
- );
43
- item.iconPath = new vscode.ThemeIcon('folder');
44
- return item;
45
- });
46
- }
47
-
48
- if (parent.contextValue === 'forge.pipelineProject' && parent.meta?.projectPath) {
49
- const r = await this.client.getProjectPipelines(parent.meta.projectPath);
50
- if (!r.ok) return [hint('⚠ ' + (r.error || 'failed to load'))];
51
- const bindings: any[] = r.data?.bindings || [];
52
- const runs: any[] = r.data?.runs || [];
53
- const out: PItem[] = [];
54
-
55
- // Bindings — workflows attached to this project.
56
- if (bindings.length === 0) {
57
- const empty = new PItem(
58
- '+ No pipelines yet',
59
- vscode.TreeItemCollapsibleState.None,
60
- 'forge.pipelineEmpty',
61
- parent.meta,
62
- 'Click to add a pipeline workflow to this project',
63
- );
64
- empty.iconPath = new vscode.ThemeIcon('add', new vscode.ThemeColor('charts.gray'));
65
- empty.command = {
66
- command: 'forge.addPipeline',
67
- title: 'Add Pipeline',
68
- arguments: [parent.meta],
69
- };
70
- out.push(empty);
71
- } else {
72
- for (const b of bindings) {
73
- const enabled = !!b.enabled;
74
- const schedule = b.config?.schedule || b.config?.cron || (b.config?.trigger === 'manual' ? 'manual' : 'manual');
75
- const item = new PItem(
76
- b.workflowName,
77
- vscode.TreeItemCollapsibleState.None,
78
- enabled ? 'forge.pipelineBinding.enabled' : 'forge.pipelineBinding.disabled',
79
- { projectPath: parent.meta.projectPath, projectName: parent.meta.projectName, workflowName: b.workflowName, enabled },
80
- `${b.workflowName}\n${enabled ? 'enabled' : 'disabled'} · ${schedule}${b.nextRunAt ? `\nnext run: ${new Date(b.nextRunAt).toLocaleString()}` : ''}`,
81
- );
82
- item.iconPath = new vscode.ThemeIcon(
83
- enabled ? 'gear' : 'gear',
84
- new vscode.ThemeColor(enabled ? 'charts.green' : 'charts.gray'),
85
- );
86
- item.description = `${enabled ? '' : 'disabled · '}${schedule}`;
87
- // Click → trigger now (fast iteration use case).
88
- item.command = {
89
- command: 'forge.triggerPipeline',
90
- title: 'Trigger Pipeline',
91
- arguments: [{ projectPath: parent.meta.projectPath, projectName: parent.meta.projectName, workflowName: b.workflowName }],
92
- };
93
- out.push(item);
94
- }
95
- }
96
-
97
- // Recent Runs section.
98
- if (runs.length > 0) {
99
- const sep = new PItem('Recent Runs', vscode.TreeItemCollapsibleState.None, 'forge.pipelineRunsHeader');
100
- sep.iconPath = new vscode.ThemeIcon('history');
101
- out.push(sep);
102
- // Sort by createdAt desc, last 10.
103
- const sorted = [...runs].sort((a: any, b: any) => (b.createdAt || '').localeCompare(a.createdAt || ''));
104
- for (const run of sorted.slice(0, 10)) {
105
- const status = run.status || 'pending';
106
- const created = run.createdAt ? new Date(run.createdAt).toLocaleString() : '';
107
- // Two ids: run.id (the project-pipelines bookkeeping row) and
108
- // run.pipelineId (the actual /api/pipelines/<id> document). Use
109
- // pipelineId for fetching detail; fall back to id for very old rows.
110
- const detailId = run.pipelineId || run.id;
111
- const item = new PItem(
112
- `${statusEmoji(status)} ${run.workflowName || detailId?.slice(0, 8)}`,
113
- vscode.TreeItemCollapsibleState.Collapsed,
114
- 'forge.pipelineRun',
115
- { runId: detailId, status, view: 'tasks' },
116
- `${run.workflowName}\nstatus: ${status}\ncreated: ${created}`,
117
- );
118
- item.iconPath = statusIcon(status);
119
- item.description = `${status} · ${created}`;
120
- out.push(item);
121
- }
122
- }
123
-
124
- return out;
125
- }
126
-
127
- // Run expanded → show nodes with status + error.
128
- if (parent.contextValue === 'forge.pipelineRun' && parent.meta?.runId) {
129
- const r = await this.client.getPipeline(parent.meta.runId);
130
- if (!r.ok || !r.data) return [hint(`⚠ ${r.error || 'failed to load'}`)];
131
- const nodes: Record<string, any> = r.data.nodes || {};
132
- const order: string[] = r.data.nodeOrder || Object.keys(nodes);
133
- if (order.length === 0) return [hint('No nodes')];
134
- return order.map((name) => {
135
- const n = nodes[name] || {};
136
- const status = n.status || 'pending';
137
- const item = new PItem(
138
- `${statusEmoji(status)} ${name}`,
139
- vscode.TreeItemCollapsibleState.None,
140
- 'forge.pipelineNode',
141
- {
142
- runId: parent.meta.runId,
143
- nodeName: name,
144
- status,
145
- error: n.error || '',
146
- taskId: n.taskId,
147
- outputs: n.outputs || {},
148
- startedAt: n.startedAt,
149
- completedAt: n.completedAt,
150
- },
151
- `${name}\nstatus: ${status}${n.error ? `\n\nerror:\n${n.error}` : ''}${n.taskId ? `\ntaskId: ${n.taskId}` : ''}`,
152
- );
153
- item.iconPath = statusIcon(status);
154
- // Description shows error preview for failed nodes, status for others.
155
- if (status === 'failed' && n.error) {
156
- item.description = '✕ ' + String(n.error).split('\n')[0].slice(0, 60);
157
- } else if (n.startedAt) {
158
- const dur = n.completedAt
159
- ? `${Math.round((new Date(n.completedAt).getTime() - new Date(n.startedAt).getTime()) / 1000)}s`
160
- : '';
161
- item.description = dur ? `${status} · ${dur}` : status;
162
- }
163
- // Always clickable — pending nodes still show status/duration (helpful)
164
- // and once they run we get richer detail.
165
- item.command = {
166
- command: 'forge.showPipelineNodeResult',
167
- title: 'Show Node Result',
168
- arguments: [{ runId: parent.meta.runId, nodeName: name, status, error: n.error, taskId: n.taskId, outputs: n.outputs, startedAt: n.startedAt, completedAt: n.completedAt }],
169
- };
170
- return item;
171
- });
172
- }
173
-
174
- return [];
175
- }
176
- }
177
-
178
- class PItem extends vscode.TreeItem {
179
- constructor(
180
- label: string,
181
- collapsible: vscode.TreeItemCollapsibleState,
182
- contextValue: string,
183
- public meta: any = {},
184
- tooltip?: string,
185
- ) {
186
- super(label, collapsible);
187
- this.contextValue = contextValue;
188
- if (tooltip) this.tooltip = tooltip;
189
- }
190
- }
191
-
192
- function statusEmoji(s: string): string {
193
- switch (s) {
194
- case 'running': return '▶';
195
- case 'pending': return '⌛';
196
- case 'done': return '✓';
197
- case 'failed': return '✕';
198
- case 'cancelled': return '⊘';
199
- default: return '·';
200
- }
201
- }
202
-
203
- function statusIcon(s: string): vscode.ThemeIcon {
204
- switch (s) {
205
- case 'running': return new vscode.ThemeIcon('loading~spin', new vscode.ThemeColor('charts.green'));
206
- case 'pending': return new vscode.ThemeIcon('clock', new vscode.ThemeColor('charts.gray'));
207
- case 'done': return new vscode.ThemeIcon('check', new vscode.ThemeColor('charts.green'));
208
- case 'failed': return new vscode.ThemeIcon('error', new vscode.ThemeColor('charts.red'));
209
- case 'cancelled': return new vscode.ThemeIcon('stop-circle', new vscode.ThemeColor('charts.gray'));
210
- default: return new vscode.ThemeIcon('circle-outline');
211
- }
212
- }
213
-
214
- function hint(msg: string): PItem {
215
- return new PItem(msg, vscode.TreeItemCollapsibleState.None, 'forge.hint');
216
- }
217
-
218
- function loginPrompt(): PItem {
219
- const item = new PItem('🔑 Click to login', vscode.TreeItemCollapsibleState.None, 'forge.login');
220
- item.command = { command: 'forge.login', title: 'Login' };
221
- return item;
222
- }
@@ -1,91 +0,0 @@
1
- import * as vscode from 'vscode';
2
- import { ForgeClient } from '../api/client';
3
-
4
- export class TerminalsProvider implements vscode.TreeDataProvider<TermItem> {
5
- private _onDidChange = new vscode.EventEmitter<TermItem | undefined | void>();
6
- onDidChangeTreeData = this._onDidChange.event;
7
-
8
- constructor(private client: ForgeClient) {}
9
-
10
- refresh(): void {
11
- this._onDidChange.fire();
12
- }
13
-
14
- getTreeItem(el: TermItem): vscode.TreeItem {
15
- return el;
16
- }
17
-
18
- async getChildren(): Promise<TermItem[]> {
19
- const r = await this.client.listTerminals();
20
- if (r.status === 401 || r.status === 403) {
21
- const item = new TermItem('🔑 Click to login', vscode.TreeItemCollapsibleState.None, 'forge.login');
22
- item.command = { command: 'forge.login', title: 'Login' };
23
- return [item];
24
- }
25
- if (!r.ok || !r.data) return [hint('⚠ ' + (r.error || 'Not connected'))];
26
-
27
- // /api/terminal-state returns { sessions: [{name, projectPath, ...}], ... }
28
- const sessions: any[] = Array.isArray(r.data) ? r.data : (r.data.sessions || []);
29
-
30
- const items: TermItem[] = sessions.map((s: any) => {
31
- const name = s.name || s.sessionName || 'unknown';
32
- const proj = s.projectPath ? s.projectPath.split('/').pop() : '';
33
- const item = new TermItem(
34
- `${name}${proj ? ' · ' + proj : ''}`,
35
- vscode.TreeItemCollapsibleState.None,
36
- 'forge.terminal',
37
- { sessionName: name },
38
- s.projectPath || name,
39
- );
40
- item.iconPath = new vscode.ThemeIcon('terminal');
41
- item.command = {
42
- command: 'forge.attachTerminal',
43
- title: 'Attach',
44
- arguments: [{ sessionName: name }],
45
- };
46
- return item;
47
- });
48
-
49
- // Always offer "Open <project>…" entries below — clicking opens the
50
- // session picker (Current / New / Other) like the forge web UI.
51
- const projRes = await this.client.listProjects();
52
- const projects: any[] = projRes.ok && Array.isArray(projRes.data) ? projRes.data : [];
53
- for (const p of projects) {
54
- const item = new TermItem(
55
- `Open ${p.name}…`,
56
- vscode.TreeItemCollapsibleState.None,
57
- 'forge.openSession',
58
- { projectPath: p.path },
59
- `Open a session in ${p.path}`,
60
- );
61
- item.iconPath = new vscode.ThemeIcon('repo');
62
- item.command = {
63
- command: 'forge.openSession',
64
- title: 'Open Session',
65
- arguments: [{ projectPath: p.path, projectName: p.name }],
66
- };
67
- items.push(item);
68
- }
69
-
70
- if (items.length === 0) return [hint('No active terminals — add a project root in Settings')];
71
- return items;
72
- }
73
- }
74
-
75
- class TermItem extends vscode.TreeItem {
76
- constructor(
77
- label: string,
78
- collapsible: vscode.TreeItemCollapsibleState,
79
- contextValue: string,
80
- public meta: any = {},
81
- tooltip?: string,
82
- ) {
83
- super(label, collapsible);
84
- this.contextValue = contextValue;
85
- if (tooltip) this.tooltip = tooltip;
86
- }
87
- }
88
-
89
- function hint(msg: string): TermItem {
90
- return new TermItem(msg, vscode.TreeItemCollapsibleState.None, 'forge.hint');
91
- }