@leeoohoo/ui-apps-devkit 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +75 -60
  2. package/bin/chatos-uiapp.js +4 -4
  3. package/package.json +26 -20
  4. package/src/cli.js +53 -53
  5. package/src/commands/dev.js +14 -14
  6. package/src/commands/init.js +131 -129
  7. package/src/commands/install.js +47 -46
  8. package/src/commands/pack.js +72 -72
  9. package/src/commands/validate.js +138 -80
  10. package/src/lib/args.js +49 -49
  11. package/src/lib/config.js +29 -29
  12. package/src/lib/fs.js +78 -78
  13. package/src/lib/path-boundary.js +16 -16
  14. package/src/lib/plugin.js +45 -45
  15. package/src/lib/state-constants.js +2 -0
  16. package/src/lib/template.js +172 -168
  17. package/src/sandbox/server.js +1957 -692
  18. package/templates/basic/README.md +78 -54
  19. package/templates/basic/chatos.config.json +5 -5
  20. package/templates/basic/docs/CHATOS_UI_APPS_AI_CONTRIBUTIONS.md +214 -181
  21. package/templates/basic/docs/CHATOS_UI_APPS_BACKEND_PROTOCOL.md +75 -74
  22. package/templates/basic/docs/CHATOS_UI_APPS_HOST_API.md +136 -123
  23. package/templates/basic/docs/CHATOS_UI_APPS_OVERVIEW.md +112 -107
  24. package/templates/basic/docs/CHATOS_UI_APPS_PLUGIN_MANIFEST.md +242 -227
  25. package/templates/basic/docs/CHATOS_UI_APPS_STYLE_GUIDE.md +95 -0
  26. package/templates/basic/docs/CHATOS_UI_APPS_TROUBLESHOOTING.md +45 -0
  27. package/templates/basic/docs/CHATOS_UI_PROMPTS_PROTOCOL.md +392 -392
  28. package/templates/basic/plugin/apps/app/compact.mjs +41 -0
  29. package/templates/basic/plugin/apps/app/index.mjs +287 -263
  30. package/templates/basic/plugin/apps/app/mcp-prompt.en.md +7 -7
  31. package/templates/basic/plugin/apps/app/mcp-prompt.zh.md +7 -7
  32. package/templates/basic/plugin/apps/app/mcp-server.mjs +15 -15
  33. package/templates/basic/plugin/backend/index.mjs +37 -37
  34. package/templates/basic/template.json +7 -7
  35. package/templates/notepad/README.md +55 -24
  36. package/templates/notepad/chatos.config.json +4 -4
  37. package/templates/notepad/docs/CHATOS_UI_APPS_AI_CONTRIBUTIONS.md +214 -181
  38. package/templates/notepad/docs/CHATOS_UI_APPS_BACKEND_PROTOCOL.md +75 -74
  39. package/templates/notepad/docs/CHATOS_UI_APPS_HOST_API.md +136 -123
  40. package/templates/notepad/docs/CHATOS_UI_APPS_OVERVIEW.md +112 -107
  41. package/templates/notepad/docs/CHATOS_UI_APPS_PLUGIN_MANIFEST.md +242 -227
  42. package/templates/notepad/docs/CHATOS_UI_APPS_STYLE_GUIDE.md +95 -0
  43. package/templates/notepad/docs/CHATOS_UI_APPS_TROUBLESHOOTING.md +45 -0
  44. package/templates/notepad/docs/CHATOS_UI_PROMPTS_PROTOCOL.md +392 -392
  45. package/templates/notepad/plugin/apps/app/api.mjs +30 -30
  46. package/templates/notepad/plugin/apps/app/compact.mjs +41 -0
  47. package/templates/notepad/plugin/apps/app/dom.mjs +14 -14
  48. package/templates/notepad/plugin/apps/app/ds-tree.mjs +35 -35
  49. package/templates/notepad/plugin/apps/app/index.mjs +1056 -1056
  50. package/templates/notepad/plugin/apps/app/layers.mjs +338 -338
  51. package/templates/notepad/plugin/apps/app/markdown.mjs +120 -120
  52. package/templates/notepad/plugin/apps/app/mcp-prompt.en.md +22 -22
  53. package/templates/notepad/plugin/apps/app/mcp-prompt.zh.md +22 -22
  54. package/templates/notepad/plugin/apps/app/mcp-server.mjs +206 -199
  55. package/templates/notepad/plugin/apps/app/styles.mjs +355 -355
  56. package/templates/notepad/plugin/apps/app/tags.mjs +21 -21
  57. package/templates/notepad/plugin/apps/app/ui.mjs +280 -280
  58. package/templates/notepad/plugin/backend/index.mjs +99 -99
  59. package/templates/notepad/plugin/plugin.json +23 -23
  60. package/templates/notepad/plugin/shared/notepad-paths.mjs +59 -41
  61. package/templates/notepad/plugin/shared/notepad-store.mjs +765 -765
  62. package/templates/notepad/template.json +8 -8
@@ -1,120 +1,120 @@
1
- function escapeHtml(input) {
2
- return String(input ?? '')
3
- .replace(/&/g, '&')
4
- .replace(/</g, '&lt;')
5
- .replace(/>/g, '&gt;')
6
- .replace(/"/g, '&quot;')
7
- .replace(/'/g, '&#39;');
8
- }
9
-
10
- function renderInlineMd(text) {
11
- let out = escapeHtml(text);
12
- out = out.replace(/`([^`]+?)`/g, '<code>$1</code>');
13
- out = out.replace(/\*\*([^*]+?)\*\*/g, '<strong>$1</strong>');
14
- out = out.replace(/\*([^*]+?)\*/g, '<em>$1</em>');
15
- out = out.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img alt="$1" src="$2" />');
16
- out = out.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noreferrer">$1</a>');
17
- return out;
18
- }
19
-
20
- export function renderMarkdown(md) {
21
- const text = String(md || '').replace(/\r\n/g, '\n');
22
- const lines = text.split('\n');
23
- let html = '';
24
- let inCode = false;
25
- let listMode = '';
26
- let paragraph = [];
27
-
28
- const flushParagraph = () => {
29
- if (paragraph.length === 0) return;
30
- const content = paragraph.map((l) => renderInlineMd(l)).join('<br />');
31
- html += `<p>${content}</p>`;
32
- paragraph = [];
33
- };
34
-
35
- const closeList = () => {
36
- if (!listMode) return;
37
- html += listMode === 'ol' ? '</ol>' : '</ul>';
38
- listMode = '';
39
- };
40
-
41
- for (const rawLine of lines) {
42
- const line = String(rawLine ?? '');
43
- const trimmed = line.trimEnd();
44
-
45
- const fence = trimmed.trim().match(/^```(\S+)?\s*$/);
46
- if (fence) {
47
- flushParagraph();
48
- closeList();
49
- if (!inCode) {
50
- inCode = true;
51
- const lang = escapeHtml(fence[1] || '');
52
- html += `<pre><code data-lang="${lang}">`;
53
- } else {
54
- inCode = false;
55
- html += '</code></pre>';
56
- }
57
- continue;
58
- }
59
-
60
- if (inCode) {
61
- html += `${escapeHtml(line)}\n`;
62
- continue;
63
- }
64
-
65
- if (!trimmed.trim()) {
66
- flushParagraph();
67
- closeList();
68
- continue;
69
- }
70
-
71
- const heading = trimmed.match(/^(#{1,6})\s+(.+)$/);
72
- if (heading) {
73
- flushParagraph();
74
- closeList();
75
- const level = Math.min(6, heading[1].length);
76
- html += `<h${level}>${renderInlineMd(heading[2])}</h${level}>`;
77
- continue;
78
- }
79
-
80
- const quote = trimmed.match(/^>\s?(.*)$/);
81
- if (quote) {
82
- flushParagraph();
83
- closeList();
84
- html += `<blockquote>${renderInlineMd(quote[1] || '')}</blockquote>`;
85
- continue;
86
- }
87
-
88
- const ul = trimmed.match(/^[-*+]\s+(.+)$/);
89
- if (ul) {
90
- flushParagraph();
91
- if (listMode && listMode !== 'ul') closeList();
92
- if (!listMode) {
93
- listMode = 'ul';
94
- html += '<ul>';
95
- }
96
- html += `<li>${renderInlineMd(ul[1])}</li>`;
97
- continue;
98
- }
99
-
100
- const ol = trimmed.match(/^\d+\.\s+(.+)$/);
101
- if (ol) {
102
- flushParagraph();
103
- if (listMode && listMode !== 'ol') closeList();
104
- if (!listMode) {
105
- listMode = 'ol';
106
- html += '<ol>';
107
- }
108
- html += `<li>${renderInlineMd(ol[1])}</li>`;
109
- continue;
110
- }
111
-
112
- paragraph.push(trimmed);
113
- }
114
-
115
- flushParagraph();
116
- closeList();
117
- if (inCode) html += '</code></pre>';
118
- return html;
119
- }
120
-
1
+ function escapeHtml(input) {
2
+ return String(input ?? '')
3
+ .replace(/&/g, '&amp;')
4
+ .replace(/</g, '&lt;')
5
+ .replace(/>/g, '&gt;')
6
+ .replace(/"/g, '&quot;')
7
+ .replace(/'/g, '&#39;');
8
+ }
9
+
10
+ function renderInlineMd(text) {
11
+ let out = escapeHtml(text);
12
+ out = out.replace(/`([^`]+?)`/g, '<code>$1</code>');
13
+ out = out.replace(/\*\*([^*]+?)\*\*/g, '<strong>$1</strong>');
14
+ out = out.replace(/\*([^*]+?)\*/g, '<em>$1</em>');
15
+ out = out.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img alt="$1" src="$2" />');
16
+ out = out.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" rel="noreferrer">$1</a>');
17
+ return out;
18
+ }
19
+
20
+ export function renderMarkdown(md) {
21
+ const text = String(md || '').replace(/\r\n/g, '\n');
22
+ const lines = text.split('\n');
23
+ let html = '';
24
+ let inCode = false;
25
+ let listMode = '';
26
+ let paragraph = [];
27
+
28
+ const flushParagraph = () => {
29
+ if (paragraph.length === 0) return;
30
+ const content = paragraph.map((l) => renderInlineMd(l)).join('<br />');
31
+ html += `<p>${content}</p>`;
32
+ paragraph = [];
33
+ };
34
+
35
+ const closeList = () => {
36
+ if (!listMode) return;
37
+ html += listMode === 'ol' ? '</ol>' : '</ul>';
38
+ listMode = '';
39
+ };
40
+
41
+ for (const rawLine of lines) {
42
+ const line = String(rawLine ?? '');
43
+ const trimmed = line.trimEnd();
44
+
45
+ const fence = trimmed.trim().match(/^```(\S+)?\s*$/);
46
+ if (fence) {
47
+ flushParagraph();
48
+ closeList();
49
+ if (!inCode) {
50
+ inCode = true;
51
+ const lang = escapeHtml(fence[1] || '');
52
+ html += `<pre><code data-lang="${lang}">`;
53
+ } else {
54
+ inCode = false;
55
+ html += '</code></pre>';
56
+ }
57
+ continue;
58
+ }
59
+
60
+ if (inCode) {
61
+ html += `${escapeHtml(line)}\n`;
62
+ continue;
63
+ }
64
+
65
+ if (!trimmed.trim()) {
66
+ flushParagraph();
67
+ closeList();
68
+ continue;
69
+ }
70
+
71
+ const heading = trimmed.match(/^(#{1,6})\s+(.+)$/);
72
+ if (heading) {
73
+ flushParagraph();
74
+ closeList();
75
+ const level = Math.min(6, heading[1].length);
76
+ html += `<h${level}>${renderInlineMd(heading[2])}</h${level}>`;
77
+ continue;
78
+ }
79
+
80
+ const quote = trimmed.match(/^>\s?(.*)$/);
81
+ if (quote) {
82
+ flushParagraph();
83
+ closeList();
84
+ html += `<blockquote>${renderInlineMd(quote[1] || '')}</blockquote>`;
85
+ continue;
86
+ }
87
+
88
+ const ul = trimmed.match(/^[-*+]\s+(.+)$/);
89
+ if (ul) {
90
+ flushParagraph();
91
+ if (listMode && listMode !== 'ul') closeList();
92
+ if (!listMode) {
93
+ listMode = 'ul';
94
+ html += '<ul>';
95
+ }
96
+ html += `<li>${renderInlineMd(ul[1])}</li>`;
97
+ continue;
98
+ }
99
+
100
+ const ol = trimmed.match(/^\d+\.\s+(.+)$/);
101
+ if (ol) {
102
+ flushParagraph();
103
+ if (listMode && listMode !== 'ol') closeList();
104
+ if (!listMode) {
105
+ listMode = 'ol';
106
+ html += '<ol>';
107
+ }
108
+ html += `<li>${renderInlineMd(ol[1])}</li>`;
109
+ continue;
110
+ }
111
+
112
+ paragraph.push(trimmed);
113
+ }
114
+
115
+ flushParagraph();
116
+ closeList();
117
+ if (inCode) html += '</code></pre>';
118
+ return html;
119
+ }
120
+
@@ -1,22 +1,22 @@
1
- # __PLUGIN_NAME__ (Markdown Notes)
2
-
3
- This app exposes MCP tools to manage local Markdown notes (folders + tags):
4
-
5
- - `init`: initialize storage (data dir, index, notes root)
6
- - `list_folders`: list folders (categories)
7
- - `create_folder`: create a folder (supports nested paths)
8
- - `rename_folder`: rename/move a folder
9
- - `delete_folder`: delete a folder (optionally recursive)
10
- - `list_notes`: list notes filtered by folder/tags/title
11
- - `create_note`: create a note (folder/title/content/tags)
12
- - `read_note`: read a note (metadata + markdown content)
13
- - `update_note`: update a note (title/content/tags/move folder)
14
- - `delete_note`: delete a note
15
- - `list_tags`: list tags with counts
16
- - `search_notes`: search by keyword (optional content search + folder/tags filters)
17
-
18
- Guidelines:
19
-
20
- 1) If you don't know the structure, start with `list_folders` + `list_notes`/`list_tags` before making changes.
21
- 2) Ask for confirmation before destructive operations (especially `delete_folder` with `recursive=true`).
22
- 3) For quick lookup by folder + tags, prefer `list_notes` (folder+tags) or `search_notes` with filters, instead of scanning everything.
1
+ # __PLUGIN_NAME__ (Markdown Notes)
2
+
3
+ This app exposes MCP tools to manage local Markdown notes (folders + tags):
4
+
5
+ - `init`: initialize storage (data dir, index, notes root)
6
+ - `list_folders`: list folders (categories)
7
+ - `create_folder`: create a folder (supports nested paths)
8
+ - `rename_folder`: rename/move a folder
9
+ - `delete_folder`: delete a folder (optionally recursive)
10
+ - `list_notes`: list notes filtered by folder/tags/title
11
+ - `create_note`: create a note (folder/title/content/tags)
12
+ - `read_note`: read a note (metadata + markdown content)
13
+ - `update_note`: update a note (title/content/tags/move folder)
14
+ - `delete_note`: delete a note
15
+ - `list_tags`: list tags with counts
16
+ - `search_notes`: search by keyword (optional content search + folder/tags filters)
17
+
18
+ Guidelines:
19
+
20
+ 1) If you don't know the structure, start with `list_folders` + `list_notes`/`list_tags` before making changes.
21
+ 2) Ask for confirmation before destructive operations (especially `delete_folder` with `recursive=true`).
22
+ 3) For quick lookup by folder + tags, prefer `list_notes` (folder+tags) or `search_notes` with filters, instead of scanning everything.
@@ -1,22 +1,22 @@
1
- # __PLUGIN_NAME__(Markdown Notes)
2
-
3
- 本应用向 ChatOS 暴露了一组 MCP tools,用于管理本地 Markdown 笔记(文件夹分类 + 标签检索):
4
-
5
- - `init`:初始化存储(数据目录、索引、notes 根目录)
6
- - `list_folders`:列出文件夹(分类)
7
- - `create_folder`:创建文件夹(支持多级路径)
8
- - `rename_folder`:重命名/移动文件夹
9
- - `delete_folder`:删除文件夹(可递归删除)
10
- - `list_notes`:按文件夹/标签/标题筛选列出笔记
11
- - `create_note`:创建笔记(可指定文件夹、标题、内容、标签)
12
- - `read_note`:读取笔记(返回元数据与 Markdown 内容)
13
- - `update_note`:更新笔记(标题/内容/标签/移动文件夹)
14
- - `delete_note`:删除笔记
15
- - `list_tags`:列出全部标签与使用次数
16
- - `search_notes`:按关键字搜索(可选:搜内容 + 叠加文件夹/标签过滤)
17
-
18
- 使用建议(重要):
19
-
20
- 1) 不确定结构时,先 `list_folders` + `list_notes`/`list_tags` 再做编辑或移动。
21
- 2) 移动或删除(尤其是 `delete_folder` 且 `recursive=true`)前先向用户确认。
22
- 3) 若需要“按标签 + 分类”快速定位,优先用 `list_notes`(folder+tags)或 `search_notes`(叠加过滤),不要盲目遍历全部内容。
1
+ # __PLUGIN_NAME__(Markdown Notes)
2
+
3
+ 本应用向 ChatOS 暴露了一组 MCP tools,用于管理本地 Markdown 笔记(文件夹分类 + 标签检索):
4
+
5
+ - `init`:初始化存储(数据目录、索引、notes 根目录)
6
+ - `list_folders`:列出文件夹(分类)
7
+ - `create_folder`:创建文件夹(支持多级路径)
8
+ - `rename_folder`:重命名/移动文件夹
9
+ - `delete_folder`:删除文件夹(可递归删除)
10
+ - `list_notes`:按文件夹/标签/标题筛选列出笔记
11
+ - `create_note`:创建笔记(可指定文件夹、标题、内容、标签)
12
+ - `read_note`:读取笔记(返回元数据与 Markdown 内容)
13
+ - `update_note`:更新笔记(标题/内容/标签/移动文件夹)
14
+ - `delete_note`:删除笔记
15
+ - `list_tags`:列出全部标签与使用次数
16
+ - `search_notes`:按关键字搜索(可选:搜内容 + 叠加文件夹/标签过滤)
17
+
18
+ 使用建议(重要):
19
+
20
+ 1) 不确定结构时,先 `list_folders` + `list_notes`/`list_tags` 再做编辑或移动。
21
+ 2) 移动或删除(尤其是 `delete_folder` 且 `recursive=true`)前先向用户确认。
22
+ 3) 若需要“按标签 + 分类”快速定位,优先用 `list_notes`(folder+tags)或 `search_notes`(叠加过滤),不要盲目遍历全部内容。