@templmf/temp-solf-lmf 0.0.55 → 0.0.57
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/fe-flow.md +348 -0
- package/package.json +1 -1
- package/ui-parse.md +308 -0
- package//345/242/236/351/207/217/351/234/200/346/261/202prompt +72 -0
- package/guanwang/README.md +0 -95
- package/guanwang/docs/changelog.md +0 -145
- package/guanwang/docs/doc-maintenance.md +0 -229
- package/guanwang/docs/product.md +0 -181
- package/guanwang/docs/test-cases.md +0 -395
- package/guanwang/docs/usage.md +0 -291
- package/guanwang/env.example +0 -27
- package/guanwang/index.html +0 -13
- package/guanwang/package-lock.json +0 -3825
- package/guanwang/package.json +0 -32
- package/guanwang/public/favicon.svg +0 -4
- package/guanwang/public/react-runtime/babel.min.js +0 -4
- package/guanwang/public/react-runtime/react-dom.min.js +0 -267
- package/guanwang/public/react-runtime/react.min.js +0 -31
- package/guanwang/public/vue-repl-assets/compiler-sfc.esm-browser.js +0 -50795
- package/guanwang/public/vue-repl-assets/runtime-dom.esm-browser.js +0 -12758
- package/guanwang/public/vue-repl-assets/server-renderer.esm-browser.js +0 -8600
- package/guanwang/public/vue-repl-assets/vue.esm-browser.js +0 -18672
- package/guanwang/src/App.vue +0 -61
- package/guanwang/src/chat-sdk/core/components/ChatBox.vue +0 -305
- package/guanwang/src/chat-sdk/core/components/ChatSidebar.vue +0 -84
- package/guanwang/src/chat-sdk/core/components/InputBar.vue +0 -354
- package/guanwang/src/chat-sdk/core/components/MessageBubble.vue +0 -703
- package/guanwang/src/chat-sdk/core/useTheme.js +0 -31
- package/guanwang/src/chat-sdk/features/artifact/ArtifactCard.vue +0 -172
- package/guanwang/src/chat-sdk/features/artifact/ArtifactPanel.vue +0 -963
- package/guanwang/src/chat-sdk/features/artifact/index.js +0 -13
- package/guanwang/src/chat-sdk/features/artifact/useArtifactStore.js +0 -275
- package/guanwang/src/chat-sdk/features/codepreview/CodePreview.vue +0 -523
- package/guanwang/src/chat-sdk/features/codepreview/index.js +0 -7
- package/guanwang/src/chat-sdk/features/markdown/index.js +0 -13
- package/guanwang/src/chat-sdk/features/markdown/useMarkdown.js +0 -724
- package/guanwang/src/chat-sdk/features/mermaid/MermaidZoom.vue +0 -254
- package/guanwang/src/chat-sdk/features/upload/FileAttachment.vue +0 -142
- package/guanwang/src/chat-sdk/features/upload/index.js +0 -17
- package/guanwang/src/chat-sdk/features/upload/useFileHandler.js +0 -336
- package/guanwang/src/chat-sdk/headless/api/adapters/openai.js +0 -76
- package/guanwang/src/chat-sdk/headless/api/chatApi.js +0 -126
- package/guanwang/src/chat-sdk/headless/buildSystemPrompt.js +0 -351
- package/guanwang/src/chat-sdk/headless/index.js +0 -15
- package/guanwang/src/chat-sdk/headless/useChat.js +0 -77
- package/guanwang/src/chat-sdk/headless/useChatDB.js +0 -147
- package/guanwang/src/chat-sdk/headless/useChatStore.js +0 -529
- package/guanwang/src/chat-sdk/index.js +0 -79
- package/guanwang/src/chat-sdk/modes/architect.js +0 -27
- package/guanwang/src/chat-sdk/modes/ask.js +0 -26
- package/guanwang/src/chat-sdk/modes/code.js +0 -25
- package/guanwang/src/chat-sdk/modes/index.js +0 -36
- package/guanwang/src/chat-sdk/modes/requirements.js +0 -175
- package/guanwang/src/chat-sdk/settings/SettingsPanel.vue +0 -170
- package/guanwang/src/chat-sdk/settings/index.js +0 -9
- package/guanwang/src/chat-sdk/settings/useSettings.js +0 -122
- package/guanwang/src/chat-sdk/tools/defaults.js +0 -89
- package/guanwang/src/chat-sdk/tools/index.js +0 -16
- package/guanwang/src/chat-sdk/tools/parser.js +0 -116
- package/guanwang/src/components/CustomCursor.vue +0 -69
- package/guanwang/src/components/Footer.vue +0 -24
- package/guanwang/src/components/LoginModal.vue +0 -109
- package/guanwang/src/components/Navbar.vue +0 -193
- package/guanwang/src/components/ThemeToggle.vue +0 -25
- package/guanwang/src/composables/useArtifactStore.js +0 -253
- package/guanwang/src/composables/useAuth.js +0 -88
- package/guanwang/src/composables/useChatDB.js +0 -147
- package/guanwang/src/composables/useCountUp.js +0 -24
- package/guanwang/src/composables/useFileHandler.js +0 -345
- package/guanwang/src/composables/useTheme.js +0 -31
- package/guanwang/src/config/api.js +0 -71
- package/guanwang/src/main.js +0 -23
- package/guanwang/src/router/index.js +0 -23
- package/guanwang/src/services/authApi.js +0 -27
- package/guanwang/src/services/chatApi.js +0 -66
- package/guanwang/src/styles/global.css +0 -478
- package/guanwang/src/tracker/analyze.js +0 -73
- package/guanwang/src/tracker/config.js +0 -82
- package/guanwang/src/tracker/index.js +0 -18
- package/guanwang/src/tracker/service.js +0 -102
- package/guanwang/src/tracker/useChatTracker.js +0 -179
- package/guanwang/src/tracker/useTracker.js +0 -45
- package/guanwang/src/views/ChatView.vue +0 -65
- package/guanwang/src/views/HomeView.vue +0 -156
- package/guanwang/src/views/MarketView.vue +0 -143
- package/guanwang/src/views/PracticesView.vue +0 -190
- package/guanwang/src/views/SkillsView.vue +0 -129
- package/guanwang/temp +0 -19
- package/guanwang/vite.config.js +0 -6
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* features/artifact
|
|
3
|
-
*
|
|
4
|
-
* core — 纯能力:artifact 解析、状态管理(headless / useChat 使用)
|
|
5
|
-
* full — 完整导出:core + UI 组件(createAIChat 使用)
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
// ── core:headless 只需要这些 ──────────────────────────────────────
|
|
9
|
-
export { useArtifactStore, provideArtifactStore, ARTIFACT_LANGS, ARTIFACT_MIN_LINES, LANG_LABEL, LANG_EXT } from './useArtifactStore.js'
|
|
10
|
-
|
|
11
|
-
// ── UI 组件:createAIChat 按需加载 ────────────────────────────────
|
|
12
|
-
export const ArtifactPanel = () => import('./ArtifactPanel.vue')
|
|
13
|
-
export const ArtifactCard = () => import('./ArtifactCard.vue')
|
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useArtifactStore.js v2
|
|
3
|
-
*
|
|
4
|
-
* 对标 Claude Artifacts 体验:
|
|
5
|
-
* - 每个代码块 = 一个 Artifact(有文件名、语言、内容)
|
|
6
|
-
* - 右侧面板顶部 tab 栏展示当前会话所有 artifact,可切换
|
|
7
|
-
* - 聊天气泡里只显示轻量文件卡片
|
|
8
|
-
* - 流式生成时实时更新右侧面板内容
|
|
9
|
-
*/
|
|
10
|
-
import { ref, computed, provide, inject, shallowRef } from 'vue'
|
|
11
|
-
|
|
12
|
-
export const STORE_KEY = Symbol('artifact-store')
|
|
13
|
-
|
|
14
|
-
// ── 常量 ─────────────────────────────────────────────────────────
|
|
15
|
-
export const ARTIFACT_MIN_LINES = 6
|
|
16
|
-
|
|
17
|
-
export const ARTIFACT_LANGS = new Set([
|
|
18
|
-
'vue','html','jsx','tsx','mermaid','svg',
|
|
19
|
-
])
|
|
20
|
-
|
|
21
|
-
export const LANG_LABEL = {
|
|
22
|
-
vue:'Vue SFC', html:'HTML', jsx:'React JSX', tsx:'React TSX',
|
|
23
|
-
javascript:'JavaScript', js:'JavaScript', typescript:'TypeScript', ts:'TypeScript',
|
|
24
|
-
python:'Python', go:'Go', rust:'Rust', java:'Java', kotlin:'Kotlin', swift:'Swift',
|
|
25
|
-
css:'CSS', scss:'SCSS', sass:'SASS', less:'LESS',
|
|
26
|
-
sql:'SQL', graphql:'GraphQL',
|
|
27
|
-
bash:'Shell', sh:'Shell', shell:'Shell',
|
|
28
|
-
json:'JSON', yaml:'YAML', yml:'YAML', toml:'TOML', xml:'XML',
|
|
29
|
-
markdown:'Markdown', md:'Markdown',
|
|
30
|
-
mermaid:'Mermaid 图', svg:'SVG', math:'Math', latex:'LaTeX',
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export const LANG_EXT = {
|
|
34
|
-
vue:'vue', html:'html', jsx:'jsx', tsx:'tsx',
|
|
35
|
-
javascript:'js', js:'js', typescript:'ts', ts:'ts',
|
|
36
|
-
python:'py', go:'go', rust:'rs', java:'java', kotlin:'kt', swift:'swift',
|
|
37
|
-
css:'css', scss:'scss', sass:'sass', less:'less',
|
|
38
|
-
sql:'sql', graphql:'graphql', bash:'sh', sh:'sh', shell:'sh',
|
|
39
|
-
json:'json', yaml:'yaml', yml:'yaml', toml:'toml', xml:'xml',
|
|
40
|
-
markdown:'md', md:'md', mermaid:'mmd', svg:'svg', math:'tex', latex:'tex',
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ── 判断是否应成为 Artifact(兜底规则,优先级低于 AI 的 [artifact] 显式标记)──
|
|
44
|
-
// 仅当代码行数 >= 50 且语言有意义时自动路由到面板
|
|
45
|
-
export function shouldBeArtifact(lang, code) {
|
|
46
|
-
if (!code?.trim()) return false
|
|
47
|
-
if (!lang) return false
|
|
48
|
-
// text 语言超过行数阈值同样路由到面板,避免长文本只显示在气泡里
|
|
49
|
-
return code.split('\n').length >= 20
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// ── 推断文件名 ────────────────────────────────────────────────────
|
|
53
|
-
export function inferFileName(lang, code, index) {
|
|
54
|
-
const ext = LANG_EXT[lang] || 'txt'
|
|
55
|
-
|
|
56
|
-
if (lang === 'vue') {
|
|
57
|
-
const m = code.match(/(?:name|defineOptions\(\{[^}]*name):\s*['"]([^'"]+)['"]/)
|
|
58
|
-
|| code.match(/\/\/\s*([A-Z][a-zA-Z0-9]+)\.vue/)
|
|
59
|
-
if (m?.[1]) return `${m[1]}.vue`
|
|
60
|
-
return `Component${index > 1 ? index : ''}.vue`
|
|
61
|
-
}
|
|
62
|
-
if (lang === 'html') {
|
|
63
|
-
const m = code.match(/<title>([^<]{1,40})<\/title>/)
|
|
64
|
-
if (m?.[1]) return `${m[1].trim().replace(/\s+/g,'-').toLowerCase()}.html`
|
|
65
|
-
return `index.html`
|
|
66
|
-
}
|
|
67
|
-
if (lang === 'jsx' || lang === 'tsx') {
|
|
68
|
-
const m = code.match(/(?:function|const|class)\s+([A-Z][a-zA-Z0-9]+)/)
|
|
69
|
-
if (m?.[1]) return `${m[1]}.${ext}`
|
|
70
|
-
return `App.${ext}`
|
|
71
|
-
}
|
|
72
|
-
if (lang === 'mermaid') {
|
|
73
|
-
const first = code.trim().split('\n')[0]?.trim().replace(/\s+.*/,'').toLowerCase()
|
|
74
|
-
return first ? `${first}.mmd` : `diagram.mmd`
|
|
75
|
-
}
|
|
76
|
-
if (lang === 'python') {
|
|
77
|
-
const m = code.match(/^#\s*(.+)/m) || code.match(/def\s+(\w+)/)
|
|
78
|
-
if (m?.[1]) return `${m[1].trim().replace(/\s+/g,'_').toLowerCase()}.py`
|
|
79
|
-
return `script.py`
|
|
80
|
-
}
|
|
81
|
-
if (lang === 'json') {
|
|
82
|
-
try {
|
|
83
|
-
const obj = JSON.parse(code)
|
|
84
|
-
if (obj.name) return `${obj.name}.json`
|
|
85
|
-
} catch {}
|
|
86
|
-
return `data.json`
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return `${lang === 'javascript' || lang === 'js' ? 'script' : 'code'}-${index}.${ext}`
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// ── Store 工厂 ───────────────────────────────────────────────────
|
|
93
|
-
export function createArtifactStore() {
|
|
94
|
-
// 当前激活 artifact 的 code 独立 ref,专门用于外部精确订阅
|
|
95
|
-
// 因为 artifactsMap 是 shallowRef,item 对象内部属性变化无法被 computed/watch 自动追踪
|
|
96
|
-
const activeCode = ref('')
|
|
97
|
-
|
|
98
|
-
// 正在 streaming 的 artifact id 集合,用 ref 包装保证 ArtifactCard 能响应式追踪
|
|
99
|
-
const streamingIds = ref(new Set())
|
|
100
|
-
|
|
101
|
-
// 同步 activeCode 到当前激活 artifact 的 code
|
|
102
|
-
function syncActiveCode() {
|
|
103
|
-
const art = artifactsMap.value.get(activeId.value)
|
|
104
|
-
|| [...artifactsMap.value.values()].at(-1)
|
|
105
|
-
|| null
|
|
106
|
-
activeCode.value = art?.code ?? ''
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// 所有 artifact,shallowRef 避免深层响应式
|
|
110
|
-
const artifactsMap = shallowRef(new Map())
|
|
111
|
-
|
|
112
|
-
// 当前激活的 artifact id
|
|
113
|
-
const activeId = ref(null)
|
|
114
|
-
|
|
115
|
-
// 用户手动收起面板
|
|
116
|
-
const manuallyHidden = ref(false)
|
|
117
|
-
|
|
118
|
-
// 面板是否可见(有 artifact 且用户未手动收起)
|
|
119
|
-
const panelVisible = computed(() => artifactsMap.value.size > 0 && !manuallyHidden.value)
|
|
120
|
-
|
|
121
|
-
// 有序 artifact 列表:插入时直接 push,避免每次 computed 都 spread+sort
|
|
122
|
-
// 用 ref 包装,外部可直接响应式订阅
|
|
123
|
-
const allArtifacts = ref([])
|
|
124
|
-
|
|
125
|
-
// 当前激活的 artifact
|
|
126
|
-
const activeArtifact = computed(() =>
|
|
127
|
-
artifactsMap.value.get(activeId.value) || allArtifacts.value[allArtifacts.value.length - 1] || null
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
// 按 messageId 分组(MessageBubble 用)
|
|
131
|
-
// 只在 allArtifacts 变化时重建,不跟 artifactsMap 直接联动
|
|
132
|
-
const byMessage = computed(() => {
|
|
133
|
-
const map = new Map()
|
|
134
|
-
for (const art of allArtifacts.value) {
|
|
135
|
-
const list = map.get(art.messageId) || []
|
|
136
|
-
list.push(art)
|
|
137
|
-
map.set(art.messageId, list)
|
|
138
|
-
}
|
|
139
|
-
return map
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
let _seq = 0
|
|
143
|
-
|
|
144
|
-
function preRegister({ messageId, lang, index }) {
|
|
145
|
-
const id = `art-${messageId}-${index}`
|
|
146
|
-
if (artifactsMap.value.has(id)) return id
|
|
147
|
-
const label = LANG_LABEL[lang] || lang?.toUpperCase() || 'Code'
|
|
148
|
-
const ext = LANG_EXT[lang] || 'txt'
|
|
149
|
-
const fileName = `generating.${ext}`
|
|
150
|
-
const item = {
|
|
151
|
-
id, messageId, lang, code: '', fileName, label, lines: 0,
|
|
152
|
-
_seq: ++_seq, streaming: true,
|
|
153
|
-
}
|
|
154
|
-
const next = new Map(artifactsMap.value)
|
|
155
|
-
next.set(id, item)
|
|
156
|
-
artifactsMap.value = next
|
|
157
|
-
allArtifacts.value = [...allArtifacts.value, item] // 维护有序列表
|
|
158
|
-
activeId.value = id
|
|
159
|
-
manuallyHidden.value = false // 新 artifact 出现时自动展开面板
|
|
160
|
-
syncActiveCode()
|
|
161
|
-
return id
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function register({ messageId, lang, code, index }) {
|
|
165
|
-
const id = `art-${messageId}-${index}`
|
|
166
|
-
const label = LANG_LABEL[lang] || lang?.toUpperCase() || 'Code'
|
|
167
|
-
const lines = code.split('\n').length
|
|
168
|
-
const inferred = inferFileName(lang, code, index)
|
|
169
|
-
const fileName = (inferred && !inferred.startsWith('generating')) ? inferred : `code-${index}.${LANG_EXT[lang] || 'txt'}`
|
|
170
|
-
|
|
171
|
-
const existing = artifactsMap.value.get(id)
|
|
172
|
-
const newItem = existing
|
|
173
|
-
? { ...existing, code, lines, fileName: (inferred && !inferred.startsWith('generating')) ? inferred : existing.fileName }
|
|
174
|
-
: { id, messageId, lang, code, fileName, label, lines, _seq: ++_seq, streaming: false }
|
|
175
|
-
const next = new Map(artifactsMap.value)
|
|
176
|
-
next.set(id, newItem)
|
|
177
|
-
artifactsMap.value = next
|
|
178
|
-
// 同步更新有序列表
|
|
179
|
-
if (existing) {
|
|
180
|
-
const idx = allArtifacts.value.findIndex(a => a.id === id)
|
|
181
|
-
if (idx !== -1) {
|
|
182
|
-
const arr = [...allArtifacts.value]
|
|
183
|
-
arr[idx] = newItem
|
|
184
|
-
allArtifacts.value = arr
|
|
185
|
-
}
|
|
186
|
-
} else {
|
|
187
|
-
allArtifacts.value = [...allArtifacts.value, newItem]
|
|
188
|
-
}
|
|
189
|
-
activeId.value = id
|
|
190
|
-
syncActiveCode()
|
|
191
|
-
return id
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function updateCode(artifactId, code) {
|
|
195
|
-
const item = artifactsMap.value.get(artifactId)
|
|
196
|
-
if (!item) return
|
|
197
|
-
// 流式期间跳过 inferFileName 和 split('\n') 计行(高频调用,代码越长越慢)
|
|
198
|
-
// lines 保持原值,等 markDone 时一次性计算
|
|
199
|
-
const next = new Map(artifactsMap.value)
|
|
200
|
-
next.set(artifactId, { ...item, code, streaming: true })
|
|
201
|
-
artifactsMap.value = next
|
|
202
|
-
syncActiveCode()
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function markDone(artifactId) {
|
|
206
|
-
const item = artifactsMap.value.get(artifactId)
|
|
207
|
-
if (!item) return
|
|
208
|
-
// 流式结束时才做 inferFileName + split 计行,只执行一次
|
|
209
|
-
const inferred = inferFileName(item.lang, item.code, item._seq)
|
|
210
|
-
const lines = item.code ? item.code.split('\n').length : 0
|
|
211
|
-
const fileName = (inferred && !inferred.startsWith('generating')) ? inferred : item.fileName
|
|
212
|
-
const updatedItem = { ...item, streaming: false, lines, fileName }
|
|
213
|
-
const next = new Map(artifactsMap.value)
|
|
214
|
-
next.set(artifactId, updatedItem)
|
|
215
|
-
artifactsMap.value = next
|
|
216
|
-
// 同步更新有序列表中的对应项
|
|
217
|
-
const idx = allArtifacts.value.findIndex(a => a.id === artifactId)
|
|
218
|
-
if (idx !== -1) {
|
|
219
|
-
const arr = [...allArtifacts.value]
|
|
220
|
-
arr[idx] = updatedItem
|
|
221
|
-
allArtifacts.value = arr
|
|
222
|
-
}
|
|
223
|
-
syncActiveCode()
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function open(id) {
|
|
227
|
-
activeId.value = id
|
|
228
|
-
manuallyHidden.value = false
|
|
229
|
-
syncActiveCode()
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function close() {
|
|
233
|
-
manuallyHidden.value = true
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function clearSession() {
|
|
237
|
-
artifactsMap.value = new Map()
|
|
238
|
-
allArtifacts.value = []
|
|
239
|
-
activeId.value = null
|
|
240
|
-
manuallyHidden.value = false
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
function clearByMessage(messageId) {
|
|
244
|
-
const next = new Map(artifactsMap.value)
|
|
245
|
-
for (const [id, art] of next) {
|
|
246
|
-
if (art.messageId === messageId) next.delete(id)
|
|
247
|
-
}
|
|
248
|
-
if (activeId.value && !next.has(activeId.value)) {
|
|
249
|
-
activeId.value = next.size > 0 ? [...next.values()].at(-1).id : null
|
|
250
|
-
}
|
|
251
|
-
artifactsMap.value = next
|
|
252
|
-
allArtifacts.value = allArtifacts.value.filter(a => a.messageId !== messageId)
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
return {
|
|
256
|
-
artifactsMap, activeId, activeArtifact, activeCode,
|
|
257
|
-
allArtifacts, panelVisible, byMessage,
|
|
258
|
-
preRegister, register, updateCode, markDone,
|
|
259
|
-
open, close, clearSession, clearByMessage,
|
|
260
|
-
LANG_LABEL, LANG_EXT,
|
|
261
|
-
shouldBeArtifact,
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
export function provideArtifactStore() {
|
|
266
|
-
const store = createArtifactStore()
|
|
267
|
-
provide(STORE_KEY, store)
|
|
268
|
-
return store
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
export function useArtifactStore() {
|
|
272
|
-
const store = inject(STORE_KEY)
|
|
273
|
-
if (!store) throw new Error('useArtifactStore: missing provideArtifactStore()')
|
|
274
|
-
return store
|
|
275
|
-
}
|