@heybox/hb-sdk 0.8.0-alpha → 0.8.0-alpha.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 (94) hide show
  1. package/CHANGELOG.md +92 -396
  2. package/README.md +101 -24
  3. package/THIRD_PARTY_NOTICES.md +1755 -0
  4. package/dist/cli-chunks/{build-DJWFSM1B.cjs → build-aDJbiFqF.cjs} +8 -5
  5. package/dist/cli-chunks/{context-DV2UK1Nz.cjs → context-Dp36pZ9a.cjs} +39 -81
  6. package/dist/cli-chunks/{create-2HfoB48V.cjs → create-P3g0ricz.cjs} +2 -2
  7. package/dist/cli-chunks/{dev-Dgt2zS9k.cjs → dev-CisJkXuQ.cjs} +396 -576
  8. package/dist/cli-chunks/doctor-B-LF5-uj.cjs +65 -0
  9. package/dist/cli-chunks/{index-D62ANeBv.cjs → index-BDaeBI_B.cjs} +50 -30
  10. package/dist/cli-chunks/{index-BjoSXl8C.cjs → index-CZGkk7fQ.cjs} +2 -2
  11. package/dist/cli-chunks/{index.esm-CigcxJ2B.cjs → index.esm-NNLG29Tt.cjs} +8 -7
  12. package/dist/cli-chunks/{login-Cumknwdx.cjs → login-DTY5GolC.cjs} +2 -2
  13. package/dist/cli-chunks/{project-vite-CcE-HMmd.cjs → project-vite-DlCjHlu_.cjs} +1 -1
  14. package/dist/cli-chunks/{remote-DDdP3xcE.cjs → remote-BBMr7j8W.cjs} +57 -25
  15. package/dist/cli-chunks/{runtime-gate-DFjw66kF.cjs → runtime-gate-BppCl1r3.cjs} +11 -3
  16. package/dist/cli-chunks/{runtime-permission-env-CjsCe5bp.cjs → runtime-permission-env-CqsTHeas.cjs} +351 -0
  17. package/dist/cli-chunks/{session-BDi_AZSv.cjs → session-CnGeZCRZ.cjs} +1 -1
  18. package/dist/cli-chunks/skill-B0yAnPOJ.cjs +83 -0
  19. package/dist/cli-chunks/version-DN5jrixS.cjs +8 -0
  20. package/dist/cli.cjs +1 -1
  21. package/dist/devtools/browser-dev-host/assets/browser-dev-host-BhZGUyYw.js +97 -0
  22. package/dist/devtools/browser-dev-host/assets/heybox-logo-CogNENsk.svg +6 -0
  23. package/dist/devtools/browser-dev-host/assets/index-DJFB5ySU.css +1 -0
  24. package/dist/devtools/browser-dev-host/assets/index-Dh9H1JOm.js +567 -0
  25. package/dist/devtools/browser-dev-host/assets/workbench-state-wHgWRb7I.js +5 -0
  26. package/dist/devtools/browser-dev-host/index.html +6 -435
  27. package/dist/index.cjs.js +939 -29
  28. package/dist/index.esm.js +939 -30
  29. package/dist/protocol.cjs.js +381 -37
  30. package/dist/protocol.esm.js +355 -38
  31. package/dist/templates/{vue3-vite-ts → vanilla-vite-js}/.gitignore.ejs +0 -1
  32. package/dist/templates/vanilla-vite-js/README.md.ejs +14 -0
  33. package/dist/templates/vanilla-vite-js/index.html.ejs +20 -0
  34. package/dist/templates/vanilla-vite-js/package.json.ejs +22 -0
  35. package/dist/templates/vanilla-vite-js/src/assets/heybox-logo.svg +8 -0
  36. package/dist/templates/vanilla-vite-js/src/main.js +39 -0
  37. package/dist/templates/vanilla-vite-js/src/styles.css +155 -0
  38. package/dist/templates/{vue3-vite-ts/vite.config.ts → vanilla-vite-js/vite.config.js} +1 -2
  39. package/dist/vite.cjs.js +228 -9
  40. package/dist/vite.esm.js +228 -9
  41. package/package.json +36 -13
  42. package/skill/SKILL.md +22 -20
  43. package/skill/references/api-protocol.md +100 -6
  44. package/skill/references/api-root.md +166 -23
  45. package/skill/references/cli.md +41 -24
  46. package/skill/references/examples.md +30 -1
  47. package/skill/references/llms-index.md +1 -1
  48. package/skill/references/recipes.md +139 -36
  49. package/skill/references/safety-boundaries.md +14 -5
  50. package/skill/skill.json +10 -5
  51. package/types/core/client.d.ts +17 -1
  52. package/types/core/sdk.d.ts +3 -0
  53. package/types/core/singleton.d.ts +3 -0
  54. package/types/index.d.ts +4 -2
  55. package/types/miniapp-manifest/index.d.ts +1 -0
  56. package/types/miniapp-manifest/node.d.ts +3 -0
  57. package/types/miniapp-manifest/permissions.d.ts +37 -0
  58. package/types/miniapp-manifest/schema.d.ts +5 -0
  59. package/types/modules/files/index.d.ts +5 -0
  60. package/types/modules/files/registry.d.ts +35 -0
  61. package/types/modules/files/types.d.ts +159 -0
  62. package/types/modules/network/index.d.ts +50 -3
  63. package/types/modules/share/index.d.ts +1 -1
  64. package/types/modules/share/show-share-menu.d.ts +1 -1
  65. package/types/modules/share/types.d.ts +2 -4
  66. package/types/protocol/capabilities.d.ts +2 -2
  67. package/types/protocol/constants.d.ts +1 -1
  68. package/types/protocol/guards.d.ts +1 -1
  69. package/types/protocol/types.d.ts +1 -1
  70. package/types/protocol.d.ts +4 -3
  71. package/types/skill-metadata.d.ts +0 -4
  72. package/dist/cli-chunks/doctor-C95gIao_.cjs +0 -204
  73. package/dist/devtools/browser-dev-host/main.js +0 -12263
  74. package/dist/templates/vue3-vite-ts/README.md.ejs +0 -47
  75. package/dist/templates/vue3-vite-ts/index.html.ejs +0 -12
  76. package/dist/templates/vue3-vite-ts/package.json.ejs +0 -33
  77. package/dist/templates/vue3-vite-ts/src/App.vue +0 -78
  78. package/dist/templates/vue3-vite-ts/src/__tests__/App.spec.ts +0 -148
  79. package/dist/templates/vue3-vite-ts/src/auth-handoff.ts +0 -46
  80. package/dist/templates/vue3-vite-ts/src/main.ts +0 -5
  81. package/dist/templates/vue3-vite-ts/src/styles.css +0 -60
  82. package/dist/templates/vue3-vite-ts/src/vite-env.d.ts +0 -1
  83. package/dist/templates/vue3-vite-ts/tsconfig.app.json +0 -17
  84. package/dist/templates/vue3-vite-ts/tsconfig.json +0 -11
  85. package/dist/templates/vue3-vite-ts/tsconfig.node.json +0 -11
  86. package/dist/templates/vue3-vite-ts/vitest.config.ts +0 -10
  87. package/skill/scripts/check-references.mjs +0 -14
  88. package/skill/scripts/markdown-sections.mjs +0 -36
  89. package/skill/scripts/package-skill.mjs +0 -60
  90. package/skill/scripts/package-skill.sh +0 -6
  91. package/skill/scripts/skill-metadata.mjs +0 -77
  92. package/skill/scripts/sync-agent-skills-payload.mjs +0 -359
  93. package/skill/scripts/sync-references.mjs +0 -794
  94. package/skill/scripts/validate-skill.mjs +0 -263
@@ -1,47 +0,0 @@
1
- # <%= projectName %>
2
-
3
- `vite.config.ts` 中的 `miniappManifest({ platforms })` 声明本项目承诺适配的平台。模板预填的 `android`、`ios`、`ohos` 只是初始配置;发布前请按实际目标调整,并在每个声明的平台完成真机验收。
4
-
5
- 这是通过 `hb-sdk create` 生成的小黑盒工坊小程序模板。项目使用 Vue 3、Vite、TypeScript 和 `@heybox/hb-sdk`。
6
-
7
- ## 使用命令
8
-
9
- ```bash
10
- npm install
11
- npm run dev
12
- npm run typecheck
13
- npm run test:unit
14
- npm run build
15
- npm run deploy
16
- ```
17
-
18
- ## 依赖说明
19
-
20
- `@heybox/hb-sdk` 是小程序页面运行时会 import 的 SDK,因此模板把它放在 `dependencies`。Vite、TypeScript、Vitest 等只参与本地开发、测试或构建的工具放在 `devDependencies`。
21
-
22
- ## 开发模式
23
-
24
- - `npm run dev`:打开本地调试页,可以使用浏览器 Mock,也可以在 Mac 版 APP 或手机小黑盒 APP 中验收。手机和电脑需要处于同一局域网。
25
- - `npm run build`:先执行 TypeScript 检查,再通过 `hb-sdk build` 构建生产产物。
26
- - `npm run deploy -- --release-note "..."`:检查、执行项目的 `scripts.build`、上传并提交审核。首次提交前先运行 `npx hb-sdk login`,再用 `npx hb-sdk remote create` 创建小程序,或用 `npx hb-sdk remote bind <mini-program-id>` 绑定已有小程序。审核通过后,用 `hb-sdk remote release <version>` 发布。
27
-
28
- ## 更多能力
29
-
30
- 模板页面只保留最小接入示例。其他常用能力可以直接从 `@heybox/hb-sdk` 调用:
31
-
32
- ```ts
33
- import hbSDK from '@heybox/hb-sdk';
34
-
35
- await hbSDK.share.showShareMenu({
36
- title: '<%= projectName %>',
37
- desc: '分享描述',
38
- });
39
-
40
- await hbSDK.storage.setStorage({
41
- key: 'settings',
42
- data: { theme: 'dark' },
43
- });
44
-
45
- ```
46
-
47
- 工坊小程序默认不能进行网络请求。开通网络权限后,把 `VITE_HEYBOX_AUTH_EXCHANGE_URL` 配成开发者服务端的 HTTPS 交换地址(本地可用 localhost)。授权契约见文档站「用户身份与登录」。
@@ -1,12 +0,0 @@
1
- <!doctype html>
2
- <html lang="zh-CN">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title><%= projectName %></title>
7
- </head>
8
- <body>
9
- <div id="app"></div>
10
- <script type="module" src="/src/main.ts"></script>
11
- </body>
12
- </html>
@@ -1,33 +0,0 @@
1
- {
2
- "name": "<%= packageName %>",
3
- "version": "0.0.0",
4
- "private": true,
5
- "type": "module",
6
- "heybox": {
7
- "miniProgramId": ""
8
- },
9
- "scripts": {
10
- "hb-sdk": "hb-sdk",
11
- "dev": "hb-sdk dev",
12
- "deploy": "hb-sdk remote deploy",
13
- "build": "vue-tsc --noEmit && hb-sdk build",
14
- "preview": "vite preview",
15
- "typecheck": "vue-tsc --noEmit",
16
- "test:unit": "vitest run",
17
- "test:unit:watch": "vitest"
18
- },
19
- "dependencies": {
20
- "@heybox/hb-sdk": "^<%= sdkVersion %>",
21
- "vue": "^3.5.34"
22
- },
23
- "devDependencies": {
24
- "@types/node": "^25.7.0",
25
- "@vitejs/plugin-vue": "^6.0.6",
26
- "@vue/test-utils": "^2.4.10",
27
- "happy-dom": "^20.9.0",
28
- "typescript": "^6.0.3",
29
- "vite": "^8.0.12",
30
- "vitest": "^4.1.6",
31
- "vue-tsc": "^3.2.9"
32
- }
33
- }
@@ -1,78 +0,0 @@
1
- <template>
2
- <main class="page">
3
- <section class="card">
4
- <p class="eyebrow">Heybox Mini Program</p>
5
- <h1><%= projectName %></h1>
6
- <p class="intro">这个模板只保留最小接入示例:SDK 会自动完成初始化,由用户主动选择受支持的操作。</p>
7
-
8
- <p class="status" data-testid="status">{{ status }}</p>
9
-
10
- <button type="button" :disabled="loading || !sdkReady" data-testid="login" @click="login">获取授权码</button>
11
-
12
- <pre data-testid="output">{{ output }}</pre>
13
- </section>
14
- </main>
15
- </template>
16
-
17
- <script setup lang="ts">
18
- import hbSDK from '@heybox/hb-sdk';
19
- import type { MiniProgramSDKHandshakeState } from '@heybox/hb-sdk';
20
- import { onBeforeUnmount, ref } from 'vue';
21
- import { loginAndExchangeAuthorizationCode } from './auth-handoff';
22
-
23
- const loading = ref(false);
24
- const sdkReady = ref(false);
25
- const status = ref('正在连接 SDK...');
26
- const output = ref('请选择操作。');
27
-
28
- function updateHandshakeState(state: MiniProgramSDKHandshakeState) {
29
- if (state.status === 'connecting') {
30
- sdkReady.value = false;
31
- status.value = '正在连接 SDK...';
32
- return;
33
- }
34
-
35
- if (state.status === 'failed') {
36
- sdkReady.value = false;
37
- status.value = 'SDK 连接失败';
38
- output.value = readErrorMessage(state.error);
39
- return;
40
- }
41
-
42
- sdkReady.value = true;
43
- status.value = 'SDK 已连接';
44
- output.value = '请选择操作。';
45
- }
46
-
47
- const stopHandshakeState = hbSDK.onHandshakeStateChange(updateHandshakeState);
48
- onBeforeUnmount(stopHandshakeState);
49
-
50
- async function login() {
51
- loading.value = true;
52
- status.value = 'auth.login 调用中...';
53
-
54
- try {
55
- const { expiresIn, scopes } = await loginAndExchangeAuthorizationCode({
56
- exchangeUrl: import.meta.env.VITE_HEYBOX_AUTH_EXCHANGE_URL,
57
- login: () => hbSDK.auth.login(),
58
- request: (config) => hbSDK.network.request(config),
59
- });
60
- status.value = 'auth.login 调用成功';
61
- output.value = JSON.stringify({ expiresIn, scopes }, null, 2);
62
- } catch (error) {
63
- status.value = 'auth.login 调用失败';
64
- output.value = readErrorMessage(error);
65
- } finally {
66
- loading.value = false;
67
- }
68
- }
69
-
70
- function readErrorMessage(error: unknown) {
71
- if (!(error instanceof Error)) {
72
- return String(error);
73
- }
74
-
75
- const code = 'code' in error && typeof error.code === 'string' ? `\ncode: ${error.code}` : '';
76
- return `${error.name}: ${error.message}${code}`;
77
- }
78
- </script>
@@ -1,148 +0,0 @@
1
- import { flushPromises, mount } from '@vue/test-utils';
2
- import { beforeEach, describe, expect, it, vi } from 'vitest';
3
- import App from '../App.vue';
4
-
5
- const sdkMock = vi.hoisted(() => ({
6
- ...(() => {
7
- type HandshakeState = { status: 'connecting' } | { status: 'ready' } | { status: 'failed'; error: Error & { code: string } };
8
-
9
- let state: HandshakeState = { status: 'connecting' };
10
- const handlers = new Set<(nextState: HandshakeState) => void>();
11
- const unsubscribe = vi.fn();
12
-
13
- return {
14
- getHandshakeState: vi.fn(() => state),
15
- onHandshakeStateChange: vi.fn((handler: (nextState: HandshakeState) => void) => {
16
- handlers.add(handler);
17
- handler(state);
18
- return () => {
19
- unsubscribe();
20
- handlers.delete(handler);
21
- };
22
- }),
23
- reset(nextState: HandshakeState = { status: 'connecting' }) {
24
- state = nextState;
25
- handlers.clear();
26
- unsubscribe.mockReset();
27
- },
28
- setHandshakeState(nextState: HandshakeState) {
29
- state = nextState;
30
- handlers.forEach((handler) => handler(state));
31
- },
32
- unsubscribe,
33
- };
34
- })(),
35
- login: vi.fn(),
36
- networkRequest: vi.fn(),
37
- }));
38
-
39
- vi.mock('@heybox/hb-sdk', () => ({
40
- default: {
41
- auth: {
42
- login: sdkMock.login,
43
- },
44
- network: {
45
- request: sdkMock.networkRequest,
46
- },
47
- getHandshakeState: sdkMock.getHandshakeState,
48
- onHandshakeStateChange: sdkMock.onHandshakeStateChange,
49
- },
50
- }));
51
-
52
- describe('App', () => {
53
- beforeEach(() => {
54
- vi.clearAllMocks();
55
- vi.unstubAllEnvs();
56
-
57
- sdkMock.reset();
58
- sdkMock.login.mockResolvedValue({ code: 'authorization_code', expiresIn: 300, scopes: ['identity'] });
59
- sdkMock.networkRequest.mockResolvedValue({ status: 200 });
60
- });
61
-
62
- it('keeps actions disabled while the SDK is connecting', () => {
63
- const wrapper = mount(App);
64
-
65
- expect(sdkMock.getHandshakeState).not.toHaveBeenCalled();
66
- expect(wrapper.get('[data-testid="status"]').text()).toBe('正在连接 SDK...');
67
- expect(wrapper.get<HTMLButtonElement>('[data-testid="login"]').element.disabled).toBe(true);
68
- });
69
-
70
- it('enables actions when the handshake becomes ready', async () => {
71
- const wrapper = mount(App);
72
-
73
- sdkMock.setHandshakeState({ status: 'ready' });
74
- await flushPromises();
75
-
76
- expect(wrapper.get('[data-testid="status"]').text()).toBe('SDK 已连接');
77
- expect(wrapper.get('[data-testid="output"]').text()).toContain('请选择操作');
78
- expect(wrapper.get<HTMLButtonElement>('[data-testid="login"]').element.disabled).toBe(false);
79
- });
80
-
81
- describe('late mount', () => {
82
- it('renders an already-ready handshake immediately', () => {
83
- sdkMock.reset({ status: 'ready' });
84
-
85
- const wrapper = mount(App);
86
-
87
- expect(wrapper.get('[data-testid="status"]').text()).toBe('SDK 已连接');
88
- expect(wrapper.get<HTMLButtonElement>('[data-testid="login"]').element.disabled).toBe(false);
89
- });
90
-
91
- it('renders the original failed handshake details immediately', () => {
92
- const error = Object.assign(new Error('Host 未响应'), {
93
- code: 'HANDSHAKE_TIMEOUT',
94
- name: 'HbMiniProgramSDKError',
95
- });
96
- sdkMock.reset({ status: 'failed', error });
97
-
98
- const wrapper = mount(App);
99
-
100
- expect(wrapper.get('[data-testid="status"]').text()).toBe('SDK 连接失败');
101
- expect(wrapper.get<HTMLButtonElement>('[data-testid="login"]').element.disabled).toBe(true);
102
- expect(wrapper.get('[data-testid="output"]').text()).toContain('HbMiniProgramSDKError');
103
- expect(wrapper.get('[data-testid="output"]').text()).toContain('Host 未响应');
104
- expect(wrapper.get('[data-testid="output"]').text()).toContain('HANDSHAKE_TIMEOUT');
105
- });
106
- });
107
-
108
- it('stops observing handshake state after unmount', () => {
109
- const wrapper = mount(App);
110
-
111
- wrapper.unmount();
112
-
113
- expect(sdkMock.unsubscribe).toHaveBeenCalledTimes(1);
114
- });
115
-
116
- it('hands the authorization code to the developer server without rendering it', async () => {
117
- vi.stubEnv('VITE_HEYBOX_AUTH_EXCHANGE_URL', 'https://developer.example.com/api/heybox/exchange');
118
- sdkMock.reset({ status: 'ready' });
119
- const wrapper = mount(App);
120
-
121
- await wrapper.get('[data-testid="login"]').trigger('click');
122
- await flushPromises();
123
-
124
- expect(sdkMock.login).toHaveBeenCalledTimes(1);
125
- expect(sdkMock.networkRequest).toHaveBeenCalledWith({
126
- method: 'POST',
127
- url: 'https://developer.example.com/api/heybox/exchange',
128
- data: { code: 'authorization_code' },
129
- });
130
- expect(wrapper.get('[data-testid="status"]').text()).toBe('auth.login 调用成功');
131
- expect(wrapper.get('[data-testid="output"]').text()).toContain('300');
132
- expect(wrapper.get('[data-testid="output"]').text()).toContain('identity');
133
- expect(wrapper.text()).not.toContain('authorization_code');
134
- });
135
-
136
- it('does not request a code when the developer server is not configured', async () => {
137
- sdkMock.reset({ status: 'ready' });
138
- const wrapper = mount(App);
139
-
140
- await wrapper.get('[data-testid="login"]').trigger('click');
141
- await flushPromises();
142
-
143
- expect(sdkMock.login).not.toHaveBeenCalled();
144
- expect(sdkMock.networkRequest).not.toHaveBeenCalled();
145
- expect(wrapper.get('[data-testid="status"]').text()).toBe('auth.login 调用失败');
146
- expect(wrapper.get('[data-testid="output"]').text()).toContain('VITE_HEYBOX_AUTH_EXCHANGE_URL');
147
- });
148
- });
@@ -1,46 +0,0 @@
1
- export interface AuthorizationCodeLoginResult {
2
- code: string;
3
- expiresIn: number;
4
- scopes: string[];
5
- }
6
-
7
- export interface LoginAndExchangeAuthorizationCodeOptions {
8
- exchangeUrl?: string;
9
- login: () => Promise<AuthorizationCodeLoginResult>;
10
- request: (config: {
11
- method: 'POST';
12
- url: string;
13
- data: { code: string };
14
- }) => Promise<unknown>;
15
- }
16
-
17
- export async function loginAndExchangeAuthorizationCode(options: LoginAndExchangeAuthorizationCodeOptions) {
18
- const exchangeUrl = options.exchangeUrl?.trim();
19
- if (!exchangeUrl) {
20
- throw new Error('请先配置 VITE_HEYBOX_AUTH_EXCHANGE_URL');
21
- }
22
- if (!isAllowedExchangeUrl(exchangeUrl)) {
23
- throw new Error('VITE_HEYBOX_AUTH_EXCHANGE_URL 必须使用 HTTPS,本地调试仅允许 localhost');
24
- }
25
-
26
- const { code, expiresIn, scopes } = await options.login();
27
- await options.request({
28
- method: 'POST',
29
- url: exchangeUrl,
30
- data: { code },
31
- });
32
-
33
- return { expiresIn, scopes };
34
- }
35
-
36
- function isAllowedExchangeUrl(value: string) {
37
- try {
38
- const url = new URL(value);
39
- if (url.protocol === 'https:') {
40
- return true;
41
- }
42
- return url.protocol === 'http:' && ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname);
43
- } catch {
44
- return false;
45
- }
46
- }
@@ -1,5 +0,0 @@
1
- import { createApp } from 'vue';
2
- import App from './App.vue';
3
- import './styles.css';
4
-
5
- createApp(App).mount('#app');
@@ -1,60 +0,0 @@
1
- :root {
2
- color: #1f2933;
3
- background: #f4f6f8;
4
- font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
5
- line-height: 1.5;
6
- }
7
- * {
8
- box-sizing: border-box;
9
- }
10
- body {
11
- margin: 0; min-width: 320px;
12
- }
13
- .page {
14
- width: min(100%, 720px);
15
- margin: 0 auto;
16
- padding: 40px 20px;
17
- }
18
- .card {
19
- border: 1px solid #d8dee6;
20
- border-radius: 8px;
21
- background: #fff;
22
- padding: 24px;
23
- }
24
- .eyebrow {
25
- margin: 0 0 8px;
26
- color: #287a4b;
27
- font-size: 13px;
28
- font-weight: 800;
29
- }
30
- h1 {
31
- margin: 0; font-size: 36px; line-height: 1.1;
32
- }
33
- .intro,
34
- .status {
35
- color: #52616f;
36
- }
37
- button {
38
- width: 100%;
39
- min-height: 42px;
40
- border: 0;
41
- border-radius: 6px;
42
- background: #1f2933;
43
- color: #fff;
44
- cursor: pointer;
45
- font: inherit;
46
- font-weight: 700;
47
- }
48
- button:disabled {
49
- cursor: not-allowed; opacity: 0.6;
50
- }
51
- pre {
52
- margin: 16px 0 0;
53
- overflow: auto;
54
- border-radius: 6px;
55
- background: #101820;
56
- color: #f7fbff;
57
- padding: 14px;
58
- white-space: pre-wrap;
59
- word-break: break-word;
60
- }
@@ -1 +0,0 @@
1
- /// <reference types="vite/client" />
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "useDefineForClassFields": true,
5
- "module": "ESNext",
6
- "moduleResolution": "Bundler",
7
- "strict": true,
8
- "jsx": "preserve",
9
- "sourceMap": true,
10
- "resolveJsonModule": true,
11
- "isolatedModules": true,
12
- "noEmit": true,
13
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
14
- "types": ["vite/client"]
15
- },
16
- "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
17
- }
@@ -1,11 +0,0 @@
1
- {
2
- "files": [],
3
- "references": [
4
- {
5
- "path": "./tsconfig.app.json"
6
- },
7
- {
8
- "path": "./tsconfig.node.json"
9
- }
10
- ]
11
- }
@@ -1,11 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "Bundler",
6
- "strict": true,
7
- "noEmit": true,
8
- "types": ["node"]
9
- },
10
- "include": ["vite.config.ts", "vitest.config.ts"]
11
- }
@@ -1,10 +0,0 @@
1
- import vue from '@vitejs/plugin-vue';
2
- import { defineConfig } from 'vitest/config';
3
-
4
- export default defineConfig({
5
- plugins: [vue()],
6
- test: {
7
- environment: 'happy-dom',
8
- include: ['src/**/*.spec.ts'],
9
- },
10
- });
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
- import { spawnSync } from 'node:child_process';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import process from 'node:process';
6
-
7
- const scriptPath = path.join(path.dirname(fileURLToPath(import.meta.url)), 'sync-references.mjs');
8
- const result = spawnSync(process.execPath, [scriptPath, '--check'], {
9
- cwd: process.cwd(),
10
- encoding: 'utf8',
11
- stdio: 'inherit',
12
- });
13
-
14
- process.exit(result.status ?? 1);
@@ -1,36 +0,0 @@
1
- export function extractSection(markdown, heading) {
2
- const lines = markdown.split('\n');
3
- const start = lines.findIndex((line) => line.trim() === heading);
4
- if (start === -1) return '';
5
- const level = heading.match(/^#+/)?.[0].length ?? 2;
6
- const out = [lines[start]];
7
- let fenceChar = '';
8
- for (let index = start + 1; index < lines.length; index += 1) {
9
- const line = lines[index];
10
- const fenceMatch = line.match(/^\s*(`{3,}|~{3,})/);
11
-
12
- if (fenceChar) {
13
- out.push(line);
14
- if (fenceMatch?.[1]?.startsWith(fenceChar)) fenceChar = '';
15
- continue;
16
- }
17
-
18
- if (fenceMatch) {
19
- fenceChar = fenceMatch[1][0];
20
- out.push(line);
21
- continue;
22
- }
23
-
24
- const headingMatch = line.match(/^(#+)\s/);
25
- if (headingMatch && headingMatch[1].length <= level) break;
26
- out.push(line);
27
- }
28
- return out.join('\n').trimEnd();
29
- }
30
-
31
- export function replaceRequiredSection(markdown, heading, replacement) {
32
- const section = extractSection(markdown, heading);
33
- if (!section) throw new Error(`sync-references: 未找到待覆盖章节 ${heading}`);
34
- const start = markdown.indexOf(section);
35
- return `${markdown.slice(0, start)}${replacement.trimEnd()}${markdown.slice(start + section.length)}`;
36
- }
@@ -1,60 +0,0 @@
1
- #!/usr/bin/env node
2
- import { cpSync, existsSync, mkdtempSync, rmSync } from 'node:fs';
3
- import { spawnSync } from 'node:child_process';
4
- import { tmpdir } from 'node:os';
5
- import path from 'node:path';
6
- import { fileURLToPath } from 'node:url';
7
- import process from 'node:process';
8
- import { HB_SDK_SKILL_NAME } from './skill-metadata.mjs';
9
-
10
- const scriptDir = path.dirname(fileURLToPath(import.meta.url));
11
- const skillDir = path.resolve(scriptDir, '..');
12
- const packageRoot = path.resolve(skillDir, '..');
13
- const skillName = HB_SDK_SKILL_NAME;
14
- const repoRoot = findRepoRoot(process.cwd()) ?? packageRoot;
15
- const zipPath = path.join(packageRoot, `${skillName}.zip`);
16
-
17
- function findRepoRoot(startDir) {
18
- let dir = path.resolve(startDir);
19
- while (true) {
20
- if (existsSync(path.join(dir, 'package.json')) && existsSync(path.join(dir, 'packages/hb-sdk/package.json'))) {
21
- return dir;
22
- }
23
- const parent = path.dirname(dir);
24
- if (parent === dir) return null;
25
- dir = parent;
26
- }
27
- }
28
-
29
- if (!existsSync(path.join(skillDir, 'SKILL.md'))) {
30
- console.error(`Missing ${path.relative(repoRoot, path.join(skillDir, 'SKILL.md'))}.`);
31
- process.exit(1);
32
- }
33
-
34
- if (existsSync(zipPath)) rmSync(zipPath);
35
-
36
- const tempRoot = mkdtempSync(path.join(tmpdir(), 'hb-sdk-skill-'));
37
- const packagedSkillRoot = path.join(tempRoot, skillName);
38
-
39
- try {
40
- cpSync(skillDir, packagedSkillRoot, { recursive: true });
41
-
42
- const result = spawnSync(
43
- 'zip',
44
- ['-r', zipPath, skillName, '-x', `${skillName}/README.md`, '-x', `${skillName}/**/.DS_Store`],
45
- {
46
- cwd: tempRoot,
47
- encoding: 'utf8',
48
- },
49
- );
50
-
51
- if (result.status !== 0) {
52
- process.stderr.write(result.stderr || result.stdout);
53
- process.exit(result.status ?? 1);
54
- }
55
-
56
- console.error(result.stdout.trim());
57
- console.log(JSON.stringify({ ok: true, zip: path.relative(repoRoot, zipPath).split(path.sep).join('/') }));
58
- } finally {
59
- rmSync(tempRoot, { recursive: true, force: true });
60
- }
@@ -1,6 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
-
4
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
5
- echo "Packaging hb-sdk skill" >&2
6
- node "$SCRIPT_DIR/package-skill.mjs"