@newsails/veil-studio 1.0.0
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 +181 -0
- package/bin/veil-studio.js +142 -0
- package/nuxt-app/.output/public/200.html +13 -0
- package/nuxt-app/.output/public/404.html +13 -0
- package/nuxt-app/.output/public/_nuxt/builds/latest.json +1 -0
- package/nuxt-app/.output/public/_nuxt/builds/meta/6b28df26-54af-4fad-a1f0-38808960d9fe.json +1 -0
- package/nuxt-app/.output/public/_nuxt/entry.BrrOeBSX.js +120 -0
- package/nuxt-app/.output/public/_nuxt/entry.CYnp7zY5.css +1 -0
- package/nuxt-app/.output/public/_nuxt/error-404.BbdzCaXe.js +1 -0
- package/nuxt-app/.output/public/_nuxt/error-404.JekaaCis.css +1 -0
- package/nuxt-app/.output/public/_nuxt/error-500.CNP9nqm1.css +1 -0
- package/nuxt-app/.output/public/_nuxt/error-500.DbOlBIIY.js +1 -0
- package/nuxt-app/.output/public/_nuxt/index.BEoXSIOu.css +1 -0
- package/nuxt-app/.output/public/_nuxt/index.CNms2yAq.js +1 -0
- package/nuxt-app/.output/public/_nuxt/materialdesignicons-webfont.B7mPwVP_.ttf +0 -0
- package/nuxt-app/.output/public/_nuxt/materialdesignicons-webfont.CSr8KVlo.eot +0 -0
- package/nuxt-app/.output/public/_nuxt/materialdesignicons-webfont.Dp5v-WZN.woff2 +0 -0
- package/nuxt-app/.output/public/_nuxt/materialdesignicons-webfont.PXm3-2wK.woff +0 -0
- package/nuxt-app/.output/public/_nuxt/vue.-sixQ7xP.BlWffD__.js +1 -0
- package/nuxt-app/.output/public/index.html +13 -0
- package/package.json +37 -0
- package/server/index.js +184 -0
- package/server/routes/files.js +80 -0
- package/server/socket.js +507 -0
- package/server/utils/board-state.js +357 -0
- package/server/utils/config.js +51 -0
- package/server/utils/db.js +484 -0
- package/server/utils/element-instances.js +104 -0
- package/server/utils/element-registry.js +127 -0
- package/server/utils/elements/agent-instance.js +62 -0
- package/server/utils/elements/agent.js +93 -0
- package/server/utils/elements/annotation.js +30 -0
- package/server/utils/elements/approval-gate.js +49 -0
- package/server/utils/elements/assumption.js +32 -0
- package/server/utils/elements/blocker.js +36 -0
- package/server/utils/elements/chat-room.js +47 -0
- package/server/utils/elements/chat-view.js +33 -0
- package/server/utils/elements/code-block.js +39 -0
- package/server/utils/elements/collapsible-group.js +37 -0
- package/server/utils/elements/comparison-table.js +38 -0
- package/server/utils/elements/constraint.js +32 -0
- package/server/utils/elements/decision.js +39 -0
- package/server/utils/elements/diff-patch.js +38 -0
- package/server/utils/elements/divider.js +30 -0
- package/server/utils/elements/document-draft.js +35 -0
- package/server/utils/elements/fact-claim.js +36 -0
- package/server/utils/elements/feedback-request.js +43 -0
- package/server/utils/elements/file-reference.js +31 -0
- package/server/utils/elements/filter.js +48 -0
- package/server/utils/elements/generator.js +51 -0
- package/server/utils/elements/goal.js +36 -0
- package/server/utils/elements/html.js +35 -0
- package/server/utils/elements/idea.js +32 -0
- package/server/utils/elements/image-local.js +21 -0
- package/server/utils/elements/image.js +34 -0
- package/server/utils/elements/json-object.js +47 -0
- package/server/utils/elements/label-tag.js +30 -0
- package/server/utils/elements/markdown.js +37 -0
- package/server/utils/elements/merger.js +36 -0
- package/server/utils/elements/message.js +40 -0
- package/server/utils/elements/milestone.js +44 -0
- package/server/utils/elements/notification.js +34 -0
- package/server/utils/elements/outline.js +35 -0
- package/server/utils/elements/primitive.js +36 -0
- package/server/utils/elements/pro-con-list.js +39 -0
- package/server/utils/elements/processor.js +54 -0
- package/server/utils/elements/project.js +40 -0
- package/server/utils/elements/question.js +42 -0
- package/server/utils/elements/queue.js +85 -0
- package/server/utils/elements/research-note.js +41 -0
- package/server/utils/elements/section.js +35 -0
- package/server/utils/elements/source-collection.js +45 -0
- package/server/utils/elements/splitter.js +42 -0
- package/server/utils/elements/status-update.js +38 -0
- package/server/utils/elements/task.js +72 -0
- package/server/utils/elements/template.js +46 -0
- package/server/utils/elements/test-case.js +42 -0
- package/server/utils/elements/text.js +29 -0
- package/server/utils/elements/todo-list.js +57 -0
- package/server/utils/elements/url-card.js +37 -0
- package/server/utils/elements/web-search-query.js +46 -0
- package/server/utils/elements/web-snapshot.js +37 -0
- package/server/utils/file-utils.js +88 -0
- package/server/utils/session-watcher.js +108 -0
- package/server/utils/socket-io.js +14 -0
- package/server/utils/veil-client.js +185 -0
- package/server/utils/veil-ws.js +207 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'agent-instance',
|
|
5
|
+
name: 'Agent Instance',
|
|
6
|
+
description: 'An active chat session with a VeilCLI agent.',
|
|
7
|
+
icon: 'message-circle',
|
|
8
|
+
defaultWidth: 180,
|
|
9
|
+
defaultHeight: 90,
|
|
10
|
+
expansionMode: 'sidebar',
|
|
11
|
+
tags: ['cli', 'agent', 'chat'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element, log } = context
|
|
17
|
+
let _isStreaming = false
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
getViewData() {
|
|
21
|
+
return {
|
|
22
|
+
agentName: element.data.agentName || null,
|
|
23
|
+
sessionId: element.data.sessionId || null,
|
|
24
|
+
isStreaming: _isStreaming,
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
getPorts() {
|
|
29
|
+
return [
|
|
30
|
+
{ key: 'msg-in', direction: 'input', dataType: 'text', label: 'Message In' },
|
|
31
|
+
{ key: 'msg-out', direction: 'output', dataType: 'text', label: 'Message Out' },
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
actions: {
|
|
36
|
+
setStreaming({ streaming }) {
|
|
37
|
+
_isStreaming = !!streaming
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
openChat(_params) {
|
|
41
|
+
// Handled client-side by useChat.ts
|
|
42
|
+
log('openChat action (client-side)')
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
async ensureSession(_params) {
|
|
46
|
+
if (element.data.sessionId) return
|
|
47
|
+
const { veil } = context
|
|
48
|
+
const agentName = element.data.agentName
|
|
49
|
+
if (!agentName) throw new Error('No agent name set')
|
|
50
|
+
try {
|
|
51
|
+
const session = await veil.post('/sessions', { agent: agentName })
|
|
52
|
+
const { updateElement } = require('../board-state.js')
|
|
53
|
+
updateElement(element.id, { data: { ...element.data, sessionId: session.id } })
|
|
54
|
+
} catch (err) {
|
|
55
|
+
log(`Failed to create session: ${err.message}`)
|
|
56
|
+
throw err
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'agent',
|
|
5
|
+
name: 'Agent',
|
|
6
|
+
description: 'A VeilCLI agent definition. Open a session to start chatting.',
|
|
7
|
+
icon: 'bot',
|
|
8
|
+
defaultWidth: 240,
|
|
9
|
+
defaultHeight: 130,
|
|
10
|
+
expansionMode: 'popup',
|
|
11
|
+
tags: ['cli', 'agent'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element, veil, emit, log } = context
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
getViewData() {
|
|
20
|
+
const name = element.data.name || element.data.agentName || null
|
|
21
|
+
const agentInfo = element.data.agentInfo || {}
|
|
22
|
+
return {
|
|
23
|
+
name,
|
|
24
|
+
agentName: name,
|
|
25
|
+
model: element.data.model || agentInfo.model || null,
|
|
26
|
+
description: element.data.description || agentInfo.description || null,
|
|
27
|
+
modes: element.data.modes || agentInfo.modes || null,
|
|
28
|
+
source: element.data.source || agentInfo.source || null,
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
getPorts() {
|
|
33
|
+
return [
|
|
34
|
+
{ key: 'instances', direction: 'output', dataType: 'agent', label: 'Instances' },
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
actions: {
|
|
39
|
+
async openSession(_params) {
|
|
40
|
+
const { createElement } = require('../board-state.js')
|
|
41
|
+
const { createInstance, getViewData, getPorts } = require('../element-instances.js')
|
|
42
|
+
const { getIO } = require('../socket-io.js')
|
|
43
|
+
|
|
44
|
+
const agentName = element.data.name || element.data.agentName
|
|
45
|
+
if (!agentName) throw new Error('No agent name set on this element')
|
|
46
|
+
|
|
47
|
+
log(`Creating Veil session for agent "${agentName}"`)
|
|
48
|
+
let sessionId = null
|
|
49
|
+
try {
|
|
50
|
+
const res = await veil.post('/sessions', { agentName })
|
|
51
|
+
sessionId = res.sessionId
|
|
52
|
+
log(`Session created: ${sessionId}`)
|
|
53
|
+
} catch (err) {
|
|
54
|
+
log(`Failed to create session: ${err.message}`)
|
|
55
|
+
throw new Error(`Could not create session: ${err.message}`)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const newEl = createElement({
|
|
59
|
+
type: 'agent-instance',
|
|
60
|
+
x: element.x + 200,
|
|
61
|
+
y: element.y,
|
|
62
|
+
width: 180,
|
|
63
|
+
height: 110,
|
|
64
|
+
data: { agentName, sessionId },
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
createInstance(newEl)
|
|
68
|
+
const viewData = getViewData(newEl.id)
|
|
69
|
+
const ports = getPorts(newEl.id)
|
|
70
|
+
getIO().to('board').emit('board:delta', {
|
|
71
|
+
type: 'element:view',
|
|
72
|
+
id: newEl.id,
|
|
73
|
+
viewData: { ...viewData, ports },
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
return { sessionId, elementId: newEl.id }
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
async refreshAgent(_params) {
|
|
80
|
+
const agentName = element.data.agentName
|
|
81
|
+
if (!agentName) return
|
|
82
|
+
try {
|
|
83
|
+
const agent = await veil.get(`/agents/${encodeURIComponent(agentName)}`)
|
|
84
|
+
const { updateElement } = require('../board-state.js')
|
|
85
|
+
updateElement(element.id, { data: { ...element.data, agentInfo: agent } })
|
|
86
|
+
} catch (err) {
|
|
87
|
+
log(`Failed to refresh agent: ${err.message}`)
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'annotation',
|
|
5
|
+
name: 'Annotation',
|
|
6
|
+
description: 'A floating note that follows its target element.',
|
|
7
|
+
icon: 'sticky-note',
|
|
8
|
+
defaultWidth: 180,
|
|
9
|
+
defaultHeight: 80,
|
|
10
|
+
expansionMode: 'inline',
|
|
11
|
+
tags: ['org'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return { text: element.data.text || '', targetId: element.data.targetId || null }
|
|
20
|
+
},
|
|
21
|
+
getPorts() { return [] },
|
|
22
|
+
actions: {
|
|
23
|
+
update(data = {}) {
|
|
24
|
+
const { updateElement } = require('../board-state.js')
|
|
25
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'approval-gate',
|
|
5
|
+
name: 'Approval Gate',
|
|
6
|
+
description: 'Gate flow on an approve/reject decision.',
|
|
7
|
+
icon: 'shield-check',
|
|
8
|
+
defaultWidth: 220,
|
|
9
|
+
defaultHeight: 90,
|
|
10
|
+
expansionMode: 'inline',
|
|
11
|
+
tags: ['comm', 'flow'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return {
|
|
20
|
+
title: element.data.title || '',
|
|
21
|
+
description: element.data.description || '',
|
|
22
|
+
status: element.data.status || 'pending',
|
|
23
|
+
reason: element.data.reason || null,
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
getPorts() {
|
|
27
|
+
return [
|
|
28
|
+
{ key: 'item-in', direction: 'input', dataType: 'any', label: 'Item In' },
|
|
29
|
+
{ key: 'approved-out', direction: 'output', dataType: 'any', label: 'Approved' },
|
|
30
|
+
{ key: 'rejected-out', direction: 'output', dataType: 'any', label: 'Rejected' },
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
actions: {
|
|
34
|
+
approve(_params) {
|
|
35
|
+
const { updateElement } = require('../board-state.js')
|
|
36
|
+
updateElement(element.id, { data: { ...element.data, status: 'approved', reason: null } })
|
|
37
|
+
},
|
|
38
|
+
reject({ reason } = {}) {
|
|
39
|
+
const { updateElement } = require('../board-state.js')
|
|
40
|
+
updateElement(element.id, { data: { ...element.data, status: 'rejected', reason: reason || null } })
|
|
41
|
+
},
|
|
42
|
+
reset(_params) {
|
|
43
|
+
const { updateElement } = require('../board-state.js')
|
|
44
|
+
updateElement(element.id, { data: { ...element.data, status: 'pending', reason: null } })
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'assumption',
|
|
5
|
+
name: 'Assumption',
|
|
6
|
+
description: 'An assumption that underlies a decision or plan.',
|
|
7
|
+
icon: 'quote',
|
|
8
|
+
defaultWidth: 180,
|
|
9
|
+
defaultHeight: 70,
|
|
10
|
+
expansionMode: 'inline',
|
|
11
|
+
tags: ['thinking'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return { text: element.data.text || '', challenged: element.data.challenged || false }
|
|
20
|
+
},
|
|
21
|
+
getPorts() {
|
|
22
|
+
return [{ key: 'assumption-out', direction: 'output', dataType: 'text', label: 'Assumption Out' }]
|
|
23
|
+
},
|
|
24
|
+
actions: {
|
|
25
|
+
update(data = {}) {
|
|
26
|
+
const { updateElement } = require('../board-state.js')
|
|
27
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'blocker',
|
|
5
|
+
name: 'Blocker',
|
|
6
|
+
description: 'Track a blocker or impediment.',
|
|
7
|
+
icon: 'octagon',
|
|
8
|
+
defaultWidth: 200,
|
|
9
|
+
defaultHeight: 80,
|
|
10
|
+
expansionMode: 'inline',
|
|
11
|
+
tags: ['thinking', 'pm'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return {
|
|
20
|
+
title: element.data.title || '',
|
|
21
|
+
description: element.data.description || '',
|
|
22
|
+
severity: element.data.severity || 'medium',
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
getPorts() {
|
|
26
|
+
return [{ key: 'blocker-out', direction: 'output', dataType: 'text', label: 'Blocker Out' }]
|
|
27
|
+
},
|
|
28
|
+
actions: {
|
|
29
|
+
update(data = {}) {
|
|
30
|
+
const { updateElement } = require('../board-state.js')
|
|
31
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'chat-room',
|
|
5
|
+
name: 'Chat Room',
|
|
6
|
+
description: 'A multi-agent chat room.',
|
|
7
|
+
icon: 'messages-square',
|
|
8
|
+
defaultWidth: 240,
|
|
9
|
+
defaultHeight: 150,
|
|
10
|
+
expansionMode: 'popup',
|
|
11
|
+
tags: ['comm'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element, emit } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return {
|
|
20
|
+
name: element.data.name || '',
|
|
21
|
+
messages: element.data.messages || [],
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
getPorts() {
|
|
25
|
+
return [
|
|
26
|
+
{ key: 'agents-in', direction: 'input', dataType: 'agent', label: 'Agents In' },
|
|
27
|
+
{ key: 'messages-out', direction: 'output', dataType: 'json', label: 'Messages Out' },
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
actions: {
|
|
31
|
+
postMessage({ role, content } = {}) {
|
|
32
|
+
const { updateElement } = require('../board-state.js')
|
|
33
|
+
const messages = [
|
|
34
|
+
...(element.data.messages || []),
|
|
35
|
+
{ role, content, timestamp: Date.now() },
|
|
36
|
+
]
|
|
37
|
+
updateElement(element.id, { data: { ...element.data, messages } })
|
|
38
|
+
emit('element:view', { id: element.id, viewData: { messages } })
|
|
39
|
+
},
|
|
40
|
+
update(data = {}) {
|
|
41
|
+
const { updateElement } = require('../board-state.js')
|
|
42
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'chat-view',
|
|
5
|
+
name: 'Chat View',
|
|
6
|
+
description: 'Inline chat panel for an agent session. Created automatically from an agent instance.',
|
|
7
|
+
icon: '💬',
|
|
8
|
+
defaultWidth: 320,
|
|
9
|
+
defaultHeight: 440,
|
|
10
|
+
hiddenFromPalette: true,
|
|
11
|
+
tags: ['cli'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
|
|
14
|
+
createInstance(context) {
|
|
15
|
+
const { element } = context
|
|
16
|
+
let _isStreaming = false
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return {
|
|
20
|
+
agentName: element.data.agentName || null,
|
|
21
|
+
sessionId: element.data.sessionId || null,
|
|
22
|
+
isStreaming: _isStreaming,
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
getPorts() { return [] },
|
|
26
|
+
actions: {
|
|
27
|
+
setStreaming({ streaming }) {
|
|
28
|
+
_isStreaming = !!streaming
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'code-block',
|
|
5
|
+
name: 'Code Block',
|
|
6
|
+
description: 'A syntax-highlighted code snippet.',
|
|
7
|
+
icon: 'code',
|
|
8
|
+
defaultWidth: 240,
|
|
9
|
+
defaultHeight: 120,
|
|
10
|
+
expansionMode: 'popup',
|
|
11
|
+
tags: ['data', 'dev'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
|
|
14
|
+
createInstance(context) {
|
|
15
|
+
const { element } = context
|
|
16
|
+
return {
|
|
17
|
+
getViewData() {
|
|
18
|
+
return {
|
|
19
|
+
code: element.data.code || '',
|
|
20
|
+
language: element.data.language || 'text',
|
|
21
|
+
title: element.data.title || '',
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
getPorts() {
|
|
25
|
+
return [{ key: 'code-out', direction: 'output', dataType: 'text', label: 'Code Out' }]
|
|
26
|
+
},
|
|
27
|
+
actions: {
|
|
28
|
+
update({ code, language, title } = {}) {
|
|
29
|
+
const { updateElement } = require('../board-state.js')
|
|
30
|
+
const data = { ...element.data }
|
|
31
|
+
if (code !== undefined) data.code = code
|
|
32
|
+
if (language !== undefined) data.language = language
|
|
33
|
+
if (title !== undefined) data.title = title
|
|
34
|
+
updateElement(element.id, { data })
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'collapsible-group',
|
|
5
|
+
name: 'Collapsible Group',
|
|
6
|
+
description: 'A group that contains other elements and can be collapsed.',
|
|
7
|
+
icon: 'group',
|
|
8
|
+
defaultWidth: 300,
|
|
9
|
+
defaultHeight: 200,
|
|
10
|
+
expansionMode: 'inline',
|
|
11
|
+
tags: ['org'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return {
|
|
20
|
+
label: element.data.label || '',
|
|
21
|
+
collapsed: element.data.collapsed || false,
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
getPorts() { return [] },
|
|
25
|
+
actions: {
|
|
26
|
+
toggle(_params) {
|
|
27
|
+
const { updateElement } = require('../board-state.js')
|
|
28
|
+
updateElement(element.id, { data: { ...element.data, collapsed: !element.data.collapsed } })
|
|
29
|
+
},
|
|
30
|
+
update(data = {}) {
|
|
31
|
+
const { updateElement } = require('../board-state.js')
|
|
32
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'comparison-table',
|
|
5
|
+
name: 'Comparison Table',
|
|
6
|
+
description: 'Compare items across multiple dimensions.',
|
|
7
|
+
icon: 'table',
|
|
8
|
+
defaultWidth: 280,
|
|
9
|
+
defaultHeight: 150,
|
|
10
|
+
expansionMode: 'popup',
|
|
11
|
+
tags: ['research', 'data'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return {
|
|
20
|
+
headers: element.data.headers || [],
|
|
21
|
+
rows: element.data.rows || [],
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
getPorts() {
|
|
25
|
+
return [
|
|
26
|
+
{ key: 'items-in', direction: 'input', dataType: 'any', label: 'Items In' },
|
|
27
|
+
{ key: 'table-out', direction: 'output', dataType: 'json', label: 'Table Out' },
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
actions: {
|
|
31
|
+
update(data = {}) {
|
|
32
|
+
const { updateElement } = require('../board-state.js')
|
|
33
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'constraint',
|
|
5
|
+
name: 'Constraint',
|
|
6
|
+
description: 'A hard or soft constraint on a solution.',
|
|
7
|
+
icon: 'lock',
|
|
8
|
+
defaultWidth: 180,
|
|
9
|
+
defaultHeight: 70,
|
|
10
|
+
expansionMode: 'inline',
|
|
11
|
+
tags: ['thinking'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return { text: element.data.text || '', severity: element.data.severity || 'hard' }
|
|
20
|
+
},
|
|
21
|
+
getPorts() {
|
|
22
|
+
return [{ key: 'constraint-out', direction: 'output', dataType: 'text', label: 'Constraint Out' }]
|
|
23
|
+
},
|
|
24
|
+
actions: {
|
|
25
|
+
update(data = {}) {
|
|
26
|
+
const { updateElement } = require('../board-state.js')
|
|
27
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'decision',
|
|
5
|
+
name: 'Decision',
|
|
6
|
+
description: 'Record a decision with rationale.',
|
|
7
|
+
icon: 'git-branch',
|
|
8
|
+
defaultWidth: 200,
|
|
9
|
+
defaultHeight: 90,
|
|
10
|
+
expansionMode: 'inline',
|
|
11
|
+
tags: ['thinking'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return {
|
|
20
|
+
title: element.data.title || '',
|
|
21
|
+
chosen: element.data.chosen || '',
|
|
22
|
+
rationale: element.data.rationale || '',
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
getPorts() {
|
|
26
|
+
return [
|
|
27
|
+
{ key: 'options-in', direction: 'input', dataType: 'any', label: 'Options In' },
|
|
28
|
+
{ key: 'decision-out', direction: 'output', dataType: 'text', label: 'Decision Out' },
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
actions: {
|
|
32
|
+
update(data = {}) {
|
|
33
|
+
const { updateElement } = require('../board-state.js')
|
|
34
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'diff-patch',
|
|
5
|
+
name: 'Diff / Patch',
|
|
6
|
+
description: 'Show the diff between original and modified text.',
|
|
7
|
+
icon: 'git-diff',
|
|
8
|
+
defaultWidth: 280,
|
|
9
|
+
defaultHeight: 150,
|
|
10
|
+
expansionMode: 'popup',
|
|
11
|
+
tags: ['dev'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
|
|
14
|
+
createInstance(context) {
|
|
15
|
+
const { element } = context
|
|
16
|
+
return {
|
|
17
|
+
getViewData() {
|
|
18
|
+
return {
|
|
19
|
+
source: element.data.source || '',
|
|
20
|
+
change: element.data.change || '',
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
getPorts() {
|
|
24
|
+
return [
|
|
25
|
+
{ key: 'source-in', direction: 'input', dataType: 'text', label: 'Source In' },
|
|
26
|
+
{ key: 'change-in', direction: 'input', dataType: 'text', label: 'Change In' },
|
|
27
|
+
{ key: 'change-out', direction: 'output', dataType: 'text', label: 'Change Out' },
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
actions: {
|
|
31
|
+
update(data = {}) {
|
|
32
|
+
const { updateElement } = require('../board-state.js')
|
|
33
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'divider',
|
|
5
|
+
name: 'Divider',
|
|
6
|
+
description: 'A visual separator line.',
|
|
7
|
+
icon: 'minus',
|
|
8
|
+
defaultWidth: 300,
|
|
9
|
+
defaultHeight: 4,
|
|
10
|
+
expansionMode: 'inline',
|
|
11
|
+
tags: ['org'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return { color: element.data.color || '#475569', thickness: element.data.thickness || 1 }
|
|
20
|
+
},
|
|
21
|
+
getPorts() { return [] },
|
|
22
|
+
actions: {
|
|
23
|
+
update(data = {}) {
|
|
24
|
+
const { updateElement } = require('../board-state.js')
|
|
25
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
type: 'document-draft',
|
|
5
|
+
name: 'Document Draft',
|
|
6
|
+
description: 'A document draft with title and content.',
|
|
7
|
+
icon: 'file-edit',
|
|
8
|
+
defaultWidth: 200,
|
|
9
|
+
defaultHeight: 100,
|
|
10
|
+
expansionMode: 'sidebar',
|
|
11
|
+
tags: ['docs'],
|
|
12
|
+
isBuiltIn: true,
|
|
13
|
+
hiddenFromPalette: true,
|
|
14
|
+
|
|
15
|
+
createInstance(context) {
|
|
16
|
+
const { element } = context
|
|
17
|
+
return {
|
|
18
|
+
getViewData() {
|
|
19
|
+
return { title: element.data.title || '', content: element.data.content || '' }
|
|
20
|
+
},
|
|
21
|
+
getPorts() {
|
|
22
|
+
return [
|
|
23
|
+
{ key: 'sections-in', direction: 'input', dataType: 'text', label: 'Sections In' },
|
|
24
|
+
{ key: 'doc-out', direction: 'output', dataType: 'text', label: 'Doc Out' },
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
actions: {
|
|
28
|
+
update(data = {}) {
|
|
29
|
+
const { updateElement } = require('../board-state.js')
|
|
30
|
+
updateElement(element.id, { data: { ...element.data, ...data } })
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
}
|