@yosai/cli 0.2.1-test.1 → 0.2.1-test.10

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 (39) hide show
  1. package/README.md +11 -9
  2. package/dist/cli.js +3 -2
  3. package/dist/commands/doctor.js +14 -13
  4. package/dist/commands/login.js +8 -12
  5. package/dist/commands/ping.js +4 -4
  6. package/dist/commands/update.js +52 -19
  7. package/dist/commands/version.js +8 -8
  8. package/dist/config.js +12 -23
  9. package/dist/domain-commands.js +13 -4
  10. package/dist/domain-executor.js +3 -0
  11. package/dist/endpoints.js +13 -8
  12. package/dist/errors.js +6 -0
  13. package/dist/npm-meta.js +88 -11
  14. package/dist/openapis-client.js +27 -8
  15. package/dist/skill-sync.js +2 -2
  16. package/dist/skills/yos/SKILL.md +23 -14
  17. package/dist/skills/yos-doc/SKILL.md +221 -0
  18. package/dist/skills/yos-doc/references/AGENT_SCHEMA.doc.md +69 -0
  19. package/dist/skills/yos-doc/references/DOC_DATA_API.md +624 -0
  20. package/dist/skills/yos-doc/references/doc-draft.template.json +721 -0
  21. package/dist/skills/yos-doc/references/few-shot.draft.json +195 -0
  22. package/dist/skills/yos-doc/scripts/validate-runtime-doc.mjs +370 -0
  23. package/dist/skills/yos-doc/scripts/yos-doc.mjs +157 -0
  24. package/dist/skills/yos-install/SKILL.md +46 -20
  25. package/dist/skills/{yos-kb → yos-knowledge}/SKILL.md +21 -8
  26. package/dist/skills/yos-retrieval/SKILL.md +1 -1
  27. package/dist/skills/yos-shared/SKILL.md +23 -14
  28. package/dist/skills/yos-sheet/SKILL.md +233 -0
  29. package/dist/skills/yos-sheet/references/AGENT_SCHEMA.sheet.md +105 -0
  30. package/dist/skills/yos-sheet/references/SHEET_DATA_API.md +356 -0
  31. package/dist/skills/yos-sheet/references/few-shot.workbook.json +50 -0
  32. package/dist/skills/yos-sheet/references/sheet-workbook.template.json +147 -0
  33. package/dist/skills/yos-sheet/scripts/validate-runtime-sheet.mjs +404 -0
  34. package/dist/skills/yos-sheet/scripts/yos-sheet.mjs +157 -0
  35. package/dist/skills/yos-support/SKILL.md +1 -1
  36. package/dist/skills/yos-transcript/SKILL.md +1 -1
  37. package/dist/update-check-worker.js +35 -0
  38. package/dist/update-notice.js +86 -0
  39. package/package.json +4 -2
@@ -0,0 +1,195 @@
1
+ {
2
+ "title": "示例:Agent few-shot",
3
+ "attachments": [],
4
+ "content": {
5
+ "type": "doc",
6
+ "content": [
7
+ {
8
+ "type": "paragraph",
9
+ "attrs": { "indent": 0, "textAlign": null },
10
+ "content": [
11
+ { "type": "text", "text": "这是一段" },
12
+ { "type": "text", "marks": [{ "type": "bold" }], "text": "加粗" },
13
+ { "type": "text", "text": "与" },
14
+ {
15
+ "type": "text",
16
+ "marks": [
17
+ {
18
+ "type": "link",
19
+ "attrs": {
20
+ "href": "https://example.com",
21
+ "target": "_blank",
22
+ "rel": "noopener noreferrer nofollow",
23
+ "class": "yos-docs-editor-link",
24
+ "title": null
25
+ }
26
+ }
27
+ ],
28
+ "text": "链接"
29
+ },
30
+ { "type": "text", "text": "。" }
31
+ ]
32
+ },
33
+ {
34
+ "type": "callout",
35
+ "attrs": {
36
+ "emoji": "💡",
37
+ "backgroundColor": "#e1eafe",
38
+ "borderColor": "#80a7f9"
39
+ },
40
+ "content": [
41
+ {
42
+ "type": "paragraph",
43
+ "attrs": { "indent": 0, "textAlign": null },
44
+ "content": [{ "type": "text", "text": "高亮提示:优先写清验收标准。" }]
45
+ }
46
+ ]
47
+ },
48
+ {
49
+ "type": "heading",
50
+ "attrs": { "level": 2, "indent": 0, "textAlign": null, "collapsed": false },
51
+ "content": [{ "type": "text", "text": "清单" }]
52
+ },
53
+ {
54
+ "type": "bulletList",
55
+ "content": [
56
+ {
57
+ "type": "listItem",
58
+ "attrs": { "collapsed": false },
59
+ "content": [
60
+ {
61
+ "type": "paragraph",
62
+ "attrs": { "indent": 0, "textAlign": null },
63
+ "content": [{ "type": "text", "text": "第一项" }]
64
+ }
65
+ ]
66
+ },
67
+ {
68
+ "type": "listItem",
69
+ "attrs": { "collapsed": false },
70
+ "content": [
71
+ {
72
+ "type": "paragraph",
73
+ "attrs": { "indent": 0, "textAlign": null },
74
+ "content": [{ "type": "text", "text": "第二项" }]
75
+ }
76
+ ]
77
+ }
78
+ ]
79
+ },
80
+ {
81
+ "type": "taskList",
82
+ "content": [
83
+ {
84
+ "type": "taskItem",
85
+ "attrs": { "checked": false },
86
+ "content": [
87
+ {
88
+ "type": "paragraph",
89
+ "attrs": { "indent": 0, "textAlign": null },
90
+ "content": [{ "type": "text", "text": "待办示例" }]
91
+ }
92
+ ]
93
+ }
94
+ ]
95
+ },
96
+ {
97
+ "type": "codeBlock",
98
+ "attrs": {
99
+ "language": "typescript",
100
+ "wrap": false,
101
+ "caption": "示例",
102
+ "collapsed": false,
103
+ "regionFolds": []
104
+ },
105
+ "content": [{ "type": "text", "text": "export const ok = true;\n" }]
106
+ },
107
+ {
108
+ "type": "table",
109
+ "content": [
110
+ {
111
+ "type": "tableRow",
112
+ "attrs": { "height": null },
113
+ "content": [
114
+ {
115
+ "type": "tableHeader",
116
+ "attrs": {
117
+ "colspan": 1,
118
+ "rowspan": 1,
119
+ "colwidth": null,
120
+ "align": null,
121
+ "backgroundColor": null
122
+ },
123
+ "content": [
124
+ {
125
+ "type": "paragraph",
126
+ "attrs": { "indent": 0, "textAlign": null },
127
+ "content": [{ "type": "text", "text": "列 A" }]
128
+ }
129
+ ]
130
+ },
131
+ {
132
+ "type": "tableHeader",
133
+ "attrs": {
134
+ "colspan": 1,
135
+ "rowspan": 1,
136
+ "colwidth": null,
137
+ "align": null,
138
+ "backgroundColor": null
139
+ },
140
+ "content": [
141
+ {
142
+ "type": "paragraph",
143
+ "attrs": { "indent": 0, "textAlign": null },
144
+ "content": [{ "type": "text", "text": "列 B" }]
145
+ }
146
+ ]
147
+ }
148
+ ]
149
+ },
150
+ {
151
+ "type": "tableRow",
152
+ "attrs": { "height": null },
153
+ "content": [
154
+ {
155
+ "type": "tableCell",
156
+ "attrs": {
157
+ "colspan": 1,
158
+ "rowspan": 1,
159
+ "colwidth": null,
160
+ "align": null,
161
+ "backgroundColor": null
162
+ },
163
+ "content": [
164
+ {
165
+ "type": "paragraph",
166
+ "attrs": { "indent": 0, "textAlign": null },
167
+ "content": [{ "type": "text", "text": "1" }]
168
+ }
169
+ ]
170
+ },
171
+ {
172
+ "type": "tableCell",
173
+ "attrs": {
174
+ "colspan": 1,
175
+ "rowspan": 1,
176
+ "colwidth": null,
177
+ "align": null,
178
+ "backgroundColor": null
179
+ },
180
+ "content": [
181
+ {
182
+ "type": "paragraph",
183
+ "attrs": { "indent": 0, "textAlign": null },
184
+ "content": [{ "type": "text", "text": "2" }]
185
+ }
186
+ ]
187
+ }
188
+ ]
189
+ }
190
+ ]
191
+ },
192
+ { "type": "horizontalRule" }
193
+ ]
194
+ }
195
+ }
@@ -0,0 +1,370 @@
1
+ /**
2
+ * CLI 用纯 ESM 校验(与 src/utils/agent/validateDocDraft.ts 保持同步)。
3
+ * 供 ./yos-doc.mjs 使用(同步自 @yos/doc-editor@0.0.41),避免 Node 直接跑 TS 的扩展名问题。
4
+ */
5
+
6
+ export const AGENT_DOC_ROOT = "doc";
7
+
8
+ export const AGENT_TIER_A_NODES = [
9
+ "doc",
10
+ "paragraph",
11
+ "heading",
12
+ "blockquote",
13
+ "horizontalRule",
14
+ "hardBreak",
15
+ "bulletList",
16
+ "orderedList",
17
+ "listItem",
18
+ "taskList",
19
+ "taskItem",
20
+ "codeBlock",
21
+ "callout",
22
+ "table",
23
+ "tableRow",
24
+ "tableHeader",
25
+ "tableCell",
26
+ "text",
27
+ ];
28
+
29
+ export const AGENT_TIER_B_NODES = ["columnBlock", "column", "image"];
30
+
31
+ export const AGENT_FORBIDDEN_NODES = [
32
+ "mindmap",
33
+ "flowchart",
34
+ "video",
35
+ "audio",
36
+ "file",
37
+ ];
38
+
39
+ export const AGENT_ALLOWED_MARKS = [
40
+ "bold",
41
+ "italic",
42
+ "strike",
43
+ "underline",
44
+ "code",
45
+ "link",
46
+ "textStyle",
47
+ "highlight",
48
+ ];
49
+
50
+ export const AGENT_FORBIDDEN_MARKS = ["glossaryTerm"];
51
+
52
+ export const AGENT_NODE_ATTR_KEYS = {
53
+ paragraph: ["indent", "textAlign"],
54
+ heading: ["level", "indent", "textAlign", "collapsed"],
55
+ orderedList: ["start", "type"],
56
+ listItem: ["collapsed"],
57
+ taskItem: ["checked"],
58
+ codeBlock: ["language", "wrap", "caption", "collapsed", "regionFolds"],
59
+ callout: ["emoji", "backgroundColor", "borderColor"],
60
+ tableRow: ["height"],
61
+ tableHeader: ["colspan", "rowspan", "colwidth", "align", "backgroundColor"],
62
+ tableCell: ["colspan", "rowspan", "colwidth", "align", "backgroundColor"],
63
+ columnBlock: ["widths"],
64
+ image: [
65
+ "src",
66
+ "mediaId",
67
+ "alt",
68
+ "title",
69
+ "width",
70
+ "height",
71
+ "align",
72
+ "caption",
73
+ "originalSrc",
74
+ "uploadStatus",
75
+ "uploadId",
76
+ ],
77
+ };
78
+
79
+ export const AGENT_MARK_ATTR_KEYS = {
80
+ link: ["href", "target", "rel", "class", "title"],
81
+ textStyle: ["color"],
82
+ highlight: ["color"],
83
+ };
84
+
85
+ export function allowedNodesForTier(tier) {
86
+ const nodes = new Set(AGENT_TIER_A_NODES);
87
+ if (tier === "B") {
88
+ for (const name of AGENT_TIER_B_NODES) {
89
+ nodes.add(name);
90
+ }
91
+ }
92
+ return nodes;
93
+ }
94
+
95
+ const ALLOWED_MARKS = new Set(AGENT_ALLOWED_MARKS);
96
+ const FORBIDDEN_MARKS = new Set(AGENT_FORBIDDEN_MARKS);
97
+ const FORBIDDEN_NODES = new Set(AGENT_FORBIDDEN_NODES);
98
+ const TEXT_ALIGN = new Set(["left", "center", "right", "justify"]);
99
+ const IMAGE_ALIGN = new Set(["left", "center", "right"]);
100
+
101
+ function push(issues, path, message) {
102
+ issues.push({ path, message });
103
+ }
104
+
105
+ function isRecord(value) {
106
+ return typeof value === "object" && value !== null && !Array.isArray(value);
107
+ }
108
+
109
+ function isHttpUrl(value) {
110
+ return /^https?:\/\//i.test(value);
111
+ }
112
+
113
+ function validateAttrKeys(issues, path, type, attrs, allowedMap) {
114
+ if (attrs === undefined || attrs === null) {
115
+ return {};
116
+ }
117
+ if (!isRecord(attrs)) {
118
+ push(issues, `${path}.attrs`, "attrs 必须是对象");
119
+ return null;
120
+ }
121
+ const allowed = allowedMap[type];
122
+ if (!allowed) {
123
+ if (Object.keys(attrs).length > 0) {
124
+ push(issues, `${path}.attrs`, `type "${type}" 不应带 attrs`);
125
+ }
126
+ return attrs;
127
+ }
128
+ const allowedSet = new Set(allowed);
129
+ for (const key of Object.keys(attrs)) {
130
+ if (!allowedSet.has(key)) {
131
+ push(issues, `${path}.attrs.${key}`, `未知 attrs 键 "${key}"`);
132
+ }
133
+ }
134
+ return attrs;
135
+ }
136
+
137
+ function validateMarks(issues, path, marks) {
138
+ if (marks === undefined) {
139
+ return;
140
+ }
141
+ if (!Array.isArray(marks)) {
142
+ push(issues, path, "marks 必须是数组");
143
+ return;
144
+ }
145
+ marks.forEach((mark, index) => {
146
+ const markPath = `${path}[${index}]`;
147
+ if (!isRecord(mark) || typeof mark.type !== "string") {
148
+ push(issues, markPath, "mark 须含 string type");
149
+ return;
150
+ }
151
+ if (FORBIDDEN_MARKS.has(mark.type)) {
152
+ push(issues, markPath, `禁止 mark "${mark.type}"(Agent 勿生成)`);
153
+ return;
154
+ }
155
+ if (!ALLOWED_MARKS.has(mark.type)) {
156
+ push(issues, markPath, `未知 mark "${mark.type}"`);
157
+ return;
158
+ }
159
+ validateAttrKeys(
160
+ issues,
161
+ markPath,
162
+ mark.type,
163
+ mark.attrs,
164
+ AGENT_MARK_ATTR_KEYS,
165
+ );
166
+ if (mark.type === "link") {
167
+ const href = isRecord(mark.attrs) ? mark.attrs.href : undefined;
168
+ if (typeof href !== "string" || !href.trim()) {
169
+ push(issues, `${markPath}.attrs.href`, "link 需要非空 href");
170
+ }
171
+ }
172
+ });
173
+ }
174
+
175
+ function validateNodeSemantics(issues, path, type, attrs, content) {
176
+ if (type === "heading") {
177
+ const level = attrs.level;
178
+ if (
179
+ level !== undefined &&
180
+ (typeof level !== "number" || level < 1 || level > 6)
181
+ ) {
182
+ push(issues, `${path}.attrs.level`, "level 须为 1~6");
183
+ }
184
+ }
185
+ if (type === "paragraph" || type === "heading") {
186
+ const align = attrs.textAlign;
187
+ if (
188
+ align !== undefined &&
189
+ align !== null &&
190
+ (typeof align !== "string" || !TEXT_ALIGN.has(align))
191
+ ) {
192
+ push(
193
+ issues,
194
+ `${path}.attrs.textAlign`,
195
+ "textAlign 须为 null 或 left/center/right/justify",
196
+ );
197
+ }
198
+ const indent = attrs.indent;
199
+ if (
200
+ indent !== undefined &&
201
+ (typeof indent !== "number" || indent < 0 || indent > 8)
202
+ ) {
203
+ push(issues, `${path}.attrs.indent`, "indent 须为 0~8");
204
+ }
205
+ }
206
+ if (type === "columnBlock") {
207
+ if (!Array.isArray(content) || content.length < 2 || content.length > 5) {
208
+ push(issues, `${path}.content`, "columnBlock 须含 2~5 个 column");
209
+ }
210
+ const widths = attrs.widths;
211
+ if (widths !== undefined) {
212
+ if (
213
+ !Array.isArray(widths) ||
214
+ !widths.every((w) => typeof w === "number")
215
+ ) {
216
+ push(issues, `${path}.attrs.widths`, "widths 须为 number[]");
217
+ } else if (Array.isArray(content) && widths.length !== content.length) {
218
+ push(issues, `${path}.attrs.widths`, "widths.length 须等于列数");
219
+ }
220
+ }
221
+ }
222
+ if (type === "image") {
223
+ const mediaId = attrs.mediaId;
224
+ if (mediaId !== undefined && mediaId !== "" && mediaId !== null) {
225
+ push(
226
+ issues,
227
+ `${path}.attrs.mediaId`,
228
+ "Agent 勿编造 mediaId,请留空并由宿主 upload",
229
+ );
230
+ }
231
+ if (attrs.uploadStatus != null && attrs.uploadStatus !== "") {
232
+ push(issues, `${path}.attrs.uploadStatus`, "Agent 勿写 uploadStatus");
233
+ }
234
+ if (
235
+ attrs.uploadId !== undefined &&
236
+ attrs.uploadId !== "" &&
237
+ attrs.uploadId !== null
238
+ ) {
239
+ push(issues, `${path}.attrs.uploadId`, "Agent 勿写 uploadId");
240
+ }
241
+ const src = attrs.src;
242
+ if (src != null && src !== "") {
243
+ if (typeof src !== "string" || !isHttpUrl(src)) {
244
+ push(issues, `${path}.attrs.src`, "image.src 仅允许 http(s) URL");
245
+ }
246
+ }
247
+ const align = attrs.align;
248
+ if (
249
+ align !== undefined &&
250
+ (typeof align !== "string" || !IMAGE_ALIGN.has(align))
251
+ ) {
252
+ push(issues, `${path}.attrs.align`, "align 须为 left/center/right");
253
+ }
254
+ }
255
+ }
256
+
257
+ function validateNode(issues, path, node, allowedNodes) {
258
+ if (!isRecord(node)) {
259
+ push(issues, path, "节点必须是对象");
260
+ return;
261
+ }
262
+ const type = node.type;
263
+ if (typeof type !== "string" || !type) {
264
+ push(issues, path, "缺少 type");
265
+ return;
266
+ }
267
+ if (FORBIDDEN_NODES.has(type)) {
268
+ push(issues, path, `禁止节点 "${type}"(属 C 档,勿由 Agent 生成)`);
269
+ return;
270
+ }
271
+ if (!allowedNodes.has(type)) {
272
+ push(
273
+ issues,
274
+ path,
275
+ `节点 "${type}" 不在当前档位白名单(可用 --tier B 放开分栏/外链图)`,
276
+ );
277
+ return;
278
+ }
279
+
280
+ if (type === "text") {
281
+ if (typeof node.text !== "string") {
282
+ push(issues, `${path}.text`, "text 节点须有 string text");
283
+ }
284
+ validateMarks(issues, `${path}.marks`, node.marks);
285
+ if (node.content !== undefined) {
286
+ push(issues, `${path}.content`, "text 节点不应有 content");
287
+ }
288
+ return;
289
+ }
290
+
291
+ const attrs = validateAttrKeys(
292
+ issues,
293
+ path,
294
+ type,
295
+ node.attrs,
296
+ AGENT_NODE_ATTR_KEYS,
297
+ );
298
+ if (attrs) {
299
+ validateNodeSemantics(issues, path, type, attrs, node.content);
300
+ }
301
+
302
+ if (node.marks !== undefined) {
303
+ push(issues, `${path}.marks`, "仅 text 节点可有 marks");
304
+ }
305
+
306
+ const atomTypes = new Set(["horizontalRule", "hardBreak", "image"]);
307
+ if (atomTypes.has(type)) {
308
+ if (
309
+ node.content !== undefined &&
310
+ Array.isArray(node.content) &&
311
+ node.content.length
312
+ ) {
313
+ push(issues, `${path}.content`, `${type} 不应有 content`);
314
+ }
315
+ return;
316
+ }
317
+
318
+ if (node.content === undefined) {
319
+ return;
320
+ }
321
+ if (!Array.isArray(node.content)) {
322
+ push(issues, `${path}.content`, "content 必须是数组");
323
+ return;
324
+ }
325
+ node.content.forEach((child, index) => {
326
+ validateNode(issues, `${path}.content[${index}]`, child, allowedNodes);
327
+ });
328
+ }
329
+
330
+ function validateAttachments(issues, attachments) {
331
+ if (attachments === undefined) {
332
+ return;
333
+ }
334
+ if (!Array.isArray(attachments)) {
335
+ push(issues, "attachments", "attachments 必须是数组");
336
+ return;
337
+ }
338
+ if (attachments.length > 0) {
339
+ push(
340
+ issues,
341
+ "attachments",
342
+ "Agent 默认勿生成 attachments(媒体由宿主 DocMediaHooks 上传);请使用 []",
343
+ );
344
+ }
345
+ }
346
+
347
+ /** @param {object} draft @param {{ tier?: 'A'|'B' }} [options] */
348
+ export function validateDocDraft(draft, options = {}) {
349
+ const tier = options.tier ?? "A";
350
+ const allowedNodes = allowedNodesForTier(tier);
351
+ const issues = [];
352
+
353
+ if (typeof draft.title !== "string") {
354
+ push(issues, "title", "title 必须是 string");
355
+ }
356
+
357
+ validateAttachments(issues, draft.attachments);
358
+
359
+ const content = draft.content;
360
+ if (!isRecord(content)) {
361
+ push(issues, "content", "content 必须是对象");
362
+ return { ok: false, issues };
363
+ }
364
+ if (content.type !== AGENT_DOC_ROOT) {
365
+ push(issues, "content.type", `根节点 type 必须是 "${AGENT_DOC_ROOT}"`);
366
+ }
367
+ validateNode(issues, "content", content, allowedNodes);
368
+
369
+ return { ok: issues.length === 0, issues };
370
+ }