subagent thinking accordion; indicator fixes; script details & edit
This commit is contained in:
759
web/package-lock.json
generated
759
web/package-lock.json
generated
@@ -9,10 +9,13 @@
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@primevue/themes": "^4.5.4",
|
||||
"@tiptap/starter-kit": "^3.22.4",
|
||||
"@tiptap/vue-3": "^3.22.4",
|
||||
"fast-json-patch": "^3.1.1",
|
||||
"pinia": "^3.0.4",
|
||||
"primeicons": "^7.0.0",
|
||||
"primevue": "^4.5.4",
|
||||
"tiptap-markdown": "^0.9.0",
|
||||
"vue": "^3.5.29",
|
||||
"vue-advanced-chat": "^2.0.4",
|
||||
"vue-router": "^5.0.3"
|
||||
@@ -133,6 +136,7 @@
|
||||
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.29.0",
|
||||
"@babel/generator": "^7.29.0",
|
||||
@@ -657,6 +661,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
@@ -697,6 +702,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
}
|
||||
@@ -1161,6 +1167,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
|
||||
"integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/utils": "^0.2.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.7.6",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
|
||||
"integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.7.5",
|
||||
"@floating-ui/utils": "^0.2.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.11",
|
||||
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
|
||||
"integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
@@ -1695,6 +1727,431 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tiptap/core": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.22.4.tgz",
|
||||
"integrity": "sha512-vGIGm/HpqLg8EAAQXQ+koV+/S828OEpzocfWcPOwo1u2QUVf9dQG47Yy6JJ8zFFaJwfv4dBcOXli+7BrJwsxDQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/pm": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-blockquote": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.22.4.tgz",
|
||||
"integrity": "sha512-7/61kNPbGFhMgM//zMknD0pSb69rGdRIkpulXOWS1JBrFHkH6hjZDfrOETNzgKkO+NlmzVl9rXSTv0xauS3lzA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bold": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.22.4.tgz",
|
||||
"integrity": "sha512-jIaPKfNOQu2lhpbLDvtwlQqM+mjF+Kk+auHpzYjBnsuwUli1Cl5ZOau7RH+rru/SQvZe1DtpQlANujDywugZAA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bubble-menu": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.22.4.tgz",
|
||||
"integrity": "sha512-v4pux5Ql3THAEjaLMY4ldtdy/Xy2qU7PJLBkq8ugLp8qicaKC+tpqxp6sGif4vLIjz7Ap5hurRbTNbXzszyyHA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4",
|
||||
"@tiptap/pm": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bullet-list": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.22.4.tgz",
|
||||
"integrity": "sha512-TB+d3fGcTixYjO7coKqTr1mGTJuqr8hjDCPUFgzuvKyJnBhqWITmBzQ/8CLq4rr6mihgGURbD3N+xkQuPAKFiw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-code": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.22.4.tgz",
|
||||
"integrity": "sha512-cnbxmVhAcc7X3G81QUYEmKP0ve2hRmvAiFXBuuv9RUtQlBiRnzmhHoJOMgkX0CsMR7+8kMRpTfeDUYq2xp5s5w==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-code-block": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.22.4.tgz",
|
||||
"integrity": "sha512-MEurzNXfMET3rhjpoPJYUgMfxTdTqbzT9+ToFrqNGAHocdXVm6m1hhO2frVC7fEtHPnxXKsn0Z3NUbCRkRTLuA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4",
|
||||
"@tiptap/pm": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-document": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.22.4.tgz",
|
||||
"integrity": "sha512-XQKla1+703FqQJC48tPDVgt9ucGiFbIEmQdOg5L5o07z9a6/NzuaZAc+1zJ7NxcUZzy+z6wBn1PrVMTiqiSXlw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-dropcursor": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.22.4.tgz",
|
||||
"integrity": "sha512-N9/yMDC35jJp0V/naL0+6gi4gUDUIcPpWEzFdCDWUSYBA8mt41c1kI1ZU7UTKYIBzTClenhYHRc2XKZxxx0+LQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extensions": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-floating-menu": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.22.4.tgz",
|
||||
"integrity": "sha512-DFuyYxgaZPgxum5z1yvJPbfYCvDdO8geXsdyqt0qYYdiat3aGE4ncJhiLRIFDhSHBhaZg5eCgu/YPYAN6jZnrA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@floating-ui/dom": "^1.0.0",
|
||||
"@tiptap/core": "3.22.4",
|
||||
"@tiptap/pm": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-gapcursor": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.22.4.tgz",
|
||||
"integrity": "sha512-UYBEUj3SFpKINIE7AdzcyeS3xICK+ee+YLBbuqNXyHStYChjJOohzJehqiqhjR16A88KQQ+ZjgyDcItKGygSog==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extensions": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-hard-break": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.22.4.tgz",
|
||||
"integrity": "sha512-xq+a4dE7T6VwApCkh/yU3p30gn3F8g8Arb9CyEZm58/WIJUIGvHSTjDdHmvU16+kiWSBg+wOOsaFHhYjJjxcKA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-heading": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.22.4.tgz",
|
||||
"integrity": "sha512-TUaj5f0Ir5qy9HKKt2ocnwfXKpZDYeHgbbP9gshKFzdq5PLe1RbIgkjfy6bnoI865cYjmPYWRjcT7XsKyIcb9Q==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-horizontal-rule": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.22.4.tgz",
|
||||
"integrity": "sha512-cCI1HekGQwhY/MbgaKQ0R/7HcH5ZM1oFAyI/J72QGLC0XnF403S/OXoHMuBWr1mCu8hNiQWCzeNRJUty0iytNw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4",
|
||||
"@tiptap/pm": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-italic": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.22.4.tgz",
|
||||
"integrity": "sha512-fVSDx5AYXgDI3v2zZIqb7V8EewthwM2NJ/ZCX+XaxRsqNEpnjVhgHs7UlvDqK1wj2OJ6zmUNjPtVlAFRxwT+HQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-link": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.22.4.tgz",
|
||||
"integrity": "sha512-uoP3yus02uwGPVzW2QaEPJWVIrUb/r5nKm6c8DiJv9fNSX1+gykZZMg42c6GwRFLZ/vyfWjVCbAE03VMUqafgA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"linkifyjs": "^4.3.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4",
|
||||
"@tiptap/pm": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.22.4.tgz",
|
||||
"integrity": "sha512-Xe8UFvvHmyp/c/TJsFwlwU9CWACYbBirNsluJ3U1+H8BTu1wqdrT/AXR5uIXeyCl5kiWKgX5q71eHWbYFOrqrg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4",
|
||||
"@tiptap/pm": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list-item": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.22.4.tgz",
|
||||
"integrity": "sha512-H659KXTvggSypIDWSOJBZ37jh9pKjQriDDvYPYvOZCdfij0D0hsDXN/wXoypArneUkoBdgruHfTtMkFOaQlgkw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list-keymap": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.22.4.tgz",
|
||||
"integrity": "sha512-t/zhker4oIS78AIGYDdFFfZC6zSBlszfD7z/zqFLGCg5PHNNgkZK5hKj6Vyix6D2SapRn/ajnx+8mhbKIUH5eA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-ordered-list": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.22.4.tgz",
|
||||
"integrity": "sha512-w77hPVf7pcHt97vfrybg/l0t5CimCd4y75OJKuHuo3CfgM5xbUP/gaPNMDyLLe7MYole/UHi/XvG3XjgzqTzAw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-paragraph": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.22.4.tgz",
|
||||
"integrity": "sha512-de6dFkIhigiENESY6rNJ3yTVS/337ybfP30dNPudTwGe9oAu9ZCS+04j6QCvXSjhlI3ULiv7wiSHqrP26Gd+Hw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-strike": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.22.4.tgz",
|
||||
"integrity": "sha512-aRHWQj42HiailXSC9LkKYM3jWMcSeGwOjbqM4PiuxQZmHVDRFmeHkfJItOdn2cSHaO0vuEVK+TvrWUWsBFi3pg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-text": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.22.4.tgz",
|
||||
"integrity": "sha512-mM69uUW5cSxIhyEpWXi/YcfyupcJMDLCPEfYi62awH0iOP/LRoCv/nHjJq4Hyj/KxRJbe8HKwIUnqaCUf7m5Pg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-underline": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.22.4.tgz",
|
||||
"integrity": "sha512-08kGdbhIrA6h10GWXqOkqIveaBj5tmxclK208/nUIAlonI9hPd739vu7fmVtpnmqCnSSNpoRtU4u6Gj5at0ZpA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extensions": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.22.4.tgz",
|
||||
"integrity": "sha512-fOe8VptJvLPs32bNdUYo8SRyljwqKNQVXWW056VoXIc5en/59OdJlJQVeHI0jRRciH3MtrqODi/gfJR0VHNZ8A==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.22.4",
|
||||
"@tiptap/pm": "3.22.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/pm": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.22.4.tgz",
|
||||
"integrity": "sha512-hj8Qka6WcHRllHUdeSjDnq2XaisUo4KsoGJc1WcFpoa1Yd+OeD861zUMnV7DFVGdZRy45Obht0CUYJpXQ4yA4w==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"prosemirror-changeset": "^2.3.0",
|
||||
"prosemirror-commands": "^1.6.2",
|
||||
"prosemirror-dropcursor": "^1.8.1",
|
||||
"prosemirror-gapcursor": "^1.3.2",
|
||||
"prosemirror-history": "^1.4.1",
|
||||
"prosemirror-keymap": "^1.2.2",
|
||||
"prosemirror-model": "^1.24.1",
|
||||
"prosemirror-schema-list": "^1.5.0",
|
||||
"prosemirror-state": "^1.4.3",
|
||||
"prosemirror-tables": "^1.6.4",
|
||||
"prosemirror-transform": "^1.10.2",
|
||||
"prosemirror-view": "^1.38.1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/starter-kit": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.22.4.tgz",
|
||||
"integrity": "sha512-qWjw+vfdin1rzMRpRU4cC5tLTwMJtUpXeQukv+6mOqqvhptuwuZBjUHImVEJaSPoHXS7+1ut+nTnrLyWyEuE5Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tiptap/core": "^3.22.4",
|
||||
"@tiptap/extension-blockquote": "^3.22.4",
|
||||
"@tiptap/extension-bold": "^3.22.4",
|
||||
"@tiptap/extension-bullet-list": "^3.22.4",
|
||||
"@tiptap/extension-code": "^3.22.4",
|
||||
"@tiptap/extension-code-block": "^3.22.4",
|
||||
"@tiptap/extension-document": "^3.22.4",
|
||||
"@tiptap/extension-dropcursor": "^3.22.4",
|
||||
"@tiptap/extension-gapcursor": "^3.22.4",
|
||||
"@tiptap/extension-hard-break": "^3.22.4",
|
||||
"@tiptap/extension-heading": "^3.22.4",
|
||||
"@tiptap/extension-horizontal-rule": "^3.22.4",
|
||||
"@tiptap/extension-italic": "^3.22.4",
|
||||
"@tiptap/extension-link": "^3.22.4",
|
||||
"@tiptap/extension-list": "^3.22.4",
|
||||
"@tiptap/extension-list-item": "^3.22.4",
|
||||
"@tiptap/extension-list-keymap": "^3.22.4",
|
||||
"@tiptap/extension-ordered-list": "^3.22.4",
|
||||
"@tiptap/extension-paragraph": "^3.22.4",
|
||||
"@tiptap/extension-strike": "^3.22.4",
|
||||
"@tiptap/extension-text": "^3.22.4",
|
||||
"@tiptap/extension-underline": "^3.22.4",
|
||||
"@tiptap/extensions": "^3.22.4",
|
||||
"@tiptap/pm": "^3.22.4"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/vue-3": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/vue-3/-/vue-3-3.22.4.tgz",
|
||||
"integrity": "sha512-fcqUWt6LlA5PbcFaDXyV1apWwAs8j80m0kWwoL5+DgKdkGxsB5LgDZU1pTWle0zvR5zmGvJ7LmB6EGAYIBjdmQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tiptap/extension-bubble-menu": "^3.22.4",
|
||||
"@tiptap/extension-floating-menu": "^3.22.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@floating-ui/dom": "^1.0.0",
|
||||
"@tiptap/core": "3.22.4",
|
||||
"@tiptap/pm": "3.22.4",
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/node24": {
|
||||
"version": "24.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node24/-/node24-24.0.4.tgz",
|
||||
@@ -1749,6 +2206,28 @@
|
||||
"undici-types": "^7.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/linkify-it": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz",
|
||||
"integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/markdown-it": {
|
||||
"version": "13.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-13.0.9.tgz",
|
||||
"integrity": "sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "^3",
|
||||
"@types/mdurl": "^1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mdurl": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz",
|
||||
"integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/ms": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
|
||||
@@ -2371,6 +2850,12 @@
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/assertion-error": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
|
||||
@@ -2482,6 +2967,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.9.0",
|
||||
"caniuse-lite": "^1.0.30001759",
|
||||
@@ -3411,6 +3897,21 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"uc.micro": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/linkifyjs": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.2.tgz",
|
||||
"integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/local-pkg": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
|
||||
@@ -3462,6 +3963,41 @@
|
||||
"url": "https://github.com/sponsors/sxzz"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it": {
|
||||
"version": "14.1.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz",
|
||||
"integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
"entities": "^4.4.0",
|
||||
"linkify-it": "^5.0.0",
|
||||
"mdurl": "^2.0.0",
|
||||
"punycode.js": "^2.3.1",
|
||||
"uc.micro": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"markdown-it": "bin/markdown-it.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it-task-lists": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz",
|
||||
"integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/markdown-it/node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/mdn-data": {
|
||||
"version": "2.12.2",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz",
|
||||
@@ -3469,6 +4005,12 @@
|
||||
"dev": true,
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/memorystream": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
|
||||
@@ -4252,6 +4794,12 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/orderedmap": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
|
||||
"integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/package-json-from-dist": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
||||
@@ -4374,6 +4922,7 @@
|
||||
"resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.4.tgz",
|
||||
"integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^7.7.7"
|
||||
},
|
||||
@@ -4451,6 +5000,168 @@
|
||||
"node": ">=12.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-changeset": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.4.1.tgz",
|
||||
"integrity": "sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-transform": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-commands": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz",
|
||||
"integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.10.2"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-dropcursor": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz",
|
||||
"integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.1.0",
|
||||
"prosemirror-view": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-gapcursor": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.1.tgz",
|
||||
"integrity": "sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-keymap": "^1.0.0",
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-view": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-history": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.5.0.tgz",
|
||||
"integrity": "sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.2.2",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.31.0",
|
||||
"rope-sequence": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-keymap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz",
|
||||
"integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"w3c-keyname": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-markdown": {
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.4.tgz",
|
||||
"integrity": "sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/markdown-it": "^14.0.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"prosemirror-model": "^1.25.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-markdown/node_modules/@types/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/prosemirror-markdown/node_modules/@types/markdown-it": {
|
||||
"version": "14.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
|
||||
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "^5",
|
||||
"@types/mdurl": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-markdown/node_modules/@types/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/prosemirror-model": {
|
||||
"version": "1.25.4",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz",
|
||||
"integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"orderedmap": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-schema-list": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz",
|
||||
"integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-state": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz",
|
||||
"integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.27.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-tables": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.5.tgz",
|
||||
"integrity": "sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-keymap": "^1.2.3",
|
||||
"prosemirror-model": "^1.25.4",
|
||||
"prosemirror-state": "^1.4.4",
|
||||
"prosemirror-transform": "^1.10.5",
|
||||
"prosemirror-view": "^1.41.4"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-transform": {
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.12.0.tgz",
|
||||
"integrity": "sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-view": {
|
||||
"version": "1.41.8",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.8.tgz",
|
||||
"integrity": "sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.20.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proto-list": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
|
||||
@@ -4468,6 +5179,15 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode.js": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
||||
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/quansync": {
|
||||
"version": "0.2.11",
|
||||
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
|
||||
@@ -4572,6 +5292,12 @@
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/rope-sequence": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
|
||||
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/run-applescript": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
|
||||
@@ -4895,6 +5621,24 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tiptap-markdown": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/tiptap-markdown/-/tiptap-markdown-0.9.0.tgz",
|
||||
"integrity": "sha512-dKLQ9iiuGNgrlGVjrNauF/UBzWu4LYOx5pkD0jNkmQt/GOwfCJsBuzZTsf1jZ204ANHOm572mZ9PYvGh1S7tpQ==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"example"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/markdown-it": "^13.0.7",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-task-lists": "^2.1.1",
|
||||
"prosemirror-markdown": "^1.11.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/tldts": {
|
||||
"version": "7.0.23",
|
||||
"resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.23.tgz",
|
||||
@@ -4957,6 +5701,7 @@
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -4965,6 +5710,12 @@
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/uc.micro": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
||||
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ufo": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz",
|
||||
@@ -5073,6 +5824,7 @@
|
||||
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.27.0",
|
||||
"fdir": "^6.5.0",
|
||||
@@ -5429,6 +6181,7 @@
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.29.tgz",
|
||||
"integrity": "sha512-BZqN4Ze6mDQVNAni0IHeMJ5mwr8VAJ3MQC9FmprRhcBYENw+wOAAjRj8jfmN6FLl0j96OXbR+CjWhmAmM+QGnA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.29",
|
||||
"@vue/compiler-sfc": "3.5.29",
|
||||
@@ -5564,6 +6317,12 @@
|
||||
"typescript": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/w3c-xmlserializer": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
|
||||
|
||||
@@ -13,10 +13,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@primevue/themes": "^4.5.4",
|
||||
"@tiptap/starter-kit": "^3.22.4",
|
||||
"@tiptap/vue-3": "^3.22.4",
|
||||
"fast-json-patch": "^3.1.1",
|
||||
"pinia": "^3.0.4",
|
||||
"primeicons": "^7.0.0",
|
||||
"primevue": "^4.5.4",
|
||||
"tiptap-markdown": "^0.9.0",
|
||||
"vue": "^3.5.29",
|
||||
"vue-advanced-chat": "^2.0.4",
|
||||
"vue-router": "^5.0.3"
|
||||
|
||||
@@ -8,6 +8,8 @@ import TabPanel from 'primevue/tabpanel'
|
||||
import OrdersTab from './tabs/OrdersTab.vue'
|
||||
import PlaceholderTab from './tabs/PlaceholderTab.vue'
|
||||
import ResearchTab from './tabs/ResearchTab.vue'
|
||||
import StrategiesTab from './tabs/StrategiesTab.vue'
|
||||
import IndicatorsTab from './tabs/IndicatorsTab.vue'
|
||||
|
||||
interface TempTab {
|
||||
id: string
|
||||
@@ -84,10 +86,11 @@ defineExpose({
|
||||
<div v-if="isExpanded" class="tray-resize-handle" @pointerdown="startResize" @pointermove="onResizeMove" />
|
||||
<Tabs :value="isExpanded ? activeTab : null" class="tray-tabs">
|
||||
<TabList class="tray-tab-list">
|
||||
<Tab value="positions" @click="onTabClick('positions')">Positions</Tab>
|
||||
<Tab value="orders" @click="onTabClick('orders')">Orders</Tab>
|
||||
<Tab value="indicators" @click="onTabClick('indicators')">Indicators</Tab>
|
||||
<Tab value="research" @click="onTabClick('research')">Research</Tab>
|
||||
<Tab value="strategies" @click="onTabClick('strategies')">Strategies</Tab>
|
||||
<Tab value="positions" @click="onTabClick('positions')">Positions</Tab>
|
||||
<Tab
|
||||
v-for="tab in tempTabs"
|
||||
:key="tab.id"
|
||||
@@ -106,8 +109,9 @@ defineExpose({
|
||||
<TabPanels v-if="isExpanded" class="tray-panels">
|
||||
<TabPanel value="positions" class="tray-panel"><PlaceholderTab label="Positions" /></TabPanel>
|
||||
<TabPanel value="orders" class="tray-panel"><OrdersTab /></TabPanel>
|
||||
<TabPanel value="strategies" class="tray-panel"><PlaceholderTab label="Strategies" /></TabPanel>
|
||||
<TabPanel value="research" class="tray-panel"><ResearchTab /></TabPanel>
|
||||
<TabPanel value="indicators" class="tray-panel"><IndicatorsTab /></TabPanel>
|
||||
<TabPanel value="strategies" class="tray-panel"><StrategiesTab /></TabPanel>
|
||||
<TabPanel
|
||||
v-for="tab in tempTabs"
|
||||
:key="tab.id"
|
||||
|
||||
107
web/src/components/CategoryItemList.vue
Normal file
107
web/src/components/CategoryItemList.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import DetailsEditDialog from './DetailsEditDialog.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
category: 'indicator' | 'strategy' | 'research'
|
||||
rows: Array<{ id: string; display_name: string; description?: string }>
|
||||
}>()
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const editingName = ref('')
|
||||
|
||||
function openEdit(name: string) {
|
||||
editingName.value = name
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function onUpdated(_payload: { category: string; name: string; success: boolean; error?: string }) {
|
||||
// Hook for handling the details_updated response — add logic here as needed
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="category-list">
|
||||
<div v-if="rows.length === 0" class="empty">No items</div>
|
||||
<div v-for="row in rows" :key="row.id" class="item-row">
|
||||
<span class="item-name">{{ row.display_name }}</span>
|
||||
<span class="item-desc">{{ row.description ?? '' }}</span>
|
||||
<button class="edit-btn" @click="openEdit(row.display_name)">Edit</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DetailsEditDialog
|
||||
v-model:visible="dialogVisible"
|
||||
:category="category"
|
||||
:name="editingName"
|
||||
@updated="onUpdated"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.category-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.empty {
|
||||
color: #555;
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.item-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 5px 10px;
|
||||
border-bottom: 1px solid #1e1e1e;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.item-row:hover {
|
||||
background: #1a1a1a;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #dbdbdb;
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
max-width: 180px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.item-desc {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 12px;
|
||||
color: #777;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-webkit-mask-image: linear-gradient(to right, black calc(100% - 48px), transparent 100%);
|
||||
mask-image: linear-gradient(to right, black calc(100% - 48px), transparent 100%);
|
||||
}
|
||||
|
||||
.edit-btn {
|
||||
flex-shrink: 0;
|
||||
background: none;
|
||||
border: 1px solid #3d3d3d;
|
||||
color: #888;
|
||||
cursor: pointer;
|
||||
font-size: 11px;
|
||||
padding: 2px 8px;
|
||||
border-radius: 3px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.edit-btn:hover {
|
||||
border-color: #089981;
|
||||
color: #089981;
|
||||
}
|
||||
</style>
|
||||
@@ -32,19 +32,10 @@ let symbolWatcher: WatchStopHandle | null = null
|
||||
|
||||
const maybeInitChart = () => {
|
||||
if (chartInitialized || !chartContainer.value) return
|
||||
if (!chartStore.symbol) {
|
||||
// Defer until backend provides a symbol
|
||||
if (!symbolWatcher) {
|
||||
symbolWatcher = watch(() => chartStore.symbol, (sym) => {
|
||||
if (sym) {
|
||||
symbolWatcher?.()
|
||||
symbolWatcher = null
|
||||
maybeInitChart()
|
||||
}
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
// If the workspace persisted null values (bad state), reset to defaults immediately
|
||||
// rather than deferring forever. This also syncs the reset back to the container.
|
||||
if (!chartStore.symbol) chartStore.symbol = 'BTC/USDT.BINANCE'
|
||||
if (!chartStore.period) chartStore.period = 900
|
||||
chartInitialized = true
|
||||
initChart()
|
||||
}
|
||||
@@ -73,7 +64,7 @@ function initChart() {
|
||||
tvWidget = new window.TradingView.widget({
|
||||
symbol: chartStore.symbol, // Use symbol from store
|
||||
datafeed: datafeed,
|
||||
interval: secondsToInterval(chartStore.period) as any,
|
||||
interval: secondsToInterval(chartStore.period || 900) as any,
|
||||
container: chartContainer.value!,
|
||||
library_path: '/charting_library/',
|
||||
locale: 'en',
|
||||
|
||||
@@ -5,6 +5,7 @@ import Badge from 'primevue/badge'
|
||||
import { wsManager } from '../composables/useWebSocket'
|
||||
import type { WebSocketMessage } from '../composables/useWebSocket'
|
||||
import { useChannelStore } from '../stores/channel'
|
||||
import ToolCallWithSubagents from './ToolCallWithSubagents.vue'
|
||||
|
||||
register()
|
||||
|
||||
@@ -57,6 +58,7 @@ const rooms = computed(() => [{
|
||||
let currentStreamingMessageId: string | null = null
|
||||
let toolCallMessageId: string | null = null
|
||||
let lastSentMessageId: string | null = null
|
||||
let subagentContentMap = new Map<string, number>() // agentName → index in subagentBlocks
|
||||
let streamingBuffer = ''
|
||||
const isAgentProcessing = ref(false)
|
||||
const isStopHovered = ref(false)
|
||||
@@ -64,6 +66,7 @@ const isStopPressed = ref(false)
|
||||
|
||||
const addToolCallBubble = (label: string) => {
|
||||
removeToolCallBubble()
|
||||
subagentContentMap = new Map()
|
||||
toolCallMessageId = `tool-call-${Date.now()}`
|
||||
const timestamp = new Date().toTimeString().split(' ')[0].slice(0, 5)
|
||||
messages.value = [...messages.value, {
|
||||
@@ -76,7 +79,9 @@ const addToolCallBubble = (label: string) => {
|
||||
distributed: false,
|
||||
seen: false,
|
||||
files: [],
|
||||
toolCall: true
|
||||
toolCall: true,
|
||||
subagentBlocks: [],
|
||||
collapsed: false
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -92,10 +97,49 @@ const appendToolCallStatus = (status: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
const removeToolCallBubble = () => {
|
||||
if (toolCallMessageId) {
|
||||
messages.value = messages.value.filter(m => m._id !== toolCallMessageId)
|
||||
toolCallMessageId = null
|
||||
const removeToolCallBubble = (force = false) => {
|
||||
if (!toolCallMessageId) return
|
||||
if (!force) {
|
||||
const idx = messages.value.findIndex(m => m._id === toolCallMessageId)
|
||||
if (idx !== -1 && messages.value[idx].subagentBlocks?.length) {
|
||||
// Has subagent content — fold and keep for the user to re-expand
|
||||
messages.value[idx] = {
|
||||
...messages.value[idx],
|
||||
collapsed: true,
|
||||
subagentBlocks: messages.value[idx].subagentBlocks.map((b: any) => ({ ...b, isActive: false }))
|
||||
}
|
||||
messages.value = [...messages.value]
|
||||
toolCallMessageId = null
|
||||
subagentContentMap = new Map()
|
||||
return
|
||||
}
|
||||
}
|
||||
messages.value = messages.value.filter(m => m._id !== toolCallMessageId)
|
||||
toolCallMessageId = null
|
||||
subagentContentMap = new Map()
|
||||
}
|
||||
|
||||
const appendSubagentChunk = (agentName: string, content: string) => {
|
||||
if (!toolCallMessageId) return
|
||||
const idx = messages.value.findIndex(m => m._id === toolCallMessageId)
|
||||
if (idx === -1) return
|
||||
const blocks = [...(messages.value[idx].subagentBlocks ?? [])]
|
||||
if (subagentContentMap.has(agentName)) {
|
||||
const blockIdx = subagentContentMap.get(agentName)!
|
||||
blocks[blockIdx] = { ...blocks[blockIdx], content: blocks[blockIdx].content + content }
|
||||
} else {
|
||||
subagentContentMap.set(agentName, blocks.length)
|
||||
blocks.push({ agentName, content, isActive: true })
|
||||
}
|
||||
messages.value[idx] = { ...messages.value[idx], subagentBlocks: blocks }
|
||||
messages.value = [...messages.value]
|
||||
}
|
||||
|
||||
const toggleCollapsed = (messageId: string) => {
|
||||
const idx = messages.value.findIndex(m => m._id === messageId)
|
||||
if (idx !== -1) {
|
||||
messages.value[idx] = { ...messages.value[idx], collapsed: !messages.value[idx].collapsed }
|
||||
messages.value = [...messages.value]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +190,7 @@ const handleMessage = (data: WebSocketMessage) => {
|
||||
}
|
||||
|
||||
if (data.type === 'subagent_chunk') {
|
||||
// Subagent final text — not shown separately; the main agent will incorporate it in its response
|
||||
appendSubagentChunk(data.agentName, data.content)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -189,13 +233,12 @@ const handleMessage = (data: WebSocketMessage) => {
|
||||
}
|
||||
} else if (data.type === 'agent_chunk') {
|
||||
console.log('[ChatPanel] Processing agent_chunk, content:', data.content, 'done:', data.done)
|
||||
// Always remove any tool-call bubble when the agent sends text, whether this
|
||||
// is a new message or a continuation of an existing one (e.g. after a retry).
|
||||
removeToolCallBubble()
|
||||
const timestamp = new Date().toTimeString().split(' ')[0].slice(0, 5)
|
||||
|
||||
if (!currentStreamingMessageId) {
|
||||
console.log('[ChatPanel] Starting new streaming message')
|
||||
// Fold tool call bubble (keeps it if it has subagent content, removes if empty)
|
||||
removeToolCallBubble()
|
||||
// Set up streaming state and mark user message as seen
|
||||
isAgentProcessing.value = true
|
||||
currentStreamingMessageId = generateMessageId()
|
||||
@@ -310,7 +353,7 @@ const handleMessage = (data: WebSocketMessage) => {
|
||||
const stopAgent = () => {
|
||||
wsManager.send({ type: 'agent_stop', session_id: SESSION_ID })
|
||||
isAgentProcessing.value = false
|
||||
removeToolCallBubble()
|
||||
removeToolCallBubble(true)
|
||||
lastSentMessageId = null
|
||||
}
|
||||
|
||||
@@ -651,6 +694,14 @@ onUnmounted(() => {
|
||||
@fetch-messages="fetchMessages"
|
||||
@open-file="openFile"
|
||||
>
|
||||
<div
|
||||
v-for="msg in messages.filter((m: any) => m.toolCall && m.subagentBlocks?.length)"
|
||||
:key="'slot-' + msg._id"
|
||||
:slot="'message_' + msg._id"
|
||||
>
|
||||
<ToolCallWithSubagents :message="msg" @toggle="toggleCollapsed(msg._id)" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="isAgentProcessing"
|
||||
slot="send-icon"
|
||||
|
||||
294
web/src/components/DetailsEditDialog.vue
Normal file
294
web/src/components/DetailsEditDialog.vue
Normal file
@@ -0,0 +1,294 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, computed, onUnmounted } from 'vue'
|
||||
import Dialog from 'primevue/dialog'
|
||||
import Button from 'primevue/button'
|
||||
import { useEditor, EditorContent } from '@tiptap/vue-3'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import { Markdown } from 'tiptap-markdown'
|
||||
import { wsManager, type WebSocketMessage } from '../composables/useWebSocket'
|
||||
|
||||
const props = defineProps<{
|
||||
visible: boolean
|
||||
category: 'indicator' | 'strategy' | 'research'
|
||||
name: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:visible': [value: boolean]
|
||||
'updated': [payload: { category: string; name: string; success: boolean; error?: string }]
|
||||
}>()
|
||||
|
||||
type LoadState = 'idle' | 'loading' | 'ready' | 'error'
|
||||
|
||||
const loadState = ref<LoadState>('idle')
|
||||
const loadError = ref('')
|
||||
const saving = ref(false)
|
||||
const showConfirmCancel = ref(false)
|
||||
|
||||
const editor = useEditor({
|
||||
extensions: [
|
||||
StarterKit,
|
||||
Markdown.configure({ html: false, transformPastedText: true }),
|
||||
],
|
||||
content: '',
|
||||
})
|
||||
|
||||
const originalContent = ref('')
|
||||
|
||||
const isDirty = computed(() => {
|
||||
if (!editor.value || loadState.value !== 'ready') return false
|
||||
return (editor.value.storage as any).markdown.getMarkdown() !== originalContent.value
|
||||
})
|
||||
|
||||
watch(() => props.visible, (v) => {
|
||||
if (v) {
|
||||
loadState.value = 'loading'
|
||||
loadError.value = ''
|
||||
saving.value = false
|
||||
showConfirmCancel.value = false
|
||||
wsManager.send({ type: 'read_details', category: props.category, name: props.name })
|
||||
} else {
|
||||
loadState.value = 'idle'
|
||||
originalContent.value = ''
|
||||
editor.value?.commands.setContent('')
|
||||
}
|
||||
})
|
||||
|
||||
const messageHandler = (msg: WebSocketMessage) => {
|
||||
if (msg.category !== props.category || msg.name !== props.name) return
|
||||
|
||||
if (msg.type === 'details_data') {
|
||||
originalContent.value = msg.details ?? ''
|
||||
editor.value?.commands.setContent(msg.details ?? '')
|
||||
loadState.value = 'ready'
|
||||
} else if (msg.type === 'details_error') {
|
||||
loadError.value = msg.error ?? 'Failed to load details'
|
||||
loadState.value = 'error'
|
||||
} else if (msg.type === 'details_updated') {
|
||||
saving.value = false
|
||||
emit('updated', {
|
||||
category: props.category,
|
||||
name: props.name,
|
||||
success: msg.success,
|
||||
error: msg.error,
|
||||
})
|
||||
if (msg.success) {
|
||||
close()
|
||||
} else {
|
||||
loadError.value = msg.error ?? 'Update failed'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wsManager.addHandler(messageHandler)
|
||||
onUnmounted(() => wsManager.removeHandler(messageHandler))
|
||||
|
||||
function save() {
|
||||
if (!editor.value || saving.value) return
|
||||
saving.value = true
|
||||
loadError.value = ''
|
||||
wsManager.send({
|
||||
type: 'update_details',
|
||||
category: props.category,
|
||||
name: props.name,
|
||||
details: (editor.value.storage as any).markdown.getMarkdown(),
|
||||
})
|
||||
}
|
||||
|
||||
function requestClose() {
|
||||
if (isDirty.value) {
|
||||
showConfirmCancel.value = true
|
||||
} else {
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
function close() {
|
||||
showConfirmCancel.value = false
|
||||
emit('update:visible', false)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog
|
||||
:visible="visible"
|
||||
:header="`Edit Details — ${name}`"
|
||||
:modal="true"
|
||||
:closable="true"
|
||||
:style="{ width: '720px', maxWidth: '95vw' }"
|
||||
class="details-dialog"
|
||||
@update:visible="requestClose"
|
||||
>
|
||||
<div class="dialog-body">
|
||||
<div v-if="loadState === 'loading'" class="state-msg">
|
||||
<i class="pi pi-spin pi-spinner" /> Loading details…
|
||||
</div>
|
||||
<div v-else-if="loadState === 'error'" class="state-msg error">
|
||||
<i class="pi pi-exclamation-triangle" /> {{ loadError }}
|
||||
</div>
|
||||
<template v-else>
|
||||
<div v-if="loadError" class="save-error">
|
||||
<i class="pi pi-exclamation-triangle" /> {{ loadError }}
|
||||
</div>
|
||||
<div class="editor-wrap">
|
||||
<EditorContent :editor="editor" class="tiptap-editor" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Confirm-cancel overlay -->
|
||||
<div v-if="showConfirmCancel" class="confirm-overlay">
|
||||
<div class="confirm-box">
|
||||
<p>Discard unsaved changes?</p>
|
||||
<div class="confirm-actions">
|
||||
<Button label="Keep editing" size="small" outlined @click="showConfirmCancel = false" />
|
||||
<Button label="Discard" size="small" severity="danger" @click="close" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<Button label="Cancel" size="small" outlined :disabled="saving" @click="requestClose" />
|
||||
<Button
|
||||
label="Save"
|
||||
size="small"
|
||||
:loading="saving"
|
||||
:disabled="loadState !== 'ready'"
|
||||
@click="save"
|
||||
/>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.dialog-body {
|
||||
min-height: 300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.state-msg {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
color: #8a8a8a;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.state-msg.error {
|
||||
color: #e06c6c;
|
||||
}
|
||||
|
||||
.save-error {
|
||||
color: #e06c6c;
|
||||
font-size: 12px;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.editor-wrap {
|
||||
flex: 1;
|
||||
border: 1px solid #2e2e2e;
|
||||
border-radius: 4px;
|
||||
overflow: auto;
|
||||
background: #0d0d0d;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.confirm-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.confirm-box {
|
||||
background: #1a1a1a;
|
||||
border: 1px solid #3d3d3d;
|
||||
border-radius: 6px;
|
||||
padding: 20px 24px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.confirm-box p {
|
||||
color: #dbdbdb;
|
||||
font-size: 13px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.confirm-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
/* Global (unscoped) so TipTap's .ProseMirror gets styled */
|
||||
.details-dialog .tiptap-editor .ProseMirror {
|
||||
padding: 12px 14px;
|
||||
outline: none;
|
||||
min-height: 280px;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: #dbdbdb;
|
||||
font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace;
|
||||
}
|
||||
|
||||
.details-dialog .tiptap-editor .ProseMirror h1,
|
||||
.details-dialog .tiptap-editor .ProseMirror h2,
|
||||
.details-dialog .tiptap-editor .ProseMirror h3 {
|
||||
color: #dbdbdb;
|
||||
margin: 0.8em 0 0.4em;
|
||||
}
|
||||
|
||||
.details-dialog .tiptap-editor .ProseMirror p { margin: 0 0 0.6em; }
|
||||
|
||||
.details-dialog .tiptap-editor .ProseMirror code {
|
||||
background: #1a1a1a;
|
||||
border-radius: 3px;
|
||||
padding: 1px 5px;
|
||||
font-size: 0.9em;
|
||||
color: #89d4e0;
|
||||
}
|
||||
|
||||
.details-dialog .tiptap-editor .ProseMirror pre {
|
||||
background: #141414;
|
||||
border: 1px solid #2e2e2e;
|
||||
border-radius: 4px;
|
||||
padding: 10px 14px;
|
||||
overflow-x: auto;
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.details-dialog .tiptap-editor .ProseMirror pre code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
color: #dbdbdb;
|
||||
}
|
||||
|
||||
.details-dialog .tiptap-editor .ProseMirror ul,
|
||||
.details-dialog .tiptap-editor .ProseMirror ol {
|
||||
padding-left: 1.4em;
|
||||
margin: 0.4em 0;
|
||||
}
|
||||
|
||||
.details-dialog .tiptap-editor .ProseMirror blockquote {
|
||||
border-left: 3px solid #3d3d3d;
|
||||
margin: 0.6em 0;
|
||||
padding-left: 12px;
|
||||
color: #8a8a8a;
|
||||
}
|
||||
</style>
|
||||
152
web/src/components/ToolCallWithSubagents.vue
Normal file
152
web/src/components/ToolCallWithSubagents.vue
Normal file
@@ -0,0 +1,152 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
interface SubagentBlock {
|
||||
agentName: string
|
||||
content: string
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
message: {
|
||||
_id: string
|
||||
content: string
|
||||
subagentBlocks: SubagentBlock[]
|
||||
collapsed: boolean
|
||||
}
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{ toggle: [messageId: string] }>()
|
||||
|
||||
const agentIcons: Record<string, string> = {
|
||||
research: '🔬',
|
||||
indicator: '📊',
|
||||
strategy: '📈',
|
||||
}
|
||||
|
||||
const headerLabel = computed(() => {
|
||||
const firstLine = props.message.content.split('\n')[0]
|
||||
return firstLine.replace(/^⚙\s*/, '') || 'Processing...'
|
||||
})
|
||||
|
||||
const isActive = computed(() => props.message.subagentBlocks.some(b => b.isActive))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="tc-bubble">
|
||||
<div class="tc-header" @click="emit('toggle', message._id)">
|
||||
<span class="tc-icon">⚙</span>
|
||||
<span class="tc-label">{{ headerLabel }}</span>
|
||||
<div v-if="isActive" class="tc-spinner"></div>
|
||||
<span v-else class="tc-done">✓</span>
|
||||
<span class="tc-chevron">{{ message.collapsed ? '▼' : '▲' }}</span>
|
||||
</div>
|
||||
<div class="tc-body" :class="{ 'tc-body--collapsed': message.collapsed }">
|
||||
<div v-for="block in message.subagentBlocks" :key="block.agentName" class="tc-agent-block">
|
||||
<div class="tc-agent-name">
|
||||
{{ agentIcons[block.agentName] ?? '🤖' }} {{ block.agentName }}
|
||||
</div>
|
||||
<div class="tc-agent-content">{{ block.content }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.tc-bubble {
|
||||
background: #141414;
|
||||
color: #dbdbdb;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #2e2e2e;
|
||||
font-size: 13px;
|
||||
min-width: 200px;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tc-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 7px 10px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tc-header:hover {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.tc-icon {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.tc-label {
|
||||
flex: 1;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.tc-spinner {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border: 2px solid rgba(8, 153, 129, 0.3);
|
||||
border-top-color: #089981;
|
||||
border-radius: 50%;
|
||||
animation: tc-spin 0.7s linear infinite;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@keyframes tc-spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.tc-done {
|
||||
color: #089981;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.tc-chevron {
|
||||
font-size: 10px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.tc-body {
|
||||
overflow: hidden;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
border-top: 1px solid #2e2e2e;
|
||||
transition: max-height 0.25s ease;
|
||||
}
|
||||
|
||||
.tc-body--collapsed {
|
||||
max-height: 0 !important;
|
||||
border-top-color: transparent;
|
||||
}
|
||||
|
||||
.tc-agent-block {
|
||||
padding: 6px 10px 8px;
|
||||
}
|
||||
|
||||
.tc-agent-block + .tc-agent-block {
|
||||
border-top: 1px solid rgba(46, 46, 46, 0.5);
|
||||
}
|
||||
|
||||
.tc-agent-name {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #8a8a8a;
|
||||
margin-bottom: 4px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.tc-agent-content {
|
||||
font-size: 12px;
|
||||
font-family: monospace;
|
||||
color: #b8b8b8;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
line-height: 1.5;
|
||||
}
|
||||
</style>
|
||||
17
web/src/components/tabs/IndicatorsTab.vue
Normal file
17
web/src/components/tabs/IndicatorsTab.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useIndicatorTypesStore } from '../../stores/indicatorTypes'
|
||||
import CategoryItemList from '../CategoryItemList.vue'
|
||||
|
||||
const store = useIndicatorTypesStore()
|
||||
const { types } = storeToRefs(store)
|
||||
|
||||
const rows = computed(() =>
|
||||
Object.entries(types.value).map(([id, t]) => ({ id, display_name: t.display_name, description: t.description }))
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CategoryItemList category="indicator" :rows="rows" />
|
||||
</template>
|
||||
@@ -1,108 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useResearchTypesStore } from '../../stores/researchTypes'
|
||||
import CategoryItemList from '../CategoryItemList.vue'
|
||||
|
||||
const store = useResearchTypesStore()
|
||||
const { types } = storeToRefs(store)
|
||||
|
||||
const expanded = ref<Set<string>>(new Set())
|
||||
|
||||
const rows = computed(() =>
|
||||
Object.entries(types.value).map(([id, t]) => ({ id, ...t }))
|
||||
Object.entries(types.value).map(([id, t]) => ({ id, display_name: t.display_name, description: t.description }))
|
||||
)
|
||||
|
||||
function toggle(id: string) {
|
||||
if (expanded.value.has(id)) {
|
||||
expanded.value.delete(id)
|
||||
} else {
|
||||
expanded.value.add(id)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="research-tab">
|
||||
<div v-if="rows.length === 0" class="empty">No research items</div>
|
||||
<div v-for="row in rows" :key="row.id" class="research-row">
|
||||
<button class="row-header" @click="toggle(row.id)">
|
||||
<i class="pi" :class="expanded.has(row.id) ? 'pi-chevron-down' : 'pi-chevron-right'" />
|
||||
<span class="row-name">{{ row.display_name }}</span>
|
||||
<span class="row-id">{{ row.id }}</span>
|
||||
</button>
|
||||
<div v-if="expanded.has(row.id)" class="row-body">
|
||||
<span v-if="row.description">{{ row.description }}</span>
|
||||
<span v-else class="no-desc">No description</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<CategoryItemList category="research" :rows="rows" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.research-tab {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.empty {
|
||||
color: #555;
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.research-row {
|
||||
border-bottom: 1px solid #1e1e1e;
|
||||
}
|
||||
|
||||
.row-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
color: #dbdbdb;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.row-header:hover {
|
||||
background: #1a1a1a;
|
||||
}
|
||||
|
||||
.row-header .pi {
|
||||
color: #666;
|
||||
font-size: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.row-name {
|
||||
flex: 1;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.row-id {
|
||||
color: #555;
|
||||
font-size: 11px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.row-body {
|
||||
padding: 6px 26px 8px;
|
||||
font-size: 12px;
|
||||
color: #aaa;
|
||||
line-height: 1.5;
|
||||
background: #0d0d0d;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.no-desc {
|
||||
color: #444;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
|
||||
17
web/src/components/tabs/StrategiesTab.vue
Normal file
17
web/src/components/tabs/StrategiesTab.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useStrategyTypesStore } from '../../stores/strategyTypes'
|
||||
import CategoryItemList from '../CategoryItemList.vue'
|
||||
|
||||
const store = useStrategyTypesStore()
|
||||
const { types } = storeToRefs(store)
|
||||
|
||||
const rows = computed(() =>
|
||||
Object.entries(types.value).map(([id, t]) => ({ id, display_name: t.display_name, description: t.description }))
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CategoryItemList category="strategy" :rows="rows" />
|
||||
</template>
|
||||
@@ -159,6 +159,10 @@ const fetchedRanges = new Map<string, { fromTime: number; toTime: number }>()
|
||||
// constructor can query the current visible range.
|
||||
let _tvWidget: any = null
|
||||
|
||||
// Set of pandas_ta_names that were registered as named TV studies at widget init.
|
||||
// Types that arrive after init are NOT in TV's registry, so must use the generic fallback.
|
||||
const _registeredStudyNames = new Set<string>()
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Generic study design constants
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -443,7 +447,16 @@ export function getCustomIndicatorsGetter(
|
||||
const typeKeys = Object.keys(types)
|
||||
console.log('[CustomIndicators] custom_indicators_getter called, types in store:', typeKeys)
|
||||
|
||||
const namedStudies = Object.values(types).map(makeNamedStudy)
|
||||
_registeredStudyNames.clear()
|
||||
const namedStudies = Object.values(types).flatMap(type => {
|
||||
try {
|
||||
_registeredStudyNames.add(type.pandas_ta_name)
|
||||
return [makeNamedStudy(type)]
|
||||
} catch (err) {
|
||||
console.error('[CustomIndicators] Skipping malformed indicator type:', type?.pandas_ta_name, err)
|
||||
return []
|
||||
}
|
||||
})
|
||||
const testStudy = makeTestStudy(PineJS)
|
||||
const studies = [
|
||||
makeGenericStudy('dxo_customstudy_overlay', true),
|
||||
@@ -526,11 +539,12 @@ export function useCustomIndicators(tvWidget: any) {
|
||||
// Resolve the study type name to use when creating a new TV study
|
||||
// ------------------------------------------------------------------
|
||||
function resolveStudyTypeName(pandasTaName: string, pane: string): string {
|
||||
// TV's createStudy() matches by the `description` field in metainfo, not the internal `name`.
|
||||
// Named studies have description = display_name (e.g. "TrendFlex"), not "dxo_ind_*".
|
||||
const typeEntry = indicatorTypesStore.types[pandasTaName]
|
||||
if (typeEntry) return typeEntry.metadata.display_name
|
||||
// Generic fallbacks have name === description, so either works.
|
||||
// Only use the named study if it was registered in TV at widget init time.
|
||||
// Types that arrived after init are not in TV's registry — fall back to generic.
|
||||
if (_registeredStudyNames.has(pandasTaName)) {
|
||||
const typeEntry = indicatorTypesStore.types[pandasTaName]
|
||||
if (typeEntry) return typeEntry.metadata.display_name
|
||||
}
|
||||
return pane === 'price' ? 'dxo_customstudy_overlay' : 'dxo_customstudy_pane'
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ class WebSocketManager {
|
||||
private maxReconnectAttempts = Infinity // Keep trying indefinitely
|
||||
private reconnectDelay = 1000 // Start with 1 second
|
||||
private maxReconnectDelay = 50000 // Max 50 seconds
|
||||
private consolePatchInstalled = false
|
||||
private forwardingLog = false // prevent re-entrancy
|
||||
|
||||
/**
|
||||
* Connect to WebSocket with JWT token for authentication
|
||||
@@ -101,6 +103,7 @@ class WebSocketManager {
|
||||
this.isAuthenticated.value = true
|
||||
this.sessionStatus.value = 'ready'
|
||||
this.statusMessage.value = ''
|
||||
this.installConsoleForwarding(message.sessionId)
|
||||
// Flush any queued messages now that we're authenticated
|
||||
this.flushMessageQueue()
|
||||
} else if (message.type === 'error') {
|
||||
@@ -210,6 +213,29 @@ class WebSocketManager {
|
||||
}
|
||||
}
|
||||
|
||||
private installConsoleForwarding(sessionId: string) {
|
||||
if (this.consolePatchInstalled) return
|
||||
this.consolePatchInstalled = true
|
||||
|
||||
const levels = ['log', 'info', 'warn', 'error', 'debug'] as const
|
||||
for (const level of levels) {
|
||||
const original = (console[level] as (...args: any[]) => void).bind(console)
|
||||
console[level] = (...args: any[]) => {
|
||||
original(...args)
|
||||
if (!this.forwardingLog && this.ws?.readyState === WebSocket.OPEN) {
|
||||
this.forwardingLog = true
|
||||
try {
|
||||
const message = args.map(a =>
|
||||
typeof a === 'string' ? a : (() => { try { return JSON.stringify(a) } catch { return String(a) } })()
|
||||
).join(' ')
|
||||
this.ws!.send(JSON.stringify({ type: 'client_log', level, message }))
|
||||
} catch { /* ignore send errors */ }
|
||||
this.forwardingLog = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this.reconnectTimeout) {
|
||||
clearTimeout(this.reconnectTimeout)
|
||||
|
||||
Reference in New Issue
Block a user