@h-ai/cli 0.1.0-alpha.19 → 0.1.0-alpha.20

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 (63) hide show
  1. package/dist/{chunk-BPO34NRL.js → chunk-3BBXDQ4Y.js} +5 -5
  2. package/dist/chunk-3BBXDQ4Y.js.map +1 -0
  3. package/dist/cli-config-templates-IGGO7P45.js +5 -0
  4. package/dist/{cli-config-templates-JCS7T3NU.js.map → cli-config-templates-IGGO7P45.js.map} +1 -1
  5. package/dist/index.js +67 -39
  6. package/dist/index.js.map +1 -1
  7. package/dist/{src-N4NPS7AG.js → src-QNEJJ3BV.js} +261 -103
  8. package/dist/src-QNEJJ3BV.js.map +1 -0
  9. package/package.json +2 -2
  10. package/templates/apps/admin/messages/en-US.json +5 -0
  11. package/templates/apps/admin/messages/zh-CN.json +5 -0
  12. package/templates/apps/admin/src/routes/+layout.svelte.hbs +5 -5
  13. package/templates/apps/admin/src/routes/+page.svelte.hbs +32 -12
  14. package/templates/apps/admin/src/routes/admin/+layout.svelte.hbs +37 -20
  15. package/templates/apps/admin/src/routes/admin/+page.svelte.hbs +33 -24
  16. package/templates/apps/admin/src/routes/admin/settings/+page.svelte.hbs +16 -13
  17. package/templates/apps/android-app/src/lib/api.ts.hbs +4 -3
  18. package/templates/apps/android-app/src/lib/capacitor.ts +1 -1
  19. package/templates/apps/android-app/src/routes/+layout.svelte.hbs +11 -10
  20. package/templates/apps/android-app/src/routes/+page.svelte.hbs +17 -6
  21. package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +4 -1
  22. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_core.yml.hbs +14 -0
  23. package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +13 -0
  24. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/index.ts.hbs +3 -0
  25. package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server-app.ts.hbs +23 -3
  26. package/templates/apps/h5/messages/en-US.json +3 -0
  27. package/templates/apps/h5/messages/zh-CN.json +3 -0
  28. package/templates/apps/h5/src/routes/+layout.svelte.hbs +30 -29
  29. package/templates/apps/h5/src/routes/+page.svelte.hbs +17 -6
  30. package/templates/apps/h5/src/routes/discover/+page.svelte.hbs +17 -6
  31. package/templates/apps/h5/src/routes/profile/+page.svelte.hbs +17 -6
  32. package/templates/apps/website/src/routes/+layout.svelte.hbs +35 -26
  33. package/templates/apps/website/src/routes/+page.svelte.hbs +28 -10
  34. package/templates/apps/website/src/routes/about/+page.svelte.hbs +11 -6
  35. package/templates/apps/website/src/routes/contact/+page.svelte.hbs +37 -34
  36. package/templates/apps/website/src/routes/services/+page.svelte.hbs +27 -40
  37. package/templates/base/package.json.hbs +26 -21
  38. package/templates/base/src/app.html.hbs +4 -0
  39. package/templates/base/src/hooks.server.ts.hbs +17 -7
  40. package/templates/base/src/lib/server/init.ts.hbs +20 -12
  41. package/templates/base/static/favicon.png +0 -0
  42. package/templates/base/tests/scaffold.test.ts.hbs +9 -1
  43. package/templates/base/vite.config.ts.hbs +3 -3
  44. package/templates/features/iam/routes-admin/(auth)/+layout.svelte.hbs +5 -5
  45. package/templates/features/iam/routes-admin/(auth)/auth/login/+page.svelte.hbs +34 -32
  46. package/templates/features/iam/routes-admin/(auth)/auth/register/+page.svelte.hbs +46 -48
  47. package/templates/features/iam/routes-h5/auth/login/+page.svelte.hbs +35 -31
  48. package/templates/features/iam/routes-h5/auth/register/+page.svelte.hbs +41 -38
  49. package/templates/skills/AGENTS.md +11 -1
  50. package/templates/skills/CLAUDE.md +2 -1
  51. package/templates/skills/copilot-instructions.md +22 -6
  52. package/templates/skills/hai-ai/SKILL.md +115 -648
  53. package/templates/skills/hai-ai/reference.md +197 -0
  54. package/templates/skills/hai-api-client/SKILL.md +3 -1
  55. package/templates/skills/hai-app-create/SKILL.md +1 -1
  56. package/templates/skills/hai-app-review/SKILL.md +1 -1
  57. package/templates/skills/hai-deploy/SKILL.md +12 -9
  58. package/templates/skills/hai-kit/SKILL.md +5 -3
  59. package/templates/skills/hai-serv/SKILL.md +2 -0
  60. package/templates/skills/hai-ui/SKILL.md +25 -11
  61. package/dist/chunk-BPO34NRL.js.map +0 -1
  62. package/dist/cli-config-templates-JCS7T3NU.js +0 -5
  63. package/dist/src-N4NPS7AG.js.map +0 -1
@@ -1,11 +1,13 @@
1
1
  {{!-- H5 注册页面 --}}
2
- <script lang="ts">
2
+ <script lang='ts'>
3
3
  /**
4
4
  * H5 注册页面
5
5
  */
6
+ import { resolve } from '$app/paths'
6
7
  {{#if hasI18n}}
7
8
  import * as m from '$lib/paraglide/messages'
8
9
  {{/if}}
10
+ import { Alert, Button, FormField, Input } from '@h-ai/ui'
9
11
 
10
12
  let username = $state('')
11
13
  let password = $state('')
@@ -13,7 +15,8 @@
13
15
  let error = $state('')
14
16
  let loading = $state(false)
15
17
 
16
- async function handleRegister() {
18
+ async function handleRegister(event: SubmitEvent) {
19
+ event.preventDefault()
17
20
  error = ''
18
21
  if (password !== confirmPassword) {
19
22
  {{#if hasI18n}}
@@ -33,20 +36,23 @@
33
36
  const data = await res.json()
34
37
  if (data.success) {
35
38
  window.location.href = '/auth/login'
36
- } else {
39
+ }
40
+ else {
37
41
  {{#if hasI18n}}
38
42
  error = data.error?.message || m.auth_register_failed()
39
43
  {{else}}
40
44
  error = data.error?.message || '注册失败'
41
45
  {{/if}}
42
46
  }
43
- } catch {
47
+ }
48
+ catch {
44
49
  {{#if hasI18n}}
45
50
  error = m.auth_error_network()
46
51
  {{else}}
47
52
  error = '网络错误'
48
53
  {{/if}}
49
- } finally {
54
+ }
55
+ finally {
50
56
  loading = false
51
57
  }
52
58
  }
@@ -60,55 +66,52 @@
60
66
  {{/if}}
61
67
  </svelte:head>
62
68
 
63
- <div class="p-4 pt-12">
69
+ <div class='p-4 pt-12 space-y-4'>
64
70
  {{#if hasI18n}}
65
- <h1 class="text-2xl font-bold text-center mb-8">{m.auth_register_title()}</h1>
71
+ <h1 class='text-2xl font-black tracking-tight text-center'>{m.auth_register_title()}</h1>
66
72
  {{else}}
67
- <h1 class="text-2xl font-bold text-center mb-8">注册</h1>
73
+ <h1 class='text-2xl font-black tracking-tight text-center'>注册</h1>
68
74
  {{/if}}
69
75
 
70
76
  {#if error}
71
- <div class="alert alert-error mb-4">
72
- <span>{error}</span>
73
- </div>
77
+ <Alert variant='error'>{error}</Alert>
74
78
  {/if}
75
79
 
76
- <form onsubmit={(e) => { e.preventDefault(); handleRegister() }} class="space-y-4">
77
- <div class="form-control">
78
- {{#if hasI18n}}
79
- <input type="text" placeholder={m.auth_label_username()} class="input input-bordered w-full" bind:value={username} required />
80
- {{else}}
81
- <input type="text" placeholder="用户名" class="input input-bordered w-full" bind:value={username} required />
82
- {{/if}}
83
- </div>
84
- <div class="form-control">
85
- {{#if hasI18n}}
86
- <input type="password" placeholder={m.auth_label_password()} class="input input-bordered w-full" bind:value={password} required />
87
- {{else}}
88
- <input type="password" placeholder="密码" class="input input-bordered w-full" bind:value={password} required />
89
- {{/if}}
90
- </div>
91
- <div class="form-control">
92
- {{#if hasI18n}}
93
- <input type="password" placeholder={m.auth_label_confirm_password()} class="input input-bordered w-full" bind:value={confirmPassword} required />
94
- {{else}}
95
- <input type="password" placeholder="确认密码" class="input input-bordered w-full" bind:value={confirmPassword} required />
96
- {{/if}}
97
- </div>
98
- <button type="submit" class="btn btn-primary w-full" disabled={loading}>
80
+ <form onsubmit={handleRegister} class='space-y-4'>
99
81
  {{#if hasI18n}}
82
+ <FormField label={m.auth_label_username()} required>
83
+ <Input id='username' type='text' bind:value={username} required />
84
+ </FormField>
85
+ <FormField label={m.auth_label_password()} required>
86
+ <Input id='password' type='password' bind:value={password} required />
87
+ </FormField>
88
+ <FormField label={m.auth_label_confirm_password()} required>
89
+ <Input id='confirmPassword' type='password' bind:value={confirmPassword} required />
90
+ </FormField>
91
+ <Button type='submit' variant='primary' loading={loading} class='w-full'>
100
92
  {loading ? m.auth_register_loading() : m.auth_register_submit()}
93
+ </Button>
101
94
  {{else}}
95
+ <FormField label='用户名' required>
96
+ <Input id='username' type='text' bind:value={username} required />
97
+ </FormField>
98
+ <FormField label='密码' required>
99
+ <Input id='password' type='password' bind:value={password} required />
100
+ </FormField>
101
+ <FormField label='确认密码' required>
102
+ <Input id='confirmPassword' type='password' bind:value={confirmPassword} required />
103
+ </FormField>
104
+ <Button type='submit' variant='primary' loading={loading} class='w-full'>
102
105
  {loading ? '注册中...' : '注册'}
106
+ </Button>
103
107
  {{/if}}
104
- </button>
105
108
  </form>
106
109
 
107
- <div class="text-center mt-6">
110
+ <div class='text-center'>
108
111
  {{#if hasI18n}}
109
- <a href="/auth/login" class="link link-primary text-sm">{m.auth_register_to_login()}</a>
112
+ <a href={resolve('/auth/login', {})} class='link link-primary text-sm'>{m.auth_register_to_login()}</a>
110
113
  {{else}}
111
- <a href="/auth/login" class="link link-primary text-sm">已有账号?立即登录</a>
114
+ <a href={resolve('/auth/login', {})} class='link link-primary text-sm'>已有账号?立即登录</a>
112
115
  {{/if}}
113
116
  </div>
114
117
  </div>
@@ -6,6 +6,8 @@
6
6
 
7
7
  本项目使用 hai-framework 构建,基于 SvelteKit 2 + Svelte 5 (Runes) + TailwindCSS 4 + DaisyUI 5 + TypeScript 5.7+。
8
8
 
9
+ 前后端分离工程中,SvelteKit app 主要负责 UI、路由与请求编排;业务 API 与服务端逻辑位于 `packages/<project>-serv`,通过 `@h-ai/serv` 实现。SSR、SPA 或静态输出以各 app 的 adapter 与配置为准,不要把 fullstack 后端业务逻辑写进 SvelteKit 页面、`load` 或前端组件。
10
+
9
11
  ## 核心规范
10
12
 
11
13
  - 统一模式:`module.init(config) → use → module.close()`,所有操作返回 `HaiResult<T>`
@@ -14,7 +16,15 @@
14
16
  - 用户可见文本走 i18n,代码注释中文,日志英文
15
17
  - HaiResult 错误直接透传,不重新包装
16
18
  - 框架模块公共 API 不抛异常,统一返回 `HaiResult<T>`;不要用 `try/catch` 处理模块返回的错误
17
- - 质量门禁:`pnpm typecheck && pnpm lint && pnpm test && pnpm --filter <app> test:e2e`
19
+ - 质量门禁按顺序执行:`pnpm typecheck` → `pnpm lint` → `pnpm build`(涉及构建/发布时)→ `pnpm test` → `pnpm --filter <workspace> test:e2e`(涉及 UI/路由/E2E 时)
20
+
21
+ ## 完成条件
22
+
23
+ - 失败的质量门禁必须先修复;不能提交或回复“已知失败”的改动。
24
+ - 新增/修改功能要同步测试;UI、路由和关键用户流程要同步 E2E。
25
+ - README、`.agents/skills/**/SKILL.md`、代码注释、i18n 消息、公共类型/API contract 与实现保持一致。
26
+ - 修改共享包、公共 API、contract、client、server procedure 或 CLI 模板后,必须检索并更新所有受影响的 `packages/*`、`apps/*` 与脚手架模板。
27
+ - 最终回复必须报告 typecheck/lint/build/test/e2e 状态、已更新文档、已更新依赖方;未执行或未通过项要说明原因和下一步。
18
28
 
19
29
  ## Skills 参考
20
30
 
@@ -7,6 +7,7 @@
7
7
  ## 使用说明
8
8
 
9
9
  - 本文件是 Claude Code 的原生项目级指引入口。
10
- - 项目概述、核心规范与工作流约定统一维护在 `AGENTS.md`;Claude Code 通过 `@AGENTS.md` 复用这些共享规范,避免双份文档漂移。
10
+ - 项目概述、核心规范、质量门禁与完成条件统一维护在 `AGENTS.md`;Claude Code 通过 `@AGENTS.md` 复用这些共享规范,避免双份文档漂移。
11
+ - 如果当前运行环境未自动展开 `@AGENTS.md`,必须先手动阅读 `AGENTS.md`,再开始修改代码或文档。
11
12
  - 共享的模块与工作流参考资料维护在 `.agents/skills/` 中;需要具体用法时,可按路径阅读对应 `SKILL.md`。
12
13
  - 当前模板为了保持单一 Skill 树,不额外生成 `.claude/skills/`;如需 Claude Code 的原生 project skills 自动发现,需要单独维护该目录。
@@ -9,7 +9,8 @@
9
9
  ## 技术栈要点
10
10
 
11
11
  - **前端框架**:Svelte 5 (Runes: `$props()`, `$state()`, `$derived()`, `$effect()`)
12
- - **路由/SSR**:SvelteKit 2(文件路由、Handle Hook、load 函数)
12
+ - **SvelteKit 应用层**:使用文件系统路由、`+layout/+page`、`load` 与 `hooks.server.ts` 做 UI/请求编排;SSR/SPA/静态输出以具体 app 的 adapter 与配置为准
13
+ - **Fullstack 服务端**:前后端分离工程的业务 API 在 `packages/<project>-serv` 中通过 `@h-ai/serv` 实现;不要把服务端业务逻辑塞进 SvelteKit 页面、`load` 或前端组件
13
14
  - **样式**:TailwindCSS 4 + DaisyUI 5
14
15
  - **后端框架**:hai-framework (`@h-ai/core`, `@h-ai/kit`, `@h-ai/reldb`, `@h-ai/iam` 等)
15
16
  - **统一模式**:`module.init(config) → use → module.close()`,所有操作返回 `HaiResult<T>`
@@ -37,7 +38,7 @@
37
38
  | ---------------- | ----------------------------------------------------- |
38
39
  | `hai-build` | 项目架构、模块依赖、初始化顺序、编码标准 |
39
40
  | `hai-core` | 配置加载、日志、i18n、HaiResult 模型、模块生命周期 |
40
- | `hai-kit` | SvelteKit 集成:Handle Hook、守卫、中间件、响应、校验 |
41
+ | `hai-kit` | SvelteKit 集成:`handle` hook、守卫、中间件、响应、校验 |
41
42
  | `hai-ui` | UI 组件库:三层架构、自动导入、主题、i18n |
42
43
  | `hai-reldb` | 数据库操作:DDL、SQL、CRUD、事务、分页 |
43
44
  | `hai-iam` | 认证与权限:密码/OTP/LDAP、会话、RBAC |
@@ -58,7 +59,22 @@
58
59
 
59
60
  ## 质量门禁
60
61
 
61
- ```bash
62
- pnpm typecheck && pnpm lint && pnpm test
63
- pnpm --filter <app-name> test:e2e # E2E 测试
64
- ```
62
+ 改动完成后按顺序执行,失败必须先修复,不能把已知失败留给下一轮:
63
+
64
+ 1. `pnpm typecheck`
65
+ 2. `pnpm lint`(可先 `pnpm lint:fix`,再重新执行 `pnpm lint`)
66
+ 3. `pnpm build`(涉及构建产物、打包配置、前后端分离工程或发布路径时必须执行)
67
+ 4. `pnpm test`
68
+ 5. `pnpm --filter <app-or-package> test:e2e`(涉及 UI、路由、浏览器交互或端到端流程时必须执行)
69
+
70
+ 优先使用 `pnpm --filter <workspace-name>` 缩小验证范围;跨包契约、共享类型或根配置变更必须提升到根命令验证。
71
+
72
+ ## 完成条件
73
+
74
+ - **测试同步**:新增/修改功能必须补单元测试;UI、路由和关键用户流程必须补 E2E 或更新现有 E2E。
75
+ - **文档同步**:README、`.agents/skills/**/SKILL.md`、代码注释与实际行为保持一致;生成模板改动要同步模板与测试断言。
76
+ - **i18n 同步**:所有用户可见文本必须走 i18n,并同时更新 `zh-CN` 与 `en-US` 消息文件。
77
+ - **类型/契约同步**:公共类型、API contract、client、server procedure 与调用方必须一起更新,不能只改一端。
78
+ - **错误处理同步**:新增错误码、错误消息或 HaiResult 形态时,同步文档、测试和调用方处理逻辑。
79
+ - **依赖方传导**:修改共享包、公共 API 或模板后,用全局检索确认引用点,并更新受影响的 `packages/*`、`apps/*`、CLI 模板/脚手架。
80
+ - **完成报告**:最终回复必须列出 typecheck/lint/build/test/e2e 状态、已更新文档、已更新依赖方;未执行或未通过的项目必须说明原因与后续动作。