@nomo-ai/wcode-dev-host 0.9.2 → 0.9.4
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/LICENSE +190 -0
- package/dist/assets/abap-CRCWOmpq.js +1 -0
- package/dist/assets/apex-DnsZk_dE.js +1 -0
- package/dist/assets/azcli-1IWB1ccx.js +1 -0
- package/dist/assets/bat-DPkNLes8.js +1 -0
- package/dist/assets/bicep-Corcdgou.js +2 -0
- package/dist/assets/cameligo-CGrWLZr3.js +1 -0
- package/dist/assets/clojure-D9WOWImG.js +1 -0
- package/dist/assets/codicon-Hscy-R9e.ttf +0 -0
- package/dist/assets/coffee-B7EJu28W.js +1 -0
- package/dist/assets/cpp-BaF-TIV3.js +1 -0
- package/dist/assets/csharp-BoL64M5l.js +1 -0
- package/dist/assets/csp-C46ZqvIl.js +1 -0
- package/dist/assets/css-DQU6DXDx.js +3 -0
- package/dist/assets/cssMode-C9N4hlpu.js +4 -0
- package/dist/assets/cypher-D84EuPTj.js +1 -0
- package/dist/assets/dart-D8lhlL1r.js +1 -0
- package/dist/assets/dockerfile-DLk6rpji.js +1 -0
- package/dist/assets/ecl-BO6FnfXk.js +1 -0
- package/dist/assets/elixir-BRjLKONM.js +1 -0
- package/dist/assets/flow9-Cac8vKd7.js +1 -0
- package/dist/assets/freemarker2-DDurVrnY.js +3 -0
- package/dist/assets/fsharp-fd1GTHhf.js +1 -0
- package/dist/assets/go-O9LJTZXk.js +1 -0
- package/dist/assets/graphql-LQdxqEYJ.js +1 -0
- package/dist/assets/handlebars-qMEUmWV9.js +1 -0
- package/dist/assets/hcl-DxDQ3s82.js +1 -0
- package/dist/assets/html-DkTxIK1u.js +1 -0
- package/dist/assets/htmlMode-BK9KKlkJ.js +4 -0
- package/dist/assets/index-CfVsSjOz.css +1 -0
- package/dist/assets/index-iO_bfZ2p.js +1377 -0
- package/dist/assets/ini-BvajGCUy.js +1 -0
- package/dist/assets/java-SYsfObOQ.js +1 -0
- package/dist/assets/javascript-BAqIzASr.js +1 -0
- package/dist/assets/jsonMode-B91QSrZm.js +6 -0
- package/dist/assets/julia-DQXNmw_w.js +1 -0
- package/dist/assets/kotlin-qQ0MG-9I.js +1 -0
- package/dist/assets/less-GGFNNJHn.js +2 -0
- package/dist/assets/lexon-Canl7DCW.js +1 -0
- package/dist/assets/liquid-LP0wHRPn.js +1 -0
- package/dist/assets/lua-D28Ae8-K.js +1 -0
- package/dist/assets/m3-DPitgjJI.js +1 -0
- package/dist/assets/markdown-B811l8j2.js +1 -0
- package/dist/assets/mdx-B0cy-eyp.js +1 -0
- package/dist/assets/mips-CdjsipkG.js +1 -0
- package/dist/assets/msdax-CYqgjx_P.js +1 -0
- package/dist/assets/mysql-BHd6q0vd.js +1 -0
- package/dist/assets/objective-c-B1aVtJYH.js +1 -0
- package/dist/assets/pascal-BhNW15KB.js +1 -0
- package/dist/assets/pascaligo-5jv8CcQD.js +1 -0
- package/dist/assets/perl-DlYyT36c.js +1 -0
- package/dist/assets/pgsql-Dy0bjov7.js +1 -0
- package/dist/assets/php-120yhfDK.js +1 -0
- package/dist/assets/pla-CjnFlu4u.js +1 -0
- package/dist/assets/postiats-CQpG440k.js +1 -0
- package/dist/assets/powerquery-DdJtto1Z.js +1 -0
- package/dist/assets/powershell-Bu_VLpJB.js +1 -0
- package/dist/assets/protobuf-IBS6jZEB.js +2 -0
- package/dist/assets/pug-kFxLfcjb.js +1 -0
- package/dist/assets/python-Dkx6kc6J.js +1 -0
- package/dist/assets/qsharp-gaqVKiJ_.js +1 -0
- package/dist/assets/r-BIFz-_sK.js +1 -0
- package/dist/assets/razor-Dl26DQBO.js +1 -0
- package/dist/assets/redis-CHOsPHWR.js +1 -0
- package/dist/assets/redshift-CBifECDb.js +1 -0
- package/dist/assets/restructuredtext-CghPJEOS.js +1 -0
- package/dist/assets/ruby-CYWGW-b1.js +1 -0
- package/dist/assets/rust-DMDD0SHb.js +1 -0
- package/dist/assets/sb-BYAiYHFx.js +1 -0
- package/dist/assets/scala-Bqvq8jcR.js +1 -0
- package/dist/assets/scheme-Dhb-2j9p.js +1 -0
- package/dist/assets/scss-CTwUZ5N7.js +3 -0
- package/dist/assets/shell-CsDZo4DB.js +1 -0
- package/dist/assets/solidity-CME5AdoB.js +1 -0
- package/dist/assets/sophia-RYC1BQQz.js +1 -0
- package/dist/assets/sparql-KEyrF7De.js +1 -0
- package/dist/assets/sql-BdTr02Mf.js +1 -0
- package/dist/assets/st-C7iG7M4S.js +1 -0
- package/dist/assets/swift-D7IUmUK8.js +1 -0
- package/dist/assets/systemverilog-DgMryOEJ.js +1 -0
- package/dist/assets/tcl-PloMZuKG.js +1 -0
- package/dist/assets/tsMode-Dc6QP6S8.js +11 -0
- package/dist/assets/twig-BfRIq3la.js +1 -0
- package/dist/assets/typescript-BCk6Lsk7.js +1 -0
- package/dist/assets/vb-BwAE3J76.js +1 -0
- package/dist/assets/wgsl-B_1kOXbF.js +298 -0
- package/dist/assets/xml-C1k12Cqw.js +1 -0
- package/dist/assets/yaml-BWrNBOao.js +1 -0
- package/dist/index.html +57 -0
- package/dist/monacoeditorwork/css.worker.bundle.js +49210 -0
- package/dist/monacoeditorwork/editor.worker.bundle.js +12428 -0
- package/dist/monacoeditorwork/html.worker.bundle.js +28459 -0
- package/dist/monacoeditorwork/json.worker.bundle.js +19688 -0
- package/dist/monacoeditorwork/ts.worker.bundle.js +183776 -0
- package/package.json +14 -13
- package/src/App.vue +96 -7
- package/src/components/ActivityBar.vue +121 -0
- package/src/components/FileTree.vue +93 -0
- package/src/components/FileTreeNode.vue +121 -0
- package/src/env.d.ts +2 -1
- package/src/main.ts +2 -4
- package/tsconfig.json +4 -1
- package/vite.config.ts +10 -10
package/package.json
CHANGED
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomo-ai/wcode-dev-host",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.4",
|
|
5
5
|
"description": "WCode plugin development host",
|
|
6
6
|
"author": "NomoAIT",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"type": "module",
|
|
9
|
-
"scripts": {
|
|
10
|
-
"dev": "vite",
|
|
11
|
-
"build": "vue-tsc && vite build",
|
|
12
|
-
"preview": "vite preview"
|
|
13
|
-
},
|
|
14
9
|
"dependencies": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"vue": "^3.5.27"
|
|
10
|
+
"vue": "^3.5.27",
|
|
11
|
+
"@nomo-ai/wcode-core": "^0.9.4"
|
|
18
12
|
},
|
|
19
13
|
"peerDependencies": {
|
|
20
|
-
"@nomo-ai/wcode-core": "^0.9.
|
|
14
|
+
"@nomo-ai/wcode-core": "^0.9.4"
|
|
21
15
|
},
|
|
22
16
|
"devDependencies": {
|
|
23
|
-
"@nomo-ai/wcode-core": "workspace:*",
|
|
24
17
|
"@vitejs/plugin-vue": "^6.0.4",
|
|
18
|
+
"monaco-editor": "^0.45.0",
|
|
25
19
|
"typescript": "^5.9.3",
|
|
26
20
|
"vite": "^7.3.1",
|
|
27
|
-
"
|
|
21
|
+
"vite-plugin-monaco-editor": "^1.1.0",
|
|
22
|
+
"vue-tsc": "^3.2.4",
|
|
23
|
+
"@nomo-ai/wcode-core": "^0.9.4"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"dev": "vite",
|
|
27
|
+
"build": "vue-tsc && vite build",
|
|
28
|
+
"preview": "vite preview"
|
|
28
29
|
}
|
|
29
|
-
}
|
|
30
|
+
}
|
package/src/App.vue
CHANGED
|
@@ -1,15 +1,52 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div class="app-layout" @mouseup="stopResize" @mousemove="doResize">
|
|
3
|
+
<ActivityBar />
|
|
4
|
+
<div class="sidebar" :style="{ width: sidebarWidth + 'px' }">
|
|
5
|
+
<FileTree v-if="ide" :ide="ide" />
|
|
6
|
+
</div>
|
|
7
|
+
<div class="resize-handle" @mousedown="startResize"></div>
|
|
8
|
+
<div id="editor-container" ref="editorContainer" class="main-content"></div>
|
|
9
|
+
</div>
|
|
3
10
|
</template>
|
|
4
11
|
|
|
5
12
|
<script setup lang="ts">
|
|
6
|
-
import { ref, onMounted } from 'vue';
|
|
13
|
+
import { ref, onMounted, shallowRef } from 'vue';
|
|
7
14
|
import { WCode } from 'wcode';
|
|
8
15
|
import type { WCodePlugin } from 'wcode';
|
|
9
16
|
import * as UserPluginModule from 'virtual:user-plugin';
|
|
17
|
+
import FileTree from './components/FileTree.vue';
|
|
18
|
+
import ActivityBar from './components/ActivityBar.vue';
|
|
10
19
|
|
|
11
20
|
const editorContainer = ref<HTMLElement>();
|
|
12
|
-
|
|
21
|
+
const ide = shallowRef<WCode | null>(null);
|
|
22
|
+
|
|
23
|
+
// Sidebar Resizing Logic
|
|
24
|
+
const sidebarWidth = ref(250);
|
|
25
|
+
const isResizing = ref(false);
|
|
26
|
+
|
|
27
|
+
function startResize() {
|
|
28
|
+
isResizing.value = true;
|
|
29
|
+
document.body.style.cursor = 'col-resize';
|
|
30
|
+
document.body.style.userSelect = 'none'; // Prevent selection while dragging
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function doResize(event: MouseEvent) {
|
|
34
|
+
if (isResizing.value) {
|
|
35
|
+
// 48px is activity bar width
|
|
36
|
+
const newWidth = event.clientX - 48;
|
|
37
|
+
if (newWidth > 150 && newWidth < 600) {
|
|
38
|
+
sidebarWidth.value = newWidth;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function stopResize() {
|
|
44
|
+
if (isResizing.value) {
|
|
45
|
+
isResizing.value = false;
|
|
46
|
+
document.body.style.cursor = '';
|
|
47
|
+
document.body.style.userSelect = '';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
13
50
|
|
|
14
51
|
onMounted(() => {
|
|
15
52
|
if (!editorContainer.value) return;
|
|
@@ -37,13 +74,15 @@ onMounted(() => {
|
|
|
37
74
|
console.warn('Could not find a valid WCodePlugin export in src/index.ts');
|
|
38
75
|
}
|
|
39
76
|
|
|
40
|
-
|
|
77
|
+
const instance = new WCode(editorContainer.value, {
|
|
41
78
|
theme: 'dark',
|
|
42
79
|
layout: {
|
|
43
|
-
showFileTree:
|
|
80
|
+
showFileTree: false, // We render our own external FileTree
|
|
44
81
|
showTabs: true,
|
|
45
82
|
showStatusBar: true,
|
|
46
|
-
showTerminal: true
|
|
83
|
+
showTerminal: true,
|
|
84
|
+
showActivityBar: false, // Hide core activity bar as we have our own sidebar
|
|
85
|
+
showMenuBar: true // Keep menu bar for "Open Folder" command
|
|
47
86
|
},
|
|
48
87
|
files: [
|
|
49
88
|
{
|
|
@@ -57,7 +96,9 @@ onMounted(() => {
|
|
|
57
96
|
terminalToken: 'dev-token-123'
|
|
58
97
|
});
|
|
59
98
|
|
|
60
|
-
ide.
|
|
99
|
+
ide.value = instance;
|
|
100
|
+
|
|
101
|
+
instance.on('ready', () => {
|
|
61
102
|
console.log('WCode Dev Environment Ready');
|
|
62
103
|
});
|
|
63
104
|
});
|
|
@@ -67,4 +108,52 @@ onMounted(() => {
|
|
|
67
108
|
:root {
|
|
68
109
|
color-scheme: dark;
|
|
69
110
|
}
|
|
111
|
+
|
|
112
|
+
body {
|
|
113
|
+
margin: 0;
|
|
114
|
+
padding: 0;
|
|
115
|
+
overflow: hidden;
|
|
116
|
+
background-color: #1e1e1e;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.app-layout {
|
|
120
|
+
display: flex;
|
|
121
|
+
width: 100vw;
|
|
122
|
+
height: 100vh;
|
|
123
|
+
overflow: hidden;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.sidebar {
|
|
127
|
+
height: 100%;
|
|
128
|
+
flex-shrink: 0;
|
|
129
|
+
background-color: #252526;
|
|
130
|
+
overflow: hidden;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.resize-handle {
|
|
134
|
+
width: 4px;
|
|
135
|
+
height: 100%;
|
|
136
|
+
cursor: col-resize;
|
|
137
|
+
background-color: transparent;
|
|
138
|
+
transition: background-color 0.2s;
|
|
139
|
+
flex-shrink: 0;
|
|
140
|
+
z-index: 10;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.resize-handle:hover, .resize-handle:active {
|
|
144
|
+
background-color: #007fd4;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.main-content {
|
|
148
|
+
flex: 1;
|
|
149
|
+
height: 100%;
|
|
150
|
+
min-width: 0; /* Prevent flex item from overflowing */
|
|
151
|
+
overflow: hidden;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* Override WCode container to fit */
|
|
155
|
+
.wcode-container {
|
|
156
|
+
width: 100% !important;
|
|
157
|
+
height: 100% !important;
|
|
158
|
+
}
|
|
70
159
|
</style>
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="activity-bar">
|
|
3
|
+
<div
|
|
4
|
+
v-for="item in items"
|
|
5
|
+
:key="item.id"
|
|
6
|
+
class="activity-item"
|
|
7
|
+
:class="{ active: activeItem === item.id }"
|
|
8
|
+
@click="activeItem = item.id"
|
|
9
|
+
:title="item.label"
|
|
10
|
+
>
|
|
11
|
+
<div class="icon-container" v-html="item.icon"></div>
|
|
12
|
+
<div class="active-indicator" v-if="activeItem === item.id"></div>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
<div class="activity-bar-bottom">
|
|
16
|
+
<div class="activity-item" title="Accounts">
|
|
17
|
+
<div class="icon-container">
|
|
18
|
+
<svg width="24" height="24" viewBox="0 0 16 16" fill="currentColor">
|
|
19
|
+
<path d="M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1zm0 1a6 6 0 1 1 0 12A6 6 0 0 1 8 2z"/>
|
|
20
|
+
<path d="M8 3.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM8 9a3 3 0 0 0-3 3 .5.5 0 0 0 1 0 2 2 0 0 1 4 0 .5.5 0 0 0 1 0 3 3 0 0 0-3-3z"/>
|
|
21
|
+
</svg>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="activity-item" title="Settings">
|
|
25
|
+
<div class="icon-container">
|
|
26
|
+
<svg width="24" height="24" viewBox="0 0 16 16" fill="currentColor">
|
|
27
|
+
<path d="M9.1 4.4L8.6 2H7.4l-.5 2.4-.7.3-2-1.3-.9.8 1.3 2-.2.7-2.4.5v1.2l2.4.5.3.8-1.3 2 .8.8 2-1.3.8.3.4 2.4h1.2l.5-2.4.8-.3 2 1.3.8-.8-1.3-2 .3-.8 2.3-.4V7.4l-2.4-.5-.3-.8 1.3-2-.8-.8-2 1.3-.7-.2zM8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/>
|
|
28
|
+
</svg>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script setup lang="ts">
|
|
36
|
+
import { ref } from 'vue';
|
|
37
|
+
|
|
38
|
+
const activeItem = ref('explorer');
|
|
39
|
+
|
|
40
|
+
const items = [
|
|
41
|
+
{
|
|
42
|
+
id: 'explorer',
|
|
43
|
+
label: 'Explorer',
|
|
44
|
+
icon: `<svg width="24" height="24" viewBox="0 0 16 16" fill="currentColor"><path d="M10 4H4c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h6c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zM4 12h6V6H4v6z"/><path d="M13 4V3H3v1h10z"/><path d="M13 2V1H3v1h10z"/></svg>`
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'search',
|
|
48
|
+
label: 'Search',
|
|
49
|
+
icon: `<svg width="24" height="24" viewBox="0 0 16 16" fill="currentColor"><path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"/></svg>`
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: 'scm',
|
|
53
|
+
label: 'Source Control',
|
|
54
|
+
icon: `<svg width="24" height="24" viewBox="0 0 16 16" fill="currentColor"><path d="M7 1a3 3 0 0 1 3 3c0 .85-.357 1.62-.924 2.162l1.096 3.107a3.001 3.001 0 1 1-.95 2.58l-1.22-3.46a2.986 2.986 0 0 1-1.936-.02L4.99 11.55a3.001 3.001 0 1 1-.866-2.68L5.22 5.77A2.992 2.992 0 0 1 7 1zm0 2a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm-3 9a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm6 2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/></svg>`
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'debug',
|
|
58
|
+
label: 'Run and Debug',
|
|
59
|
+
icon: `<svg width="24" height="24" viewBox="0 0 16 16" fill="currentColor"><path d="M8 2a3 3 0 0 0-3 3v.688A3.002 3.002 0 0 0 2 8v3.5A2.5 2.5 0 0 0 4.5 14h7a2.5 2.5 0 0 0 2.5-2.5V8a3.002 3.002 0 0 0-3-2.312V5a3 3 0 0 0-3-3zm0 1a2 2 0 0 1 2 2v.223A3.996 3.996 0 0 0 8 5a3.996 3.996 0 0 0-2 .223V5a2 2 0 0 1 2-2zM4 11h3V9H4v2zm5 0h3V9H9v2z"/></svg>`
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: 'extensions',
|
|
63
|
+
label: 'Extensions',
|
|
64
|
+
icon: `<svg width="24" height="24" viewBox="0 0 16 16" fill="currentColor"><path d="M9 1H4a2 2 0 0 0-2 2v3h1V3a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H8v1h1a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2z"/><path d="M7 6H4a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1V7a1 1 0 0 0-1-1zm0 6H4V7h3v5z"/></svg>`
|
|
65
|
+
}
|
|
66
|
+
];
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<style scoped>
|
|
70
|
+
.activity-bar {
|
|
71
|
+
width: 48px;
|
|
72
|
+
height: 100%;
|
|
73
|
+
background-color: #333333;
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-direction: column;
|
|
76
|
+
flex-shrink: 0;
|
|
77
|
+
border-right: 1px solid #252526;
|
|
78
|
+
user-select: none;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.activity-item {
|
|
82
|
+
width: 48px;
|
|
83
|
+
height: 48px;
|
|
84
|
+
display: flex;
|
|
85
|
+
justify-content: center;
|
|
86
|
+
align-items: center;
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
position: relative;
|
|
89
|
+
color: #858585;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.activity-item:hover {
|
|
93
|
+
color: #ffffff;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.activity-item.active {
|
|
97
|
+
color: #ffffff;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.active-indicator {
|
|
101
|
+
position: absolute;
|
|
102
|
+
left: 0;
|
|
103
|
+
top: 0;
|
|
104
|
+
bottom: 0;
|
|
105
|
+
width: 2px;
|
|
106
|
+
background-color: #007fd4; /* VS Code blue */
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.icon-container {
|
|
110
|
+
display: flex;
|
|
111
|
+
justify-content: center;
|
|
112
|
+
align-items: center;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.activity-bar-bottom {
|
|
116
|
+
margin-top: auto;
|
|
117
|
+
display: flex;
|
|
118
|
+
flex-direction: column;
|
|
119
|
+
padding-bottom: 5px;
|
|
120
|
+
}
|
|
121
|
+
</style>
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="file-tree-container">
|
|
3
|
+
<div class="tree-header">资源管理器</div>
|
|
4
|
+
<ul class="root-list">
|
|
5
|
+
<FileTreeNode
|
|
6
|
+
v-for="node in treeData"
|
|
7
|
+
:key="node.path"
|
|
8
|
+
:node="node"
|
|
9
|
+
:depth="0"
|
|
10
|
+
:active-path="activePath"
|
|
11
|
+
@open-file="handleOpenFile"
|
|
12
|
+
/>
|
|
13
|
+
</ul>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup lang="ts">
|
|
18
|
+
import { ref, onMounted } from 'vue';
|
|
19
|
+
import type { WCode, FileNode } from 'wcode';
|
|
20
|
+
import FileTreeNode from './FileTreeNode.vue';
|
|
21
|
+
|
|
22
|
+
const props = defineProps<{
|
|
23
|
+
ide: WCode;
|
|
24
|
+
}>();
|
|
25
|
+
|
|
26
|
+
const treeData = ref<FileNode[]>([]);
|
|
27
|
+
const activePath = ref<string | null>(null);
|
|
28
|
+
|
|
29
|
+
function updateTree() {
|
|
30
|
+
if (props.ide) {
|
|
31
|
+
treeData.value = props.ide.getFileSystem().getFileTree();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function handleOpenFile(path: string) {
|
|
36
|
+
props.ide.openFile(path);
|
|
37
|
+
activePath.value = path;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Listen to IDE events
|
|
41
|
+
function setupListeners() {
|
|
42
|
+
const events = [
|
|
43
|
+
'file:create', 'file:delete', 'file:rename',
|
|
44
|
+
'directory:create', 'directory:delete', 'directory:rename'
|
|
45
|
+
] as const;
|
|
46
|
+
|
|
47
|
+
events.forEach(event => {
|
|
48
|
+
props.ide.on(event, () => {
|
|
49
|
+
updateTree();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
props.ide.on('file:open', ({ path }) => {
|
|
54
|
+
activePath.value = path;
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Listen for bulk project load
|
|
58
|
+
props.ide.on('project:load', () => {
|
|
59
|
+
updateTree();
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
onMounted(() => {
|
|
64
|
+
updateTree();
|
|
65
|
+
setupListeners();
|
|
66
|
+
});
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<style scoped>
|
|
70
|
+
.file-tree-container {
|
|
71
|
+
height: 100%;
|
|
72
|
+
overflow-y: auto;
|
|
73
|
+
background-color: #252526;
|
|
74
|
+
color: #ccc;
|
|
75
|
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.tree-header {
|
|
79
|
+
padding: 8px 12px;
|
|
80
|
+
font-size: 11px;
|
|
81
|
+
font-weight: bold;
|
|
82
|
+
text-transform: uppercase;
|
|
83
|
+
letter-spacing: 0.5px;
|
|
84
|
+
background-color: #252526;
|
|
85
|
+
position: sticky;
|
|
86
|
+
top: 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.root-list {
|
|
90
|
+
padding: 0;
|
|
91
|
+
margin: 0;
|
|
92
|
+
}
|
|
93
|
+
</style>
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<li class="file-tree-node">
|
|
3
|
+
<div
|
|
4
|
+
class="node-content"
|
|
5
|
+
:class="{ active: isActive, 'is-directory': isDirectory }"
|
|
6
|
+
@click="handleClick"
|
|
7
|
+
@dblclick="handleDoubleClick"
|
|
8
|
+
:style="{ paddingLeft: depth * 12 + 'px' }"
|
|
9
|
+
>
|
|
10
|
+
<span class="icon" v-if="isDirectory" @click.stop="toggleExpand">
|
|
11
|
+
{{ isExpanded ? '▼' : '▶' }}
|
|
12
|
+
</span>
|
|
13
|
+
<span class="icon" v-else>📄</span>
|
|
14
|
+
<span class="label">{{ node.name }}</span>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<ul v-if="isDirectory && isExpanded" class="children-list">
|
|
18
|
+
<FileTreeNode
|
|
19
|
+
v-for="child in sortedChildren"
|
|
20
|
+
:key="child.path"
|
|
21
|
+
:node="child"
|
|
22
|
+
:depth="depth + 1"
|
|
23
|
+
:active-path="activePath"
|
|
24
|
+
@open-file="$emit('open-file', $event)"
|
|
25
|
+
/>
|
|
26
|
+
</ul>
|
|
27
|
+
</li>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script setup lang="ts">
|
|
31
|
+
import { computed, ref, toRefs } from 'vue';
|
|
32
|
+
import type { FileNode } from 'wcode';
|
|
33
|
+
|
|
34
|
+
const props = defineProps<{
|
|
35
|
+
node: FileNode;
|
|
36
|
+
depth: number;
|
|
37
|
+
activePath: string | null;
|
|
38
|
+
}>();
|
|
39
|
+
|
|
40
|
+
const emit = defineEmits<{
|
|
41
|
+
(e: 'open-file', path: string): void;
|
|
42
|
+
}>();
|
|
43
|
+
|
|
44
|
+
const { node, activePath } = toRefs(props);
|
|
45
|
+
const isExpanded = ref(false);
|
|
46
|
+
|
|
47
|
+
const isDirectory = computed(() => props.node.type === 'directory');
|
|
48
|
+
|
|
49
|
+
const isActive = computed(() => {
|
|
50
|
+
return !isDirectory.value && activePath.value === props.node.path;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const sortedChildren = computed(() => {
|
|
54
|
+
if (!props.node.children) return [];
|
|
55
|
+
// Directories first, then files
|
|
56
|
+
return [...props.node.children].sort((a, b) => {
|
|
57
|
+
if (a.type === b.type) return a.name.localeCompare(b.name);
|
|
58
|
+
return a.type === 'directory' ? -1 : 1;
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
function handleClick() {
|
|
63
|
+
if (!isDirectory.value) {
|
|
64
|
+
emit('open-file', props.node.path);
|
|
65
|
+
} else {
|
|
66
|
+
toggleExpand();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function handleDoubleClick() {
|
|
71
|
+
if (!isDirectory.value) {
|
|
72
|
+
emit('open-file', props.node.path);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function toggleExpand() {
|
|
77
|
+
if (isDirectory.value) {
|
|
78
|
+
isExpanded.value = !isExpanded.value;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
</script>
|
|
82
|
+
|
|
83
|
+
<style scoped>
|
|
84
|
+
.file-tree-node {
|
|
85
|
+
list-style: none;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.node-content {
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
padding: 4px 8px;
|
|
92
|
+
cursor: pointer;
|
|
93
|
+
user-select: none;
|
|
94
|
+
font-size: 13px;
|
|
95
|
+
color: #ccc;
|
|
96
|
+
white-space: nowrap;
|
|
97
|
+
overflow: hidden;
|
|
98
|
+
text-overflow: ellipsis;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.node-content:hover {
|
|
102
|
+
background-color: #3e3e42;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.node-content.active {
|
|
106
|
+
background-color: #37373d;
|
|
107
|
+
color: #fff;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.icon {
|
|
111
|
+
margin-right: 6px;
|
|
112
|
+
width: 16px;
|
|
113
|
+
display: inline-block;
|
|
114
|
+
text-align: center;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.children-list {
|
|
118
|
+
padding: 0;
|
|
119
|
+
margin: 0;
|
|
120
|
+
}
|
|
121
|
+
</style>
|
package/src/env.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
declare module '*.vue' {
|
|
2
2
|
import type { DefineComponent } from 'vue';
|
|
3
|
-
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
const component: DefineComponent<object, object, any>;
|
|
4
5
|
export default component;
|
|
5
6
|
}
|
|
6
7
|
|
package/src/main.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { createApp } from 'vue';
|
|
2
2
|
import App from './App.vue';
|
|
3
|
-
import { WCode } from '@nomo-ai/wcode-core';
|
|
4
|
-
import 'element-plus/dist/index.css';
|
|
5
|
-
import 'element-plus/theme-chalk/dark/css-vars.css';
|
|
3
|
+
// import { WCode } from '@nomo-ai/wcode-core';
|
|
6
4
|
|
|
7
|
-
console.log('WCode Core loaded:', WCode);
|
|
5
|
+
// console.log('WCode Core loaded:', WCode);
|
|
8
6
|
|
|
9
7
|
createApp(App).mount('#app');
|
package/tsconfig.json
CHANGED
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
"extends": "../../tsconfig.base.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"baseUrl": ".",
|
|
5
|
-
"
|
|
5
|
+
"paths": {
|
|
6
|
+
"wcode": ["../core/src/index.ts"]
|
|
7
|
+
},
|
|
8
|
+
"types": ["vite/client"],
|
|
6
9
|
"jsx": "preserve",
|
|
7
10
|
"jsxImportSource": "vue"
|
|
8
11
|
},
|
package/vite.config.ts
CHANGED
|
@@ -3,7 +3,7 @@ import vue from '@vitejs/plugin-vue';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import monacoEditorPlugin from 'vite-plugin-monaco-editor';
|
|
5
5
|
|
|
6
|
-
// @ts-
|
|
6
|
+
// @ts-expect-error - vite-plugin-monaco-editor type definition might be missing or incorrect
|
|
7
7
|
const monacoEditorPluginDefault = monacoEditorPlugin.default || monacoEditorPlugin;
|
|
8
8
|
|
|
9
9
|
export default defineConfig({
|
|
@@ -23,22 +23,22 @@ export default defineConfig({
|
|
|
23
23
|
if (id === '\0virtual:user-plugin') {
|
|
24
24
|
return 'export default {}'; // Empty plugin for standalone mode
|
|
25
25
|
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
28
|
],
|
|
29
29
|
resolve: {
|
|
30
30
|
alias: {
|
|
31
31
|
// Link to local source for development
|
|
32
|
-
|
|
32
|
+
wcode: path.resolve(__dirname, '../core/src'),
|
|
33
33
|
// Fix for JSZip in browser
|
|
34
|
-
|
|
35
|
-
}
|
|
34
|
+
jszip: 'jszip/dist/jszip.min.js',
|
|
35
|
+
},
|
|
36
36
|
},
|
|
37
37
|
assetsInclude: ['**/*.ttf'],
|
|
38
38
|
server: {
|
|
39
39
|
port: 3000,
|
|
40
40
|
fs: {
|
|
41
|
-
strict: false
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
});
|
|
41
|
+
strict: false,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
});
|