@heybox/hb-sdk 0.8.0-alpha → 0.8.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -1
- package/README.md +87 -14
- package/THIRD_PARTY_NOTICES.md +1755 -0
- package/dist/cli-chunks/{build-DJWFSM1B.cjs → build-qWzAbpS7.cjs} +2 -2
- package/dist/cli-chunks/{context-DV2UK1Nz.cjs → context-CtS2Thp0.cjs} +1 -26
- package/dist/cli-chunks/{create-2HfoB48V.cjs → create-PV5ua977.cjs} +1 -1
- package/dist/cli-chunks/{dev-Dgt2zS9k.cjs → dev-CwKbAm_H.cjs} +337 -522
- package/dist/cli-chunks/doctor-tJUGOYrm.cjs +65 -0
- package/dist/cli-chunks/{index-BjoSXl8C.cjs → index-DVuD75Hr.cjs} +1 -1
- package/dist/cli-chunks/{index-D62ANeBv.cjs → index-De687C6-.cjs} +33 -24
- package/dist/cli-chunks/{index.esm-CigcxJ2B.cjs → index.esm-B-4yrLNm.cjs} +6 -5
- package/dist/cli-chunks/{login-Cumknwdx.cjs → login-DolpqD8K.cjs} +2 -2
- package/dist/cli-chunks/{project-vite-CcE-HMmd.cjs → project-vite-1rvkK-M8.cjs} +1 -1
- package/dist/cli-chunks/{remote-DDdP3xcE.cjs → remote-rIAQE_G2.cjs} +4 -4
- package/dist/cli-chunks/{session-BDi_AZSv.cjs → session-CzaM2Cq3.cjs} +1 -1
- package/dist/cli-chunks/skill-CM40_9WH.cjs +83 -0
- package/dist/cli-chunks/version-Bz-AfXQU.cjs +8 -0
- package/dist/cli.cjs +1 -1
- package/dist/devtools/browser-dev-host/assets/browser-dev-host-uq-Wac6k.js +97 -0
- package/dist/devtools/browser-dev-host/assets/heybox-logo-CogNENsk.svg +6 -0
- package/dist/devtools/browser-dev-host/assets/index-CeP6SLB3.js +567 -0
- package/dist/devtools/browser-dev-host/assets/index-KD2f3Jdz.css +1 -0
- package/dist/devtools/browser-dev-host/assets/workbench-state-D-1U0JRq.js +5 -0
- package/dist/devtools/browser-dev-host/index.html +6 -435
- package/dist/index.cjs.js +924 -28
- package/dist/index.esm.js +924 -29
- package/dist/protocol.cjs.js +208 -6
- package/dist/protocol.esm.js +182 -7
- package/dist/vite.cjs.js +1 -1
- package/dist/vite.esm.js +1 -1
- package/package.json +29 -10
- package/skill/SKILL.md +16 -13
- package/skill/references/api-protocol.md +100 -4
- package/skill/references/api-root.md +142 -15
- package/skill/references/cli.md +27 -22
- package/skill/references/examples.md +30 -1
- package/skill/references/llms-index.md +1 -1
- package/skill/references/recipes.md +106 -2
- package/skill/references/safety-boundaries.md +12 -1
- package/skill/skill.json +10 -5
- package/types/core/client.d.ts +17 -1
- package/types/core/sdk.d.ts +3 -0
- package/types/core/singleton.d.ts +3 -0
- package/types/index.d.ts +4 -2
- package/types/modules/files/index.d.ts +5 -0
- package/types/modules/files/registry.d.ts +35 -0
- package/types/modules/files/types.d.ts +159 -0
- package/types/modules/network/index.d.ts +50 -3
- package/types/protocol/capabilities.d.ts +2 -2
- package/types/protocol/constants.d.ts +1 -1
- package/types/protocol/guards.d.ts +1 -1
- package/types/protocol/types.d.ts +1 -1
- package/types/protocol.d.ts +4 -3
- package/types/skill-metadata.d.ts +0 -4
- package/dist/cli-chunks/doctor-C95gIao_.cjs +0 -204
- package/dist/devtools/browser-dev-host/main.js +0 -12263
- package/skill/scripts/check-references.mjs +0 -14
- package/skill/scripts/markdown-sections.mjs +0 -36
- package/skill/scripts/package-skill.mjs +0 -60
- package/skill/scripts/package-skill.sh +0 -6
- package/skill/scripts/skill-metadata.mjs +0 -77
- package/skill/scripts/sync-agent-skills-payload.mjs +0 -359
- package/skill/scripts/sync-references.mjs +0 -794
- package/skill/scripts/validate-skill.mjs +0 -263
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import process from 'node:process';
|
|
6
|
-
import { HB_SDK_PACKAGE_NAME, HB_SDK_SKILL_NAME, validateSkillManifest } from './skill-metadata.mjs';
|
|
7
|
-
|
|
8
|
-
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const skillRoot = path.resolve(scriptDir, '..');
|
|
10
|
-
const packageRoot = path.resolve(skillRoot, '..');
|
|
11
|
-
const repoRoot = findRepoRoot(process.cwd()) ?? findRepoRoot(skillRoot) ?? process.cwd();
|
|
12
|
-
const errors = [];
|
|
13
|
-
const warnings = [];
|
|
14
|
-
|
|
15
|
-
function findRepoRoot(startDir) {
|
|
16
|
-
let dir = path.resolve(startDir);
|
|
17
|
-
while (true) {
|
|
18
|
-
if (existsSync(path.join(dir, 'package.json')) && existsSync(path.join(dir, 'packages/hb-sdk/package.json'))) {
|
|
19
|
-
return dir;
|
|
20
|
-
}
|
|
21
|
-
const parent = path.dirname(dir);
|
|
22
|
-
if (parent === dir) return null;
|
|
23
|
-
dir = parent;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function rel(filePath) {
|
|
28
|
-
return path.relative(repoRoot, filePath).split(path.sep).join('/');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function skillRel(filePath) {
|
|
32
|
-
return path.relative(skillRoot, filePath).split(path.sep).join('/');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function fail(message) {
|
|
36
|
-
errors.push(message);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function warn(message) {
|
|
40
|
-
warnings.push(message);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function read(filePath) {
|
|
44
|
-
return readFileSync(filePath, 'utf8');
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function walk(dir) {
|
|
48
|
-
const out = [];
|
|
49
|
-
for (const entry of readdirSync(dir)) {
|
|
50
|
-
const fullPath = path.join(dir, entry);
|
|
51
|
-
const stat = statSync(fullPath);
|
|
52
|
-
if (stat.isDirectory()) out.push(...walk(fullPath));
|
|
53
|
-
else out.push(fullPath);
|
|
54
|
-
}
|
|
55
|
-
return out;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function parseFrontmatter(markdown) {
|
|
59
|
-
const match = markdown.match(/^---\n([\s\S]*?)\n---\n/);
|
|
60
|
-
if (!match) return null;
|
|
61
|
-
const fields = new Map();
|
|
62
|
-
for (const line of match[1].split('\n')) {
|
|
63
|
-
const field = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
|
|
64
|
-
if (field) fields.set(field[1], field[2].replace(/^['"]|['"]$/g, ''));
|
|
65
|
-
}
|
|
66
|
-
return fields;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function validateLocalMarkdownLinks(filePath, markdown) {
|
|
70
|
-
const linkPattern = /\[[^\]]*\]\(([^)]+)\)/g;
|
|
71
|
-
for (const match of markdown.matchAll(linkPattern)) {
|
|
72
|
-
const rawTarget = match[1].trim().replace(/^<|>$/g, '');
|
|
73
|
-
if (/^(?:https?:|mailto:|#)/i.test(rawTarget)) continue;
|
|
74
|
-
|
|
75
|
-
const targetWithoutAnchor = rawTarget.split('#')[0];
|
|
76
|
-
if (!targetWithoutAnchor) continue;
|
|
77
|
-
|
|
78
|
-
const resolved = path.resolve(path.dirname(filePath), targetWithoutAnchor);
|
|
79
|
-
if (!existsSync(resolved)) {
|
|
80
|
-
const line = markdown.slice(0, match.index).split('\n').length;
|
|
81
|
-
fail(`Broken local Markdown link in ${skillRel(filePath)}:${line}: ${rawTarget}`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
const requiredFiles = [
|
|
87
|
-
'SKILL.md',
|
|
88
|
-
'skill.json',
|
|
89
|
-
'references/api-root.md',
|
|
90
|
-
'references/api-protocol.md',
|
|
91
|
-
'references/cli.md',
|
|
92
|
-
'references/recipes.md',
|
|
93
|
-
'references/safety-boundaries.md',
|
|
94
|
-
'references/llms-index.md',
|
|
95
|
-
'references/examples.md',
|
|
96
|
-
'references/smoke-evaluation.md',
|
|
97
|
-
'scripts/sync-references.mjs',
|
|
98
|
-
'scripts/check-references.mjs',
|
|
99
|
-
'scripts/skill-metadata.mjs',
|
|
100
|
-
'scripts/validate-skill.mjs',
|
|
101
|
-
'scripts/package-skill.mjs',
|
|
102
|
-
'scripts/package-skill.sh',
|
|
103
|
-
];
|
|
104
|
-
|
|
105
|
-
for (const file of requiredFiles) {
|
|
106
|
-
const absolutePath = path.join(skillRoot, file);
|
|
107
|
-
if (!existsSync(absolutePath)) fail(`Missing required file: ${rel(absolutePath)}`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const skillMdPath = path.join(skillRoot, 'SKILL.md');
|
|
111
|
-
const packageJsonPath = path.join(repoRoot, 'packages/hb-sdk/package.json');
|
|
112
|
-
const skillJsonPath = path.join(skillRoot, 'skill.json');
|
|
113
|
-
|
|
114
|
-
if (existsSync(skillJsonPath) && existsSync(packageJsonPath)) {
|
|
115
|
-
try {
|
|
116
|
-
const skillJson = JSON.parse(read(skillJsonPath));
|
|
117
|
-
const packageJson = JSON.parse(read(packageJsonPath));
|
|
118
|
-
|
|
119
|
-
for (const error of validateSkillManifest({ manifest: skillJson, sdkVersion: packageJson.version })) {
|
|
120
|
-
fail(error);
|
|
121
|
-
}
|
|
122
|
-
} catch (error) {
|
|
123
|
-
fail(`skill.json must be valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (existsSync(skillMdPath)) {
|
|
128
|
-
const skillMd = read(skillMdPath);
|
|
129
|
-
const frontmatter = parseFrontmatter(skillMd);
|
|
130
|
-
if (!frontmatter) {
|
|
131
|
-
fail('SKILL.md must start with YAML frontmatter.');
|
|
132
|
-
} else {
|
|
133
|
-
const allowedFrontmatter = new Set(['name', 'description']);
|
|
134
|
-
for (const key of frontmatter.keys()) {
|
|
135
|
-
if (!allowedFrontmatter.has(key)) fail(`SKILL.md frontmatter must only include name and description; found ${key}.`);
|
|
136
|
-
}
|
|
137
|
-
const name = frontmatter.get('name');
|
|
138
|
-
const description = frontmatter.get('description');
|
|
139
|
-
if (name !== HB_SDK_SKILL_NAME) fail('SKILL.md frontmatter name must be `hb-sdk`.');
|
|
140
|
-
if (!description) fail('SKILL.md frontmatter description is required.');
|
|
141
|
-
if (description && description.length > 1024) fail('SKILL.md description must be <= 1024 characters.');
|
|
142
|
-
if (description && !description.includes("Don't use")) warn('Description should include negative triggers for discoverability.');
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const lineCount = skillMd.split('\n').length;
|
|
146
|
-
if (lineCount > 500) fail(`SKILL.md must stay under 500 lines; found ${lineCount}.`);
|
|
147
|
-
if (!skillMd.includes('references/api-root.md')) fail('SKILL.md must point agents to references/api-root.md.');
|
|
148
|
-
if (!skillMd.includes('references/api-protocol.md')) fail('SKILL.md must point agents to references/api-protocol.md.');
|
|
149
|
-
if (!skillMd.includes('references/cli.md')) fail('SKILL.md must point agents to references/cli.md.');
|
|
150
|
-
if (!skillMd.includes('references/smoke-evaluation.md')) fail('SKILL.md must point evaluators to references/smoke-evaluation.md.');
|
|
151
|
-
if (!skillMd.includes('host/runtime') && !skillMd.includes('Host/runtime')) fail('SKILL.md must gate protocol usage to host/runtime tasks.');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const nestedReferenceFiles = existsSync(path.join(skillRoot, 'references'))
|
|
155
|
-
? walk(path.join(skillRoot, 'references')).filter((file) =>
|
|
156
|
-
path.dirname(path.relative(path.join(skillRoot, 'references'), file)).includes(path.sep),
|
|
157
|
-
)
|
|
158
|
-
: [];
|
|
159
|
-
for (const file of nestedReferenceFiles) fail(`References must be one level deep: ${skillRel(file)}`);
|
|
160
|
-
|
|
161
|
-
if (existsSync(path.join(skillRoot, 'README.md')))
|
|
162
|
-
fail('Do not create README.md inside hb-sdk skill; keep human distribution docs outside the skill folder.');
|
|
163
|
-
if (existsSync(path.join(skillRoot, 'CHANGELOG.md'))) fail('Do not create CHANGELOG.md inside hb-sdk skill.');
|
|
164
|
-
if (existsSync(path.join(skillRoot, 'INSTALLATION_GUIDE.md'))) fail('Do not create INSTALLATION_GUIDE.md inside hb-sdk skill.');
|
|
165
|
-
|
|
166
|
-
const textFiles = existsSync(skillRoot) ? walk(skillRoot).filter((file) => /\.(md|yaml|yml|json|txt)$/.test(file)) : [];
|
|
167
|
-
|
|
168
|
-
const negativeMarkers = [
|
|
169
|
-
'do not',
|
|
170
|
-
"don't",
|
|
171
|
-
'does not',
|
|
172
|
-
'must not',
|
|
173
|
-
'never',
|
|
174
|
-
'no ',
|
|
175
|
-
'without',
|
|
176
|
-
'forbidden',
|
|
177
|
-
'refuse',
|
|
178
|
-
'block',
|
|
179
|
-
'fail',
|
|
180
|
-
'negative',
|
|
181
|
-
'不会',
|
|
182
|
-
'不应',
|
|
183
|
-
'不要',
|
|
184
|
-
'不能',
|
|
185
|
-
'不开放',
|
|
186
|
-
'无',
|
|
187
|
-
'禁止',
|
|
188
|
-
];
|
|
189
|
-
const positiveCredentialPattern =
|
|
190
|
-
/\b(read|extract|forward|store|persist|depend on|use|request|expose|get|parse|send)\b.*\b(token|cookie|credentials?|phone number|login state)\b/i;
|
|
191
|
-
const unsupportedStoragePattern = /\b(removeStorage|clearStorage|getStorageInfo|getStorageV2|delete storage|clear storage)\b/i;
|
|
192
|
-
const rawProtocolPattern = /\b(raw postMessage|construct bridge|bridge envelope|nonce handling|mutate bridge|sdk\.handshake)\b/i;
|
|
193
|
-
const removedUserLoginPattern = /\b(?:hbSDK\.)?user\.login\s*\(/;
|
|
194
|
-
const removedLocalIdentityPattern = /\b(?:hbSDK\.)?user\.getLocalIdentity\s*\(/;
|
|
195
|
-
|
|
196
|
-
for (const file of textFiles) {
|
|
197
|
-
const relative = skillRel(file);
|
|
198
|
-
const content = read(file);
|
|
199
|
-
if (file.endsWith('.md')) validateLocalMarkdownLinks(file, content);
|
|
200
|
-
if (removedUserLoginPattern.test(content)) {
|
|
201
|
-
fail(
|
|
202
|
-
`Removed API guidance found in ${relative}: use auth.login() for network-enabled server authentication or user.getInfo() for network-disabled local identity instead of user.login().`,
|
|
203
|
-
);
|
|
204
|
-
}
|
|
205
|
-
if (removedLocalIdentityPattern.test(content)) {
|
|
206
|
-
fail(
|
|
207
|
-
`Removed API guidance found in ${relative}: use user.getInfo() and read userInfo.app_user_id for network-disabled local identity.`,
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (
|
|
212
|
-
new RegExp(`${HB_SDK_PACKAGE_NAME.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\/(?!(?:protocol|vite|miniapp-publish)\\b)[A-Za-z0-9_./-]+`).test(
|
|
213
|
-
content,
|
|
214
|
-
)
|
|
215
|
-
) {
|
|
216
|
-
fail(
|
|
217
|
-
`Deep/internal hb-sdk import guidance found in ${relative}. Only @heybox/hb-sdk, @heybox/hb-sdk/protocol, @heybox/hb-sdk/vite, and @heybox/hb-sdk/miniapp-publish are allowed.`,
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const lines = content.split('\n');
|
|
222
|
-
lines.forEach((line, index) => {
|
|
223
|
-
const lower = line.toLowerCase();
|
|
224
|
-
const isNegative = negativeMarkers.some((marker) => lower.includes(marker));
|
|
225
|
-
if (positiveCredentialPattern.test(line) && !isNegative) {
|
|
226
|
-
fail(`Unsafe positive credential guidance in ${relative}:${index + 1}: ${line.trim()}`);
|
|
227
|
-
}
|
|
228
|
-
if (unsupportedStoragePattern.test(line) && !isNegative) {
|
|
229
|
-
fail(`Unsupported storage capability guidance in ${relative}:${index + 1}: ${line.trim()}`);
|
|
230
|
-
}
|
|
231
|
-
if (rawProtocolPattern.test(line) && !isNegative && !/host\/runtime|runtime|protocol|parent-container|parent container|父容器/i.test(line)) {
|
|
232
|
-
fail(`Raw protocol guidance without host/runtime context in ${relative}:${index + 1}: ${line.trim()}`);
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const recipesPath = path.join(skillRoot, 'references/recipes.md');
|
|
238
|
-
if (existsSync(recipesPath)) {
|
|
239
|
-
const recipes = read(recipesPath);
|
|
240
|
-
if (/api-protocol\.md/.test(recipes) && !/host\/runtime-only|host\/runtime|runtime only/i.test(recipes)) {
|
|
241
|
-
fail('references/recipes.md references api-protocol.md without a nearby host/runtime-only warning.');
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const protocolPath = path.join(skillRoot, 'references/api-protocol.md');
|
|
246
|
-
if (existsSync(protocolPath)) {
|
|
247
|
-
const protocol = read(protocolPath);
|
|
248
|
-
if (!/Host\/runtime-only warning/i.test(protocol)) fail('references/api-protocol.md must include a Host/runtime-only warning section.');
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const zipPath = path.join(packageRoot, 'hb-sdk.zip');
|
|
252
|
-
if (existsSync(zipPath)) {
|
|
253
|
-
const size = statSync(zipPath).size;
|
|
254
|
-
if (size <= 0) fail('packages/hb-sdk/hb-sdk.zip exists but is empty.');
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
for (const warning of warnings) console.error(`warning: ${warning}`);
|
|
258
|
-
if (errors.length > 0) {
|
|
259
|
-
for (const error of errors) console.error(`error: ${error}`);
|
|
260
|
-
process.exit(1);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
console.log(JSON.stringify({ ok: true, skillRoot: rel(skillRoot), checkedFiles: textFiles.length, warnings: warnings.length }));
|