@h-ai/cli 0.1.0-alpha.61 → 0.1.0-alpha.62
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/README.en.md +15 -1
- package/README.ja.md +15 -1
- package/README.md +15 -1
- package/dist/{chunk-WWG3U5ZD.js → chunk-X3RSYNBG.js} +8 -3
- package/dist/chunk-X3RSYNBG.js.map +1 -0
- package/dist/{cli-skill-templates-2KDUACT6.js → cli-skill-templates-EZFW7D43.js} +3 -3
- package/dist/{cli-skill-templates-2KDUACT6.js.map → cli-skill-templates-EZFW7D43.js.map} +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/templates/README.md +5 -4
- package/templates/apps/api/e2e/capture-evidence.ts.hbs +23 -0
- package/templates/apps/api/playwright.config.ts.hbs +1 -0
- package/templates/apps/fullstack/e2e/fullstack.spec.ts.hbs +123 -4
- package/templates/apps/fullstack/packages/{{projectName}}-serv/config/_serv.yml.hbs +2 -0
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/app-server.ts.hbs +1 -21
- package/templates/apps/fullstack/packages/{{projectName}}-serv/src/server/procedures/admin-procedures.ts.hbs +1 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/README.md.hbs +7 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/en-US.json.hbs +19 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/messages/zh-CN.json.hbs +19 -1
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AdminWorkspace.svelte.hbs +7 -2
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/AppShell.svelte.hbs +5 -3
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/components/ProfileSettings.svelte.hbs +3 -3
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/stores/guide-store.ts.hbs +55 -0
- package/templates/apps/fullstack/playwright.config.ts.hbs +21 -10
- package/templates/base/e2e/app.spec.ts.hbs +10 -6
- package/templates/base/package.json.hbs +1 -1
- package/templates/skills/AGENTS.md +6 -0
- package/templates/skills/bridges/admin/AGENTS.md +6 -0
- package/templates/skills/bridges/api/AGENTS.md +6 -0
- package/templates/skills/bridges/fullstack/AGENTS.md.hbs +6 -0
- package/templates/skills/bridges/h5/AGENTS.md +6 -0
- package/templates/skills/bridges/mobile-app/AGENTS.md +6 -0
- package/templates/skills/bridges/website/AGENTS.md +6 -0
- package/templates/skills/copilot-instructions.md +3 -9
- package/templates/skills/hai-app-create/SKILL.md +6 -0
- package/templates/skills/hai-app-create/development.md +10 -6
- package/templates/skills/hai-audit/SKILL.md +1 -1
- package/templates/skills/hai-build/SKILL.md +1 -0
- package/templates/skills/hai-build/reference.md +1 -1
- package/templates/skills/hai-ci/SKILL.md +1 -1
- package/templates/skills/hai-framework-sync/SKILL.md +67 -70
- package/templates/skills/hai-framework-sync/sync.md +49 -0
- package/templates/skills/hai-iam/SKILL.md +5 -0
- package/templates/skills/hai-iam/reference.md +88 -7
- package/templates/skills/hai-pr-review/SKILL.md +1 -1
- package/templates/skills/hai-reach/SKILL.md +1 -1
- package/templates/skills/hai-reach/reference.md +4 -5
- package/templates/skills/hai-serv/SKILL.md +1 -1
- package/templates/skills/hai-serv/reference.md +9 -6
- package/templates/skills/hai-spec-implement/SKILL.md +41 -0
- package/templates/skills/hai-spec-implement/templates.md +90 -0
- package/templates/skills/hai-spec-implement/workflow.md +53 -0
- package/templates/skills/hai-spec-review/SKILL.md +44 -0
- package/templates/skills/hai-spec-review/checklist.md +70 -0
- package/templates/skills/hai-storage/SKILL.md +9 -2
- package/templates/skills/hai-ui/SKILL.md +3 -1
- package/templates/skills/hai-ui/guide.md +79 -0
- package/templates/skills/hai-ui/reference.md +11 -0
- package/templates/skills/opencode.json +1 -1
- package/dist/chunk-WWG3U5ZD.js.map +0 -1
- package/templates/skills/bridges/admin/copilot-instructions.md +0 -11
- package/templates/skills/bridges/api/copilot-instructions.md +0 -13
- package/templates/skills/bridges/fullstack/copilot-instructions.md.hbs +0 -19
- package/templates/skills/bridges/h5/copilot-instructions.md +0 -11
- package/templates/skills/bridges/mobile-app/copilot-instructions.md +0 -11
- package/templates/skills/bridges/website/copilot-instructions.md +0 -11
package/README.en.md
CHANGED
|
@@ -25,9 +25,15 @@ Claude Code v2.1.277 and later can also read root `AGENTS.md` directly when no h
|
|
|
25
25
|
|
|
26
26
|
The CLI copies complete selected skill directories from `templates/skills/` into the generated project's `.agents/skills/`. `SKILL.md` defines boundaries and task navigation; `reference.md`/`guide.md` hold on-demand examples. Do not copy only the entry file. AGENTS.md holds application constraints and Claude/Copilot bridge files reference it. Template changes must sync relevant repository skills. Generation tests verify delivery of reference files.
|
|
27
27
|
|
|
28
|
+
Every application type includes `hai-spec-review` to review requirements and designs before generation: completeness, ambiguity, technical/framework correctness, and consistent naming. It reports located issues with concrete corrections and declares generation readiness only when issues are resolved and evidence is sufficient. `hai init` / `hai add` also backfill this workflow skill while preserving custom files.
|
|
29
|
+
|
|
30
|
+
After review, the separate `hai-spec-implement` skill handles implementation from documents. Every application includes it, and `hai init` / `hai add` backfill its complete resources. AI splits work by independently verifiable features and actual dependencies, using `docs/task-list.md` and `docs/tasks/<id>-<slug>.md` by default. Each task uses its own Git branch, TDD, quality gates and a local merge; records are marked complete after the actual merge commit and integration checks. Rework keeps the same task ID, file and branch, adding a new cycle linked to prior evidence. This uses Markdown, Git and existing development/test skills, with no new runtime dependency or workflow engine. Requests can plan only, implement a document, execute T003, or repair and merge T002. Planning does not start implementation; selected tasks require completed dependencies, and remote actions follow the user's authorization.
|
|
31
|
+
|
|
28
32
|
For everyday feature additions, changes and fixes, `AGENTS.md` routes to `hai-app-create/SKILL.md` and `development.md`. Map requirements to existing framework features, configuration and extension points before implementing against the installed package's exports and types. Reuse applicable capabilities and explain concrete gaps; do not install unrelated dependencies to increase module coverage. Codex uses `.agents/skills/` and the project root's persistent `AGENTS.md` rules.
|
|
29
33
|
|
|
30
|
-
Tool entry points share one set of rules and skills: Codex/Cursor use AGENTS and `.agents/skills/`; Copilot
|
|
34
|
+
Tool entry points share one set of rules and skills: Codex/Cursor use AGENTS and `.agents/skills/`; Copilot's `.github/copilot-instructions.md` only references the shared `AGENTS.md`, with application-specific rules maintained there; OpenCode's opencode.json references the shared rules directly through `instructions: ["AGENTS.md"]`. Claude Code's root CLAUDE.md contains only `@AGENTS.md`; task navigation in the shared rules leads to skill bodies and references in `.agents/skills/` as needed. The CLI does not create `.claude/`, duplicate skills or require symlinks. This setup does not register native Claude skills or `/skill` commands; existing Claude settings and skills are preserved. Sources: [Claude project instructions](https://code.claude.com/docs/en/memory), [Claude native skills](https://code.claude.com/docs/en/skills), [Copilot](https://docs.github.com/en/copilot/concepts/agents/about-agent-skills), [OpenCode](https://docs.opencode.ai/docs/skills/), [Cursor](https://cursor.com/docs/skills).
|
|
35
|
+
|
|
36
|
+
Codex discovers `.agents/skills/` natively and selects skills as needed. Invoke `$hai-app-create`, `$hai-app-review`, or another skill explicitly when useful; entry points and references remain on demand. No additional `.codex/skills` tree or Copilot settings are required. Sources: [Codex skills](https://learn.chatgpt.com/docs/build-skills), [AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md).
|
|
31
37
|
|
|
32
38
|
Generated projects share `eslint-rules.js`. Lint rejects explicit `any`, console calls, unexplained suppressions, double unknown assertions, internal framework source imports and writes to known sensitive localStorage keys. A necessary third-party workaround requires a documented local exception. Static rules do not prove authorization, input safety, transaction behavior or log redaction; verify those through tests and review.
|
|
33
39
|
|
|
@@ -56,6 +62,8 @@ In PowerShell, use `pnpm.cmd add -g @h-ai/cli`. To update an installed CLI to th
|
|
|
56
62
|
|
|
57
63
|
Generated `@h-ai/*` dependencies are pinned to the CLI version; pnpm references that exact version through `catalog:`. Upgrade framework packages together and verify the versions resolved in the lockfile.
|
|
58
64
|
|
|
65
|
+
In your application repository, ask the AI to "upgrade Hai-framework to the latest version". Project instructions route to [hai-framework-sync](templates/skills/hai-framework-sync/SKILL.md) to check published versions online, compare cumulative changes and application impact, request decisions or blocker resolution when needed, then migrate dependencies/code/configuration, merge skills and AI instructions, and validate. Comparison-only requests do not modify the application. `hai init` / `hai add` backfill the upgrade skill, adjacent resources and referenced CI/PR workflow skills even when the original template cannot be identified. Existing files are preserved; older skills and routing still need to be merged.
|
|
66
|
+
|
|
59
67
|
Creation messages are written directly to the terminal. Installation failures display the package manager command, exit code and stdout/stderr, and retain generated files for a retry from the project directory. The `prebuild-install@7.1.3` deprecation warning comes from the upstream `better-sqlite3` installer dependency. That warning alone does not fail installation; do not override or remove the native installer to hide it.
|
|
60
68
|
|
|
61
69
|
```bash
|
|
@@ -135,6 +143,8 @@ hai g:model order
|
|
|
135
143
|
|
|
136
144
|
## Fullstack mini administration
|
|
137
145
|
|
|
146
|
+
The default workspace includes `@h-ai/ui/guide` onboarding and help: first-use invitations, element tours, searchable instructions, manual replay and profile setup tours. Web/App/Desktop share content and translations; Web uses Cookies and native WebViews use localStorage, isolated by user and tour version. Extend the shared guide-store and data-guide anchors; see the [guide skill](templates/skills/hai-ui/guide.md).
|
|
147
|
+
|
|
138
148
|
`--type fullstack` generates an administration workspace with IAM, reldb, cache, audit, storage and crypto by default. The required management modules remain enabled even with the minimal preset. `--frontends` selects Web, Capacitor App and Tauri Desktop; miniapp remains a documentation placeholder excluded from runtime and builds.
|
|
139
149
|
|
|
140
150
|
```powershell
|
|
@@ -261,6 +271,10 @@ pnpm --filter @h-ai/cli test:watch
|
|
|
261
271
|
pnpm --filter @h-ai/cli test:coverage
|
|
262
272
|
```
|
|
263
273
|
|
|
274
|
+
Admin and fullstack gates also verify public types and runtime behavior from installed local tarballs: streams/checksums/create-only writes, API Key scopes/revocation, current authorization, batch users/role pagination, Reach templates and Audit metadata. Fullstack also verifies trusted peer IPs.
|
|
275
|
+
|
|
276
|
+
Successful screenshots default to the CLI's `test-results/scaffold-evidence/`. Set `HAI_AUTH_EVIDENCE_DIR` to retain them in a chosen directory after generated projects are cleaned up. Fullstack E2E starts every selected Web/App/Desktop browser preview and checks login, tours, help and profile navigation. Miniapp and native shells require separate platform acceptance.
|
|
277
|
+
|
|
264
278
|
## License
|
|
265
279
|
|
|
266
280
|
Apache-2.0
|
package/README.ja.md
CHANGED
|
@@ -25,9 +25,15 @@ Claude Code v2.1.277 以降は、優先されるプロジェクト CLAUDE ファ
|
|
|
25
25
|
|
|
26
26
|
CLI は選択した skill のディレクトリー全体を `templates/skills/` から生成先の `.agents/skills/` にコピーします。`SKILL.md` は機能の境界とタスク案内、`reference.md`/`guide.md` は必要時に読む例を提供します。入口だけをコピーしてはいけません。AGENTS.md にアプリの制約を置き、Claude/Copilot のブリッジから参照します。テンプレート変更は関連するリポジトリー skill と同期し、生成テストで参照ファイルの完全な提供を確認します。
|
|
27
27
|
|
|
28
|
+
すべてのアプリ種別に `hai-spec-review` を提供します。生成前に要件・設計の完全性、曖昧さ、技術・フレームワーク利用の正確性、命名の一貫性を厳密に確認し、箇所と具体的な修正案を報告します。問題が解決され、証拠が十分な場合のみ AI 生成に進めると判定します。`hai init` / `hai add` は既存のカスタムファイルを保持してこの skill も補完します。
|
|
29
|
+
|
|
30
|
+
審査後の文書からの実装は、独立した `hai-spec-implement` が担当します。全アプリに提供し、`hai init` / `hai add` でも関連リソース全体を補完します。AI は独立して検証できる機能と実際の依存関係に基づいて分割を判断し、既定では `docs/task-list.md` と `docs/tasks/<id>-<slug>.md` を使います。各タスクは専用 Git ブランチで TDD と品質チェックを行い、ローカルでマージして実際のコミットと統合検証を記録してから完了にします。修正時は元の番号・ファイル・ブランチを再利用し、以前の証拠に関連付けた新しい実施回を追加します。Markdown、Git、既存の開発・テスト skills を使い、新しいランタイム依存やワークフローエンジンは不要です。「文書からタスク一覧だけ作成」「文書から実装」「T003 を実行」「T002 を修正してマージ」のように指定できます。計画だけの依頼では実装せず、指定タスクは依存を確認し、リモート操作はユーザーの許可範囲に従います。
|
|
31
|
+
|
|
28
32
|
通常の機能追加・変更・修正では、`AGENTS.md` が `hai-app-create/SKILL.md` と `development.md` に案内します。要件を既存のフレームワーク機能・設定・拡張点に対応付け、インストール済みバージョンの exports と型を確認して実装します。適用できる機能を優先して再利用し、不足する能力を具体的に説明します。利用率のために無関係な依存を追加しません。Codex は `.agents/skills/` とプロジェクトルートの `AGENTS.md` を使用します。
|
|
29
33
|
|
|
30
|
-
各ツールの入口は一つの規則と skill を共有します。Codex/Cursor は AGENTS と `.agents/skills
|
|
34
|
+
各ツールの入口は一つの規則と skill を共有します。Codex/Cursor は AGENTS と `.agents/skills/` を使用します。Copilot の `.github/copilot-instructions.md` は共通の `AGENTS.md` のみを参照し、アプリ種別の規則もそこに集約します。OpenCode の opencode.json は `instructions: ["AGENTS.md"]` で共通規則を直接参照します。Claude Code のルート CLAUDE.md は `@AGENTS.md` のみを含み、共有規則のタスク案内から `.agents/skills/` の本文と参照ファイルを必要時に読みます。CLI は `.claude/` を生成せず、skill の複製やシンボリックリンクも不要です。この構成では Claude のネイティブ skill 自動検出や `/skill` コマンドは登録されません。既存の Claude 設定と skill は保持します。根拠:[Claude プロジェクト指針](https://code.claude.com/docs/en/memory)、[Claude ネイティブ skills](https://code.claude.com/docs/en/skills)、[Copilot](https://docs.github.com/en/copilot/concepts/agents/about-agent-skills)、[OpenCode](https://docs.opencode.ai/docs/skills/)、[Cursor](https://cursor.com/docs/skills)。
|
|
35
|
+
|
|
36
|
+
Codex は `.agents/skills/` を標準で検出し、タスクに応じて Skill を選びます。必要に応じて `$hai-app-create`、`$hai-app-review` などを明示的に呼び出せます。入口と参考ファイルは必要時に読みます。追加の `.codex/skills` や Copilot 設定は不要です。根拠:[Codex skills](https://learn.chatgpt.com/docs/build-skills)、[AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md)。
|
|
31
37
|
|
|
32
38
|
生成プロジェクトは `eslint-rules.js` を共有します。lint は明示的な `any`、console、説明のない抑制、unknown を介した二重アサーション、フレームワーク内部ソースの import、既知の機密 localStorage キーへの書き込みを拒否します。必要なサードパーティーの回避策は局所的な説明を付けます。権限分離・入力安全性・トランザクション・ログのマスキングは静的規則だけでは証明できないため、テストとレビューで確認します。
|
|
33
39
|
|
|
@@ -56,6 +62,8 @@ PowerShell では `pnpm.cmd add -g @h-ai/cli` を使用してください。同
|
|
|
56
62
|
|
|
57
63
|
生成する `@h-ai/*` 依存は CLI と同じバージョンに固定し、pnpm は `catalog:` からその完全なバージョンを参照します。更新時はフレームワークのパッケージをまとめて更新し、lockfile の実際の解決バージョンを確認してください。
|
|
58
64
|
|
|
65
|
+
アプリケーションのリポジトリーで AI に「Hai-framework を最新バージョンにアップグレードして」と伝えると、プロジェクトの指針から [hai-framework-sync](templates/skills/hai-framework-sync/SKILL.md) を読みます。公開バージョンをオンラインで確認し、累積差分とアプリへの影響を比較して、必要な選択や阻害要因の解消をユーザーに求めます。その後、依存・コード・設定を移行し、skills と AI 入口をマージして検証します。比較のみの依頼ではアプリを変更しません。`hai init` / `hai add` は元のテンプレートを特定できない旧プロジェクトにも、アップグレード skill、関連リソース、参照先の CI/PR skill を補完します。既存ファイルは保持されるため、旧版 skill と入口は別途マージしてください。
|
|
66
|
+
|
|
59
67
|
作成メッセージは端末へ直接出力します。依存のインストールが失敗した場合は、コマンド、終了コード、stdout/stderr を表示し、生成したファイルを残します。プロジェクト内でインストールを再実行できます。`prebuild-install@7.1.3` の非推奨警告は `better-sqlite3` の上流インストーラー依存によるものです。この警告だけではインストールは失敗しません。警告を隠すためにネイティブインストーラーを上書き・削除しないでください。
|
|
60
68
|
|
|
61
69
|
```bash
|
|
@@ -135,6 +143,8 @@ hai g:model order
|
|
|
135
143
|
|
|
136
144
|
## Fullstack mini 管理画面
|
|
137
145
|
|
|
146
|
+
既定の管理画面は `@h-ai/ui/guide` の初回案内、要素ガイド、検索付きヘルプ、再表示、個人設定ガイドを提供します。Web/App/Desktop は内容と翻訳を共有し、Web は Cookie、WebView は localStorage でユーザーとバージョンごとに状態を保存します。共有 guide-store と data-guide を拡張してください。[ガイド skill](templates/skills/hai-ui/guide.md)を参照してください。
|
|
147
|
+
|
|
138
148
|
`--type fullstack` は IAM、reldb、cache、audit、storage、crypto を含む管理 workspace を既定で生成します。minimal を選んでも管理に必要なモジュールは有効です。`--frontends` で Web、Capacitor App、Tauri Desktop を選択します。miniapp は説明用のプレースホルダーで、実行・ビルド対象には含まれません。
|
|
139
149
|
|
|
140
150
|
```powershell
|
|
@@ -261,6 +271,10 @@ pnpm --filter @h-ai/cli test:watch
|
|
|
261
271
|
pnpm --filter @h-ai/cli test:coverage
|
|
262
272
|
```
|
|
263
273
|
|
|
274
|
+
Admin/fullstack の門禁では実際にインストールしたローカル tarball の公開型と動作も検証します:ストリーム/checksum/上書き拒否、API Key scope/失効、現在の認可、ユーザー一括/ロールページ検索、Reach テンプレート、Audit ページ情報。fullstack は信頼できる接続元 IP も検証します。
|
|
275
|
+
|
|
276
|
+
成功時のスクリーンショットは CLI の `test-results/scaffold-evidence/` に保存します。`HAI_AUTH_EVIDENCE_DIR` で保存先を指定でき、生成プロジェクトの削除後も残ります。fullstack E2E は選択した全 Web/App/Desktop のブラウザープレビューでログイン、ガイド、ヘルプ、個人設定を検証します。小程序とネイティブシェルは各プラットフォームで別途検証します。
|
|
277
|
+
|
|
264
278
|
## License
|
|
265
279
|
|
|
266
280
|
Apache-2.0
|
package/README.md
CHANGED
|
@@ -23,9 +23,15 @@
|
|
|
23
23
|
|
|
24
24
|
CLI 从 `templates/skills/` 将所选 skill 的完整目录复制到生成项目 `.agents/skills/`。`SKILL.md` 提供能力边界和任务导航,`reference.md`/`guide.md` 保留按需范本;同步时不能只复制入口。AGENTS.md 保存应用约束,Claude/Copilot 桥接文件引用它;修改模板需同步相关仓库 skills。模板生成测试会核对参考文件的完整交付。
|
|
25
25
|
|
|
26
|
+
所有应用类型均交付 `hai-spec-review`:生成前严格检查需求/设计文档的完备性、歧义、技术及框架使用错误、命名一致性,给出带位置和修正建议的问题清单;问题解决且证据充分后才判定可以进入 AI 生成。`hai init` / `hai add` 同时为已有项目补齐该工作流 skill,保留自定义文件。
|
|
27
|
+
|
|
28
|
+
审查后的文档实施使用独立的 `hai-spec-implement`,同样交付到所有应用并由 `hai init` / `hai add` 补齐。AI 按可独立验收的功能和实际依赖决定是否拆分,默认写入 `docs/task-list.md` 与 `docs/tasks/<编号>-<slug>.md`;每项在独立 Git 分支走 TDD、门禁、本地合并,记录真实合并提交后更新清单。返修复用原任务编号、文件和分支,追加轮次并关联此前证据。流程复用 Markdown、Git 和已有开发/测试 skills,无新增运行依赖或工作流引擎。可以请求“只根据 docs/需求.md 拆分任务”“根据该文档生成代码”“执行 T003”或“T002 返修后合并”;仅规划时不实施,指定任务先核验依赖,远端操作依实际授权。
|
|
29
|
+
|
|
26
30
|
日常新增、修改、修复功能由 `AGENTS.md` 引导读取 `hai-app-create/SKILL.md` 与 `development.md`:先把需求映射到框架现成功能、配置和扩展点,再依据当前安装版本的 exports/类型实现。适用能力优先复用;能力不足时说明具体缺口,不为模块覆盖率安装无关依赖。Codex 使用 `.agents/skills/`,仍需遵循项目根 `AGENTS.md` 的常驻规则。
|
|
27
31
|
|
|
28
|
-
工具入口共享同一份规则与技能:Codex/Cursor 使用 AGENTS 与 `.agents/skills/`;Copilot
|
|
32
|
+
工具入口共享同一份规则与技能:Codex/Cursor 使用 AGENTS 与 `.agents/skills/`;Copilot 的 `.github/copilot-instructions.md` 只引用共享 `AGENTS.md`,不另保存各应用类型规则;OpenCode 的 opencode.json 通过 `instructions: ["AGENTS.md"]` 直接引用共享规则。Claude Code 的根 CLAUDE.md 仅包含 `@AGENTS.md`,通过共享规则的任务导航按需读取 `.agents/skills/` 正文和参考文件。CLI 不创建 `.claude/`,无需重复技能或符号链接。此模式不提供 Claude 原生技能自动发现或 `/skill` 命令;项目已有的 Claude 设置与技能保留。依据:[Claude 项目指引](https://code.claude.com/docs/en/memory)、[Claude 原生 skills](https://code.claude.com/docs/en/skills)、[Copilot](https://docs.github.com/en/copilot/concepts/agents/about-agent-skills)、[OpenCode](https://docs.opencode.ai/docs/skills/)、[Cursor](https://cursor.com/docs/skills)。
|
|
33
|
+
|
|
34
|
+
Codex 原生发现 `.agents/skills/` 并按任务自动选择,也可显式输入 `$hai-app-create`、`$hai-app-review` 等名称调用;入口和参考文件保持按需读取。无需额外 `.codex/skills` 或 Copilot 设置。依据:[Codex skills](https://learn.chatgpt.com/docs/build-skills)、[AGENTS.md](https://learn.chatgpt.com/docs/agent-configuration/agents-md)。
|
|
29
35
|
|
|
30
36
|
Claude Code v2.1.277 起也可直接读取根 `AGENTS.md`(没有更高优先级项目 CLAUDE 文件且相关内置插件启用时)。保留这一行导入可兼容旧版及未开启该能力的会话,官方说明导入不会重复加载规则;仍无须 `.claude/` 目录。参见 [AGENTS.md 支持](https://code.claude.com/docs/en/memory#agentsmd)。
|
|
31
37
|
|
|
@@ -56,6 +62,8 @@ PowerShell 中使用 `pnpm.cmd add -g @h-ai/cli`。已安装 CLI 时,执行相
|
|
|
56
62
|
|
|
57
63
|
生成项目的 `@h-ai/*` 依赖固定为 CLI 对应版本;pnpm 通过 `catalog:` 引用该精确版本。升级时统一更新框架包并验证 lockfile 中实际解析的版本。
|
|
58
64
|
|
|
65
|
+
在应用仓库对 AI 说“升级 Hai-framework 到最新版本”,项目入口会引导读取 [hai-framework-sync](templates/skills/hai-framework-sync/SKILL.md):在线确认发布版本、比较累计差异与应用影响,需要用户选择或处理阻塞时提示,随后迁移依赖/代码/配置、合并 skills 与 AI 入口并验证。仅要求比较时不会修改应用。`hai init` / `hai add` 为旧项目补齐升级 skill、相邻资源及引用的 CI/PR 流程技能,即使无法识别原模板也会交付;已有文件保留,旧版 skill 及入口仍须合并。
|
|
66
|
+
|
|
59
67
|
创建提示直接输出到终端;安装失败会显示包管理器命令、退出码和 stdout/stderr,已生成文件保留,可进入目录重试安装。`prebuild-install@7.1.3` 的弃用警告来自 `better-sqlite3` 的上游安装依赖,单独的警告不会令安装失败;不要为隐藏警告覆盖或删除原生安装器。
|
|
60
68
|
|
|
61
69
|
```bash
|
|
@@ -135,6 +143,8 @@ hai g:model order
|
|
|
135
143
|
|
|
136
144
|
## Fullstack mini 管理后台
|
|
137
145
|
|
|
146
|
+
默认管理界面启用 `@h-ai/ui/guide` 新手引导与帮助中心:首次邀请、页面逐步高亮、搜索使用说明、手动重看和个人设置导览。Web/App/Desktop 共用 guide-store 和业务翻译,Web 用 Cookie、原生 WebView 用 localStorage,按用户和引导版本记录。新增页面只需补共享内容与 data-guide 锚点,见 [引导 skill](templates/skills/hai-ui/guide.md)。
|
|
147
|
+
|
|
138
148
|
`--type fullstack` 默认生成包含 IAM、reldb、cache、audit、storage、crypto 的管理工程;即使选择 minimal,管理所需模块也会保留。`--frontends` 选择 Web、Capacitor App 和 Tauri Desktop;miniapp 仍是说明占位,不参与运行或构建。
|
|
139
149
|
|
|
140
150
|
```powershell
|
|
@@ -261,6 +271,10 @@ pnpm --filter @h-ai/cli test:watch
|
|
|
261
271
|
pnpm --filter @h-ai/cli test:coverage
|
|
262
272
|
```
|
|
263
273
|
|
|
274
|
+
Admin 与 fullstack 门禁还用实际安装的本地 tarball 验证公开类型和运行行为:流式文件/checksum/拒覆盖、API Key scope 与撤销、当前授权、批量用户/角色分页、Reach 模板路由和 Audit 分页元数据;fullstack 同时验证可信对端 IP。
|
|
275
|
+
|
|
276
|
+
成功截图默认保存在 CLI 的 `test-results/scaffold-evidence/`,可通过 `HAI_AUTH_EVIDENCE_DIR` 指定独立目录,生成项目清理后仍保留。fullstack E2E 启动所有已选 Web/App/Desktop 浏览器预览,并验证各端的登录、导览、帮助与个人设置;小程序和原生壳仍需要对应平台验收。
|
|
277
|
+
|
|
264
278
|
## License
|
|
265
279
|
|
|
266
280
|
Apache-2.0
|
|
@@ -117,9 +117,14 @@ var SKILL_EXCLUSIONS_BY_APP_TYPE = {
|
|
|
117
117
|
};
|
|
118
118
|
var WORKFLOW_SKILLS = [
|
|
119
119
|
"hai-build",
|
|
120
|
+
"hai-spec-review",
|
|
121
|
+
"hai-spec-implement",
|
|
120
122
|
"hai-app-create",
|
|
121
123
|
"hai-app-review",
|
|
122
|
-
"hai-app-tests"
|
|
124
|
+
"hai-app-tests",
|
|
125
|
+
"hai-framework-sync",
|
|
126
|
+
"hai-ci",
|
|
127
|
+
"hai-pr-review"
|
|
123
128
|
];
|
|
124
129
|
var PACKAGE_SKILL_MAP = {
|
|
125
130
|
"@h-ai/api-contract": "hai-api-contract",
|
|
@@ -369,5 +374,5 @@ async function generateProjectAiSupport(projectPath, skillNames, options = {}) {
|
|
|
369
374
|
}
|
|
370
375
|
|
|
371
376
|
export { cliM, generateModuleSkillFile, generateProjectAiSupport, generateSkillFiles, resolveCompatibleSkillNames, resolveSkillNamesForPackages };
|
|
372
|
-
//# sourceMappingURL=chunk-
|
|
373
|
-
//# sourceMappingURL=chunk-
|
|
377
|
+
//# sourceMappingURL=chunk-X3RSYNBG.js.map
|
|
378
|
+
//# sourceMappingURL=chunk-X3RSYNBG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../messages/en-US.json","../messages/zh-CN.json","../src/cli-i18n.ts","../src/commands/cli-skill-templates.ts"],"names":[],"mappings":";;;;;;;;AAAA,IAAA,aAAA,GAAA;AAAA,EACE,gBAAA,EAAoB,2BAAA;AAAA,EACpB,iBAAA,EAAqB,wCAAA;AAAA,EACrB,gBAAA,EAAoB,oBAAA;AAAA,EACpB,YAAA,EAAgB,mBAAA;AAAA,EAChB,UAAA,EAAc,kBAAA;AAAA,EACd,cAAA,EAAkB,uCAAA;AAAA,EAClB,mBAAA,EAAuB,+BAAA;AAAA,EACvB,kBAAA,EAAsB,kBAAA;AAAA,EACtB,mBAAA,EAAuB,0BAAA;AAAA,EACvB,uBAAA,EAA2B,sFAAA;AAAA,EAC3B,4BAAA,EAAgC,mFAAA;AAAA,EAChC,kBAAA,EAAsB,0DAAA;AAAA,EACtB,yBAAA,EAA6B,sDAAA;AAAA,EAC7B,2BAAA,EAA+B,wBAAA;AAAA,EAC/B,6BAAA,EAAiC,uCAAA;AAAA,EACjC,6BAAA,EAAiC,4BAAA;AAAA,EACjC,sBAAA,EAA0B,0BAAA;AAAA,EAC1B,yBAAA,EAA6B,iCAAA;AAAA,EAC7B,sBAAA,EAA0B,iDAAA;AAAA,EAC1B,wBAAA,EAA4B,sBAAA;AAAA,EAC5B,mBAAA,EAAuB,yBAAA;AAAA,EACvB,sBAAA,EAA0B,wBAAA;AAAA,EAC1B,kBAAA,EAAsB,gEAAA;AAAA,EACtB,eAAA,EAAmB,MAAA;AAAA,EACnB,uBAAA,EAA2B,+BAAA;AAAA,EAC3B,sBAAA,EAA0B,wBAAA;AAAA,EAC1B,sBAAA,EAA0B,2BAAA;AAAA,EAC1B,oBAAA,EAAwB,0BAAA;AAAA,EACxB,iBAAA,EAAqB,0BAAA;AAAA,EACrB,kBAAA,EAAsB,wBAAA;AAAA,EACtB,cAAA,EAAkB,cAAA;AAAA,EAClB,aAAA,EAAiB,YAAA;AAAA,EACjB,cAAA,EAAkB,gBAAA;AAAA,EAClB,yBAAA,EAA6B,uBAAA;AAAA,EAC7B,sBAAA,EAA0B;AAC5B,CAAA;;;ACpCA,IAAA,aAAA,GAAA;AAAA,EACE,gBAAA,EAAoB,uCAAA;AAAA,EACpB,iBAAA,EAAqB,4DAAA;AAAA,EACrB,gBAAA,EAAoB,yBAAA;AAAA,EACpB,YAAA,EAAgB,4BAAA;AAAA,EAChB,UAAA,EAAc,wBAAA;AAAA,EACd,cAAA,EAAkB,4DAAA;AAAA,EAClB,mBAAA,EAAuB,0DAAA;AAAA,EACvB,kBAAA,EAAsB,2BAAA;AAAA,EACtB,mBAAA,EAAuB,uCAAA;AAAA,EACvB,uBAAA,EAA2B,oKAAA;AAAA,EAC3B,4BAAA,EAAgC,wJAAA;AAAA,EAChC,kBAAA,EAAsB,+FAAA;AAAA,EACtB,yBAAA,EAA6B,6FAAA;AAAA,EAC7B,2BAAA,EAA+B,4CAAA;AAAA,EAC/B,6BAAA,EAAiC,qDAAA;AAAA,EACjC,6BAAA,EAAiC,+CAAA;AAAA,EACjC,sBAAA,EAA0B,wDAAA;AAAA,EAC1B,yBAAA,EAA6B,wDAAA;AAAA,EAC7B,sBAAA,EAA0B,8EAAA;AAAA,EAC1B,wBAAA,EAA4B,4CAAA;AAAA,EAC5B,mBAAA,EAAuB,4CAAA;AAAA,EACvB,sBAAA,EAA0B,yCAAA;AAAA,EAC1B,kBAAA,EAAsB,wGAAA;AAAA,EACtB,eAAA,EAAmB,QAAA;AAAA,EACnB,uBAAA,EAA2B,8DAAA;AAAA,EAC3B,sBAAA,EAA0B,+CAAA;AAAA,EAC1B,sBAAA,EAA0B,kDAAA;AAAA,EAC1B,oBAAA,EAAwB,4CAAA;AAAA,EACxB,iBAAA,EAAqB,yCAAA;AAAA,EACrB,kBAAA,EAAsB,gCAAA;AAAA,EACtB,cAAA,EAAkB,2BAAA;AAAA,EAClB,aAAA,EAAiB,0BAAA;AAAA,EACjB,cAAA,EAAkB,yCAAA;AAAA,EAClB,yBAAA,EAA6B,sCAAA;AAAA,EAC7B,sBAAA,EAA0B;AAC5B,CAAA;;;AC/BO,IAAM,IAAA,GAAO,KAAK,IAAA,CAAK,mBAAA,CAAuC,EAAE,OAAA,EAAS,aAAA,EAAM,OAAA,EAAS,aAAA,EAAM;;;ACYrG,IAAM,gBAAA,GAA2C;AAAA,EAC/C,IAAA,EAAM,WAAA;AAAA,EACN,OAAA,EAAS,WAAA;AAAA,EACT,OAAA,EAAS,WAAA;AAAA,EACT,KAAA,EAAO,SAAA;AAAA,EACP,SAAA,EAAW,aAAA;AAAA,EACX,IAAA,EAAM,QAAA;AAAA,EACN,QAAA,EAAU,YAAA;AAAA,EACV,SAAA,EAAW,aAAA;AAAA,EACX,OAAA,EAAS,WAAA;AAAA,EACT,UAAA,EAAY,cAAA;AAAA,EACZ,OAAA,EAAS,WAAA;AAAA,EACT,WAAA,EAAa,eAAA;AAAA,EACb,OAAA,EAAS,WAAA;AAAA,EACT,QAAA,EAAU,YAAA;AAAA,EACV,KAAA,EAAO,SAAA;AAAA,EACP,IAAA,EAAM,QAAA;AAAA,EACN,YAAA,EAAc,gBAAA;AAAA,EACd,WAAA,EAAa;AACf,CAAA;AAQA,IAAM,4BAAA,GAAmE;AAAA,EACvE,OAAA,EAAS,CAAC,UAAA,EAAY,kBAAA,EAAoB,kBAAkB,eAAe,CAAA;AAAA,EAC3E,SAAA,EAAW,CAAC,UAAA,EAAY,kBAAA,EAAoB,kBAAkB,eAAe,CAAA;AAAA,EAC7E,IAAA,EAAM,CAAC,UAAA,EAAY,kBAAA,EAAoB,kBAAkB,eAAe,CAAA;AAAA,EACxE,KAAA,EAAO,CAAC,QAAA,EAAU,SAAA,EAAW,eAAe,CAAA;AAAA,EAC5C,YAAA,EAAc,CAAC,UAAA,EAAY,SAAA,EAAW,YAAY,kBAAkB,CAAA;AAAA,EACpE,WAAA,EAAa,CAAC,SAAS;AACzB,CAAA;AAEA,IAAM,eAAA,GAAkB;AAAA,EACtB,WAAA;AAAA,EACA,iBAAA;AAAA,EACA,oBAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,eAAA;AAAA,EACA,oBAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,iBAAA,GAA4C;AAAA,EAChD,oBAAA,EAAsB,kBAAA;AAAA,EACtB,kBAAA,EAAoB,gBAAA;AAAA,EACpB,YAAA,EAAc,UAAA;AAAA,EACd,YAAA,EAAc,UAAA;AAAA,EACd,WAAA,EAAa,SAAA;AAAA,EACb,UAAA,EAAY,QAAA;AAAA,EACZ,aAAA,EAAe,WAAA;AAAA,EACf,aAAA,EAAe,WAAA;AAAA,EACf,WAAA,EAAa,SAAA;AAAA,EACb,eAAA,EAAiB,aAAA;AAAA,EACjB,UAAA,EAAY,QAAA;AAAA,EACZ,cAAA,EAAgB,YAAA;AAAA,EAChB,eAAA,EAAiB,aAAA;AAAA,EACjB,aAAA,EAAe,WAAA;AAAA,EACf,gBAAA,EAAkB,cAAA;AAAA,EAClB,aAAA,EAAe,WAAA;AAAA,EACf,iBAAA,EAAmB,eAAA;AAAA,EACnB,aAAA,EAAe,WAAA;AAAA,EACf,cAAA,EAAgB,YAAA;AAAA,EAChB,iBAAA,EAAmB;AACrB,CAAA;AAEA,IAAM,iBAAA,GAAoB,CAAC,gBAAgB,CAAA;AAE3C,IAAM,YAAA,GAAe;AAAA,EACnB;AAAA,IACE,MAAA,EAAQ,yBAAA;AAAA,IACR,WAAA,EAAa;AAAA,GACf;AAAA,EACA;AAAA,IACE,MAAA,EAAQ,WAAA;AAAA,IACR,WAAA,EAAa;AAAA,GACf;AAAA,EACA;AAAA,IACE,MAAA,EAAQ,WAAA;AAAA,IACR,WAAA,EAAa;AAAA,GACf;AAAA,EACA;AAAA,IACE,MAAA,EAAQ,eAAA;AAAA,IACR,WAAA,EAAa;AAAA;AAEjB,CAAA;AAEA,IAAM,oBAAA,GAAuB,cAAA;AAG7B,eAAe,oBAAoB,WAAA,EAA2E;AAC5G,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,cAAc,CAAA;AACzD,EAAA,IAAI,CAAE,MAAM,GAAA,CAAI,UAAA,CAAW,WAAW,CAAA,EAAI;AACxC,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,MAAM,GAAA,CAAI,QAAA,CAAS,WAAW,CAAA;AAAA,EAC3C,CAAA,CAAA,MACM;AACJ,IAAA,OAAO,EAAC;AAAA,EACV;AACA,EAAA,IAAI,CAAC,QAAA,IAAY,OAAO,QAAA,KAAa,QAAA,IAAY,EAAE,MAAA,IAAU,QAAA,CAAA,IACxD,OAAO,QAAA,CAAS,SAAS,QAAA,IAAY,CAAC,qBAAqB,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,EAAG;AACnF,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,cAAc,QAAA,CAAS,IAAA;AAC7B,EAAA,KAAA,MAAW,CAAC,OAAA,EAAS,SAAA,EAAW,QAAQ,CAAA,IAAK;AAAA,IAC3C,CAAC,WAAA,EAAa,UAAA,EAAY,CAAC,UAAA,EAAY,MAAA,EAAQ,QAAQ,CAAC,CAAA;AAAA,IACxD,CAAC,KAAA,EAAO,MAAA,EAAQ,CAAC,UAAA,EAAY,SAAS,CAAC;AAAA,GACzC,EAAY;AACV,IAAA,MAAM,YAAY,MAAM,OAAA,CAAQ,IAAI,QAAA,CAAS,GAAA,CAAI,YAAU,GAAA,CAAI,UAAA;AAAA,MAC7D,IAAA,CAAK,KAAK,WAAA,EAAa,SAAA,EAAW,GAAG,WAAW,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA,EAAI,cAAc;AAAA,KAC7E,CAAC,CAAA;AACF,IAAA,IAAI,SAAA,CAAU,KAAA,CAAM,OAAO,CAAA,EAAG;AAC5B,MAAA,OAAO,EAAE,SAAS,WAAA,EAAY;AAAA,IAChC;AAAA,EACF;AAEA,EAAA,IAAI,UAAA,IAAc,QAAA,IAAY,KAAA,CAAM,OAAA,CAAQ,QAAA,CAAS,QAAQ,CAAA,IAAK,QAAA,CAAS,QAAA,CAAS,QAAA,CAAS,KAAK,CAAA,EAAG;AACnG,IAAA,KAAA,MAAW,WAAW,CAAC,OAAA,EAAS,SAAA,EAAW,IAAA,EAAM,YAAY,CAAA,EAAY;AACvE,MAAA,IAAI,QAAA,CAAS,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA,EAAG;AACvC,QAAA,OAAO,EAAE,SAAS,WAAA,EAAY;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,EAAE,WAAA,EAAY;AACvB;AAEA,eAAe,uBAAuB,YAAA,EAAyC;AAC7E,EAAA,MAAM,OAAA,GAAU,MAAM,GAAA,CAAI,OAAA,CAAQ,cAAc,EAAE,aAAA,EAAe,MAAM,CAAA;AACvE,EAAA,MAAM,aAAuB,EAAC;AAE9B,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,IAAI,CAAC,MAAM,WAAA,EAAY,IAAK,CAAC,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,MAAM,CAAA,EAAG;AAC1D,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,gBAAgB,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,KAAA,CAAM,MAAM,UAAU,CAAA;AACpE,IAAA,IAAI,MAAM,GAAA,CAAI,UAAA,CAAW,aAAa,CAAA,EAAG;AACvC,MAAA,UAAA,CAAW,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,IAC5B;AAAA,EACF;AAEA,EAAA,OAAO,UAAA,CAAW,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,aAAA,CAAc,CAAC,CAAC,CAAA;AACrD;AAEO,SAAS,2BAAA,CACd,YACA,OAAA,EACU;AACV,EAAA,MAAM,cAAA,GAAiB,IAAI,GAAA,CAAI,OAAA,GAAU,4BAAA,CAA6B,OAAO,CAAA,IAAK,EAAC,GAAI,EAAE,CAAA;AACzF,EAAA,OAAO,WAAW,MAAA,CAAO,CAAA,SAAA,KAAa,CAAC,cAAA,CAAe,GAAA,CAAI,SAAS,CAAC,CAAA;AACtE;AASA,SAAS,oBAAA,GAA+B;AACtC,EAAA,MAAM,aAAa,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAC9D,EAAA,MAAM,WAAW,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY,IAAA,EAAM,aAAa,QAAQ,CAAA;AACrE,EAAA,IAAI,GAAA,CAAI,cAAA,CAAe,QAAQ,CAAA,EAAG;AAChC,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAK,OAAA,CAAQ,UAAA,EAAY,IAAA,EAAM,IAAA,EAAM,aAAa,QAAQ,CAAA;AACnE;AASA,eAAe,UACb,YAAA,EACA,SAAA,EACA,aACA,UAAA,GAAgC,iBAAA,EAChC,YAAY,IAAA,EACO;AACnB,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,SAAS,CAAA;AAE7C,EAAA,IAAI,CAAE,MAAM,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,EAAI;AAChC,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,MAAM,SAAA,GAAY,MAAM,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,EAAE,SAAA,EAAW,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,CAAA;AACjF,EAAA,MAAM,aAAA,GAAgB,UAAU,MAAA,CAAO,CAAA,QAAA,KAAY,SAAS,MAAA,EAAQ,EACjE,GAAA,CAAI,CAAA,QAAA,KAAY,KAAK,QAAA,CAAS,GAAA,EAAK,KAAK,IAAA,CAAK,QAAA,CAAS,YAAY,QAAA,CAAS,IAAI,CAAC,CAAC,CAAA;AAEpF,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,WAAW,SAAS,CAAA;AACxD,IAAA,MAAM,uBAAA,CAAwB,aAAa,IAAI,CAAA;AAC/C,IAAA,IAAI,CAAC,SAAA,EAAW;AAEd,MAAA,MAAM,eAAyB,EAAC;AAChC,MAAA,KAAA,MAAW,gBAAgB,aAAA,EAAe;AACxC,QAAA,IAAI,CAAE,MAAM,GAAA,CAAI,UAAA,CAAW,KAAK,IAAA,CAAK,IAAA,EAAM,YAAY,CAAC,CAAA,EAAI;AAC1D,UAAA,YAAA,CAAa,KAAK,YAAY,CAAA;AAAA,QAChC;AAAA,MACF;AACA,MAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAC7B,QAAA;AAAA,MACF;AACA,MAAA,KAAA,MAAW,YAAA,IAAgB,YAAA;AACzB,QAAA,MAAM,wBAAwB,WAAA,EAAa,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,YAAY,CAAC,CAAA;AAC1E,MAAA,MAAM,IAAI,IAAA,CAAK,GAAA,EAAK,MAAM,EAAE,SAAA,EAAW,OAAO,CAAA;AAC9C,MAAA,WAAA,CAAY,KAAK,GAAG,YAAA,CAAa,GAAA,CAAI,CAAA,YAAA,KAAgB,GAAG,SAAS,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAAI,aAAa,UAAA,CAAW,IAAA,CAAK,KAAK,GAAG,CAAC,EAAE,CAAC,CAAA;AAAA,IAC7H,CAAA,MACK;AACH,MAAA,KAAA,MAAW,YAAA,IAAgB,aAAA;AACzB,QAAA,MAAM,wBAAwB,WAAA,EAAa,IAAA,CAAK,IAAA,CAAK,IAAA,EAAM,YAAY,CAAC,CAAA;AAC1E,MAAA,MAAM,IAAI,IAAA,CAAK,GAAA,EAAK,MAAM,EAAE,SAAA,EAAW,MAAM,CAAA;AAC7C,MAAA,WAAA,CAAY,IAAA,CAAK,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,SAAS,CAAA,SAAA,CAAW,CAAA;AAAA,IACvD;AAAA,EACF;AAEA,EAAA,OAAO,WAAA;AACT;AAGA,eAAe,uBAAA,CAAwB,aAAqB,WAAA,EAAoC;AAC9F,EAAA,IAAI,QAAA,GAAW,WAAA;AACf,EAAA,OAAO,CAAE,MAAM,GAAA,CAAI,UAAA,CAAW,QAAQ,CAAA,EAAI;AACxC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,QAAQ,CAAA;AACpC,IAAA,IAAI,MAAA,KAAW,QAAA;AACb,MAAA,MAAM,IAAI,KAAA,CAAM,IAAA,CAAK,8BAA8B,CAAC,CAAA;AACtD,IAAA,QAAA,GAAW,MAAA;AAAA,EACb;AACA,EAAA,MAAM,gBAAA,GAAmB,IAAA,CAAK,QAAA,CAAS,MAAM,GAAA,CAAI,QAAA,CAAS,WAAW,CAAA,EAAG,MAAM,GAAA,CAAI,QAAA,CAAS,QAAQ,CAAC,CAAA;AACpG,EAAA,IAAI,gBAAA,KAAqB,IAAA,IAAQ,gBAAA,CAAiB,UAAA,CAAW,CAAA,EAAA,EAAK,IAAA,CAAK,GAAG,CAAA,CAAE,CAAA,IAAK,IAAA,CAAK,UAAA,CAAW,gBAAgB,CAAA;AAC/G,IAAA,MAAM,IAAI,KAAA,CAAM,IAAA,CAAK,8BAA8B,CAAC,CAAA;AACxD;AAEA,eAAe,WACb,YAAA,EACA,UAAA,EACA,aACA,UAAA,GAAgC,iBAAA,EAChC,YAAY,IAAA,EACO;AACnB,EAAA,MAAM,cAAwB,EAAC;AAE/B,EAAA,KAAA,MAAW,SAAA,IAAa,IAAI,GAAA,CAAI,UAAU,CAAA,EAAG;AAC3C,IAAA,WAAA,CAAY,IAAA,CAAK,GAAG,MAAM,SAAA,CAAU,cAAc,SAAA,EAAW,WAAA,EAAa,UAAA,EAAY,SAAS,CAAC,CAAA;AAAA,EAClG;AAEA,EAAA,OAAO,WAAA;AACT;AAQA,eAAe,gBACb,YAAA,EACA,WAAA,EACA,SAAA,GAAY,IAAA,EACZ,SACA,WAAA,EACmB;AACnB,EAAA,MAAM,cAAwB,EAAC;AAE/B,EAAA,KAAA,MAAW,QAAQ,YAAA,EAAc;AAC/B,IAAA,MAAM,GAAA,GAAM,MAAM,mBAAA,CAAoB,YAAA,EAAc,KAAK,MAAA,EAAQ,OAAA,EAAS,gBAAgB,MAAS,CAAA;AACnG,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,WAAA,EAAa,KAAK,WAAW,CAAA;AAEpD,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,SAAA,IAAa,MAAM,GAAA,CAAI,UAAA,CAAW,IAAI,CAAA,EAAG;AAC5C,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,uBAAA,CAAwB,aAAa,IAAI,CAAA;AAC/C,IAAA,MAAM,GAAA,CAAI,SAAA,CAAU,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAC,CAAA;AACtC,IAAA,IAAI,GAAA,CAAI,QAAA,CAAS,MAAM,CAAA,EAAG;AACxB,MAAA,MAAM,QAAA,GAAW,MAAM,GAAA,CAAI,QAAA,CAAS,KAAK,MAAM,CAAA;AAC/C,MAAA,MAAM,QAAA,GAAW,UAAA,CAAW,OAAA,CAAQ,QAAA,EAAU,EAAE,QAAA,EAAU,IAAA,EAAM,CAAA,CAAE,EAAE,WAAA,EAAa,CAAA;AACjF,MAAA,MAAM,GAAA,CAAI,SAAA,CAAU,IAAA,EAAM,QAAA,EAAU,MAAM,CAAA;AAAA,IAC5C,CAAA,MACK;AACH,MAAA,MAAM,IAAI,IAAA,CAAK,GAAA,EAAK,IAAA,EAAM,EAAE,WAAW,CAAA;AAAA,IACzC;AACA,IAAA,WAAA,CAAY,IAAA,CAAK,KAAK,WAAW,CAAA;AAAA,EACnC;AAEA,EAAA,OAAO,WAAA;AACT;AAEA,eAAe,mBAAA,CACb,YAAA,EACA,MAAA,EACA,OAAA,EACA,gBAAgB,KAAA,EACQ;AACxB,EAAA,MAAM,UAAU,OAAA,IAAW,oBAAA,CAAqB,IAAA,CAAK,OAAO,IAAI,OAAA,GAAU,SAAA;AAC1E,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,GAAI,aAAA,GAAgB,CAAC,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,SAAA,EAAW,OAAA,EAAS,CAAA,EAAG,MAAM,CAAA,IAAA,CAAM,CAAC,IAAI,EAAC;AAAA,IACtF,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,SAAA,EAAW,SAAS,MAAM,CAAA;AAAA,IAClD,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,SAAA,EAAW,WAAW,MAAM,CAAA;AAAA,IACpD,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,MAAM;AAAA,GAChC;AAEA,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,IAAI,MAAM,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACnC,MAAA,OAAO,SAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAWA,eAAsB,kBAAA,CACpB,WAAA,EACA,SAAA,EACA,OAAA,EACA,WAAA,EACmB;AACnB,EAAA,MAAM,eAAe,oBAAA,EAAqB;AAE1C,EAAA,IAAI,CAAE,MAAM,GAAA,CAAI,UAAA,CAAW,YAAY,CAAA,EAAI;AACzC,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,cAAwB,EAAC;AAE/B,EAAA,MAAM,kBAAA,GAAqB,MAAM,sBAAA,CAAuB,YAAY,CAAA;AACpE,EAAA,MAAM,oBAAA,GAAuB,2BAAA,CAA4B,kBAAA,EAAoB,OAA8B,CAAA;AAE3G,EAAA,WAAA,CAAY,KAAK,GAAG,MAAM,WAAW,YAAA,EAAc,oBAAA,EAAsB,WAAW,CAAC,CAAA;AAGrF,EAAA,WAAA,CAAY,IAAA,CAAK,GAAG,MAAM,eAAA,CAAgB,cAAc,WAAA,EAAa,IAAA,EAAM,OAAA,EAAS,WAAW,CAAC,CAAA;AAEhG,EAAA,OAAO,WAAA;AACT;AAWA,eAAsB,uBAAA,CACpB,aACA,QAAA,EAC0B;AAC1B,EAAA,MAAM,SAAA,GAAY,iBAAiB,QAAQ,CAAA;AAC3C,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,cAAc,MAAM,wBAAA,CAAyB,WAAA,EAAa,CAAC,SAAS,CAAA,EAAG;AAAA,IAC3E,eAAA,EAAiB,KAAA;AAAA,IACjB,oBAAA,EAAsB;AAAA,GACvB,CAAA;AACD,EAAA,OAAO,WAAA,CAAY,MAAA,GAAS,CAAA,GAAI,WAAA,GAAc,IAAA;AAChD;AAEO,SAAS,6BAA6B,YAAA,EAAkC;AAC7E,EAAA,MAAM,UAAA,GAAa,CAAC,GAAG,eAAe,CAAA;AAEtC,EAAA,KAAA,MAAW,eAAe,YAAA,EAAc;AACtC,IAAA,MAAM,SAAA,GAAY,kBAAkB,WAAW,CAAA;AAC/C,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,UAAA,CAAW,KAAK,SAAS,CAAA;AAAA,IAC3B;AAAA,EACF;AAEA,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,UAAU,CAAC,CAAA;AAChC;AAEA,eAAsB,wBAAA,CACpB,WAAA,EACA,UAAA,EACA,OAAA,GAKI,EAAC,EACc;AACnB,EAAA,MAAM,eAAe,oBAAA,EAAqB;AAE1C,EAAA,IAAI,CAAE,MAAM,GAAA,CAAI,UAAA,CAAW,YAAY,CAAA,EAAI;AACzC,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM;AAAA,IACJ,eAAA,GAAkB,IAAA;AAAA,IAClB,oBAAA,GAAuB;AAAA,GACzB,GAAI,OAAA;AAEJ,EAAA,MAAM,QAAA,GAAW,MAAM,mBAAA,CAAoB,WAAW,CAAA;AACtD,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,QAAA,CAAS,OAAA;AAC5C,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,WAAA,IAAe,QAAA,CAAS,WAAA;AAEpD,EAAA,MAAM,kBAAA,GAAqB,UACvB,CAAC,GAAG,4BAA4B,MAAM,sBAAA,CAAuB,YAAY,CAAA,EAAG,OAAkB,GAAG,GAAG,eAAA,EAAiB,GAAG,UAAU,CAAA,GAClI,CAAC,GAAG,eAAA,EAAiB,GAAG,UAAU,CAAA;AACtC,EAAA,MAAM,cAAwB,EAAC;AAC/B,EAAA,WAAA,CAAY,IAAA,CAAK,GAAG,MAAM,UAAA,CAAW,cAAc,kBAAA,EAAoB,WAAA,EAAa,iBAAA,EAAmB,eAAe,CAAC,CAAA;AACvH,EAAA,WAAA,CAAY,IAAA,CAAK,GAAG,MAAM,eAAA,CAAgB,cAAc,WAAA,EAAa,oBAAA,EAAsB,OAAA,EAAS,WAAW,CAAC,CAAA;AAEhH,EAAA,OAAO,WAAA;AACT","file":"chunk-X3RSYNBG.js","sourcesContent":["{\n \"cli_createFailed\": \"Failed to create project:\",\n \"cli_installFailed\": \"Dependency installation failed ({pm}).\",\n \"cli_commandLabel\": \"Command: {command}\",\n \"cli_exitCode\": \"Exit code: {code}\",\n \"cli_signal\": \"Signal: {signal}\",\n \"cli_selectHint\": \"- ↑/↓ select, Enter confirm\",\n \"cli_multiselectHint\": \"- Space select, Enter confirm\",\n \"cli_featuresPrompt\": \"Select features:\",\n \"cli_frontendsPrompt\": \"Select frontend targets:\",\n \"cli_invalidGenerateName\": \"Use a name starting with a letter, with only letters, digits, hyphens or underscores\",\n \"cli_generateOutsideWorkspace\": \"Generated files must remain inside the workspace, including symbolic link targets\",\n \"cli_generateExists\": \"File already exists: {path}. Use --force to overwrite it\",\n \"cli_deploy_module_missing\": \"Deploy module not found. Install @h-ai/deploy first:\",\n \"cli_deploy_load_credentials\": \"Loading credentials...\",\n \"cli_deploy_credentials_failed\": \"Failed to load credentials: {message}\",\n \"cli_deploy_credentials_loaded\": \"Loaded {count} credentials\",\n \"cli_deploy_load_config\": \"Loading deploy config...\",\n \"cli_deploy_config_missing\": \"Deploy config not found: {path}\",\n \"cli_deploy_config_hint\": \"Run: hai add deploy to generate config template\",\n \"cli_deploy_config_loaded\": \"Deploy config loaded\",\n \"cli_deploy_scanning\": \"Scanning application...\",\n \"cli_deploy_scan_failed\": \"Scan failed: {message}\",\n \"cli_deploy_scanned\": \"Scanned: {name} (SvelteKit: {sveltekit}, Services: {services})\",\n \"cli_deploy_none\": \"none\",\n \"cli_deploy_initializing\": \"Initializing deploy module...\",\n \"cli_deploy_init_failed\": \"Init failed: {message}\",\n \"cli_deploy_initialized\": \"Deploy module initialized\",\n \"cli_deploy_deploying\": \"Deploying application...\",\n \"cli_deploy_failed\": \"Deploy failed: {message}\",\n \"cli_deploy_success\": \"Deployment successful!\",\n \"cli_deploy_url\": \" URL: {url}\",\n \"cli_deploy_id\": \" ID: {id}\",\n \"cli_deploy_env\": \" Env: {names}\",\n \"cli_deploy_command_failed\": \"Deploy command failed\",\n \"cli_adminPasswordSaved\": \" Administrator: admin; the random initial password is saved as HAI_ADMIN_DEFAULT_PASSWORD in .env\"\n}\n","{\n \"cli_createFailed\": \"创建项目失败:\",\n \"cli_installFailed\": \"安装依赖失败({pm})。\",\n \"cli_commandLabel\": \"命令: {command}\",\n \"cli_exitCode\": \"退出码: {code}\",\n \"cli_signal\": \"信号: {signal}\",\n \"cli_selectHint\": \"- ↑/↓ 选择,回车确认\",\n \"cli_multiselectHint\": \"- 空格选择,回车确认\",\n \"cli_featuresPrompt\": \"选择功能:\",\n \"cli_frontendsPrompt\": \"选择前端目标:\",\n \"cli_invalidGenerateName\": \"名称必须以字母开头,且仅包含字母、数字、短横线或下划线\",\n \"cli_generateOutsideWorkspace\": \"生成文件必须位于工作目录内,符号链接目标也不得越界\",\n \"cli_generateExists\": \"文件已存在:{path}。使用 --force 才可覆盖\",\n \"cli_deploy_module_missing\": \"未找到部署模块,请先安装 @h-ai/deploy:\",\n \"cli_deploy_load_credentials\": \"正在加载凭证…\",\n \"cli_deploy_credentials_failed\": \"加载凭证失败:{message}\",\n \"cli_deploy_credentials_loaded\": \"已加载 {count} 项凭证\",\n \"cli_deploy_load_config\": \"正在加载部署配置…\",\n \"cli_deploy_config_missing\": \"未找到部署配置:{path}\",\n \"cli_deploy_config_hint\": \"运行 hai add deploy 生成部署配置模板\",\n \"cli_deploy_config_loaded\": \"部署配置已加载\",\n \"cli_deploy_scanning\": \"正在扫描应用…\",\n \"cli_deploy_scan_failed\": \"扫描失败:{message}\",\n \"cli_deploy_scanned\": \"已扫描:{name}(SvelteKit:{sveltekit},服务:{services})\",\n \"cli_deploy_none\": \"无\",\n \"cli_deploy_initializing\": \"正在初始化部署模块…\",\n \"cli_deploy_init_failed\": \"初始化失败:{message}\",\n \"cli_deploy_initialized\": \"部署模块已初始化\",\n \"cli_deploy_deploying\": \"正在部署应用…\",\n \"cli_deploy_failed\": \"部署失败:{message}\",\n \"cli_deploy_success\": \"部署成功!\",\n \"cli_deploy_url\": \" 地址:{url}\",\n \"cli_deploy_id\": \" 标识:{id}\",\n \"cli_deploy_env\": \" 环境变量:{names}\",\n \"cli_deploy_command_failed\": \"部署命令失败\",\n \"cli_adminPasswordSaved\": \" 管理员:admin;随机初始密码已保存到 .env 的 HAI_ADMIN_DEFAULT_PASSWORD\"\n}\n","/** CLI 用户可见消息;通过 core 的全局 locale 选择语言。 */\nimport { core } from '@h-ai/core'\nimport enUS from '../messages/en-US.json'\nimport zhCN from '../messages/zh-CN.json'\n\nexport const cliM = core.i18n.createMessageGetter<keyof typeof zhCN>({ 'en-US': enUS, 'zh-CN': zhCN })\n","/**\n * @h-ai/cli — Skill 模板生成\n *\n * 将 Skill 模板文件复制到用户项目中,供 AI 编程助手使用。\n * @module cli-skill-templates\n */\n\nimport type { AppType } from '../cli-types.js'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport fse from 'fs-extra'\nimport Handlebars from 'handlebars'\nimport { cliM } from '../cli-i18n.js'\n\n/**\n * 模块名到 Skill 目录名的映射\n */\nconst MODULE_SKILL_MAP: Record<string, string> = {\n 'db': 'hai-reldb',\n 'reldb': 'hai-reldb',\n 'cache': 'hai-cache',\n 'iam': 'hai-iam',\n 'storage': 'hai-storage',\n 'ai': 'hai-ai',\n 'crypto': 'hai-crypto',\n 'payment': 'hai-payment',\n 'vecdb': 'hai-vecdb',\n 'datapipe': 'hai-datapipe',\n 'reach': 'hai-reach',\n 'scheduler': 'hai-scheduler',\n 'audit': 'hai-audit',\n 'deploy': 'hai-deploy',\n 'kit': 'hai-kit',\n 'ui': 'hai-ui',\n 'api-client': 'hai-api-client',\n 'capacitor': 'hai-capacitor',\n}\n\n/**\n * 各 appType 互斥的 Skill。\n *\n * 生成样板工程时,默认复制 templates/skills 下所有 hai-* Skill,\n * 仅排除与当前样板技术栈明显冲突的少数 Skill。\n */\nconst SKILL_EXCLUSIONS_BY_APP_TYPE: Partial<Record<AppType, string[]>> = {\n 'admin': ['hai-serv', 'hai-api-contract', 'hai-api-client', 'hai-capacitor'],\n 'website': ['hai-serv', 'hai-api-contract', 'hai-api-client', 'hai-capacitor'],\n 'h5': ['hai-serv', 'hai-api-contract', 'hai-api-client', 'hai-capacitor'],\n 'api': ['hai-ui', 'hai-kit', 'hai-capacitor'],\n 'mobile-app': ['hai-core', 'hai-kit', 'hai-serv', 'hai-api-contract'],\n 'fullstack': ['hai-kit'],\n}\n\nconst WORKFLOW_SKILLS = [\n 'hai-build',\n 'hai-spec-review',\n 'hai-spec-implement',\n 'hai-app-create',\n 'hai-app-review',\n 'hai-app-tests',\n 'hai-framework-sync',\n 'hai-ci',\n 'hai-pr-review',\n]\n\nconst PACKAGE_SKILL_MAP: Record<string, string> = {\n '@h-ai/api-contract': 'hai-api-contract',\n '@h-ai/api-client': 'hai-api-client',\n '@h-ai/core': 'hai-core',\n '@h-ai/serv': 'hai-serv',\n '@h-ai/kit': 'hai-kit',\n '@h-ai/ui': 'hai-ui',\n '@h-ai/reldb': 'hai-reldb',\n '@h-ai/cache': 'hai-cache',\n '@h-ai/iam': 'hai-iam',\n '@h-ai/storage': 'hai-storage',\n '@h-ai/ai': 'hai-ai',\n '@h-ai/crypto': 'hai-crypto',\n '@h-ai/payment': 'hai-payment',\n '@h-ai/vecdb': 'hai-vecdb',\n '@h-ai/datapipe': 'hai-datapipe',\n '@h-ai/reach': 'hai-reach',\n '@h-ai/scheduler': 'hai-scheduler',\n '@h-ai/audit': 'hai-audit',\n '@h-ai/deploy': 'hai-deploy',\n '@h-ai/capacitor': 'hai-capacitor',\n}\n\nconst SKILL_TARGET_DIRS = ['.agents/skills'] as const\n\nconst BRIDGE_FILES = [\n {\n source: 'copilot-instructions.md',\n destination: '.github/copilot-instructions.md',\n },\n {\n source: 'CLAUDE.md',\n destination: 'CLAUDE.md',\n },\n {\n source: 'AGENTS.md',\n destination: 'AGENTS.md',\n },\n {\n source: 'opencode.json',\n destination: 'opencode.json',\n },\n] as const\n\nconst BRIDGE_PROFILE_REGEX = /^[a-z0-9-]+$/\n\n/** 从已有模板标识与实际包布局确认桥接类型,不按项目名称猜测技术栈。 */\nasync function detectBridgeContext(projectPath: string): Promise<{ appType?: AppType, projectName?: string }> {\n const packagePath = path.join(projectPath, 'package.json')\n if (!(await fse.pathExists(packagePath))) {\n return {}\n }\n\n let metadata: unknown\n try {\n metadata = await fse.readJson(packagePath)\n }\n catch {\n return {}\n }\n if (!metadata || typeof metadata !== 'object' || !('name' in metadata)\n || typeof metadata.name !== 'string' || !BRIDGE_PROFILE_REGEX.test(metadata.name)) {\n return {}\n }\n\n const projectName = metadata.name\n for (const [appType, directory, suffixes] of [\n ['fullstack', 'packages', ['contract', 'serv', 'shared']],\n ['api', 'apps', ['contract', 'service']],\n ] as const) {\n const manifests = await Promise.all(suffixes.map(suffix => fse.pathExists(\n path.join(projectPath, directory, `${projectName}-${suffix}`, 'package.json'),\n )))\n if (manifests.every(Boolean)) {\n return { appType, projectName }\n }\n }\n\n if ('keywords' in metadata && Array.isArray(metadata.keywords) && metadata.keywords.includes('hai')) {\n for (const appType of ['admin', 'website', 'h5', 'mobile-app'] as const) {\n if (metadata.keywords.includes(appType)) {\n return { appType, projectName }\n }\n }\n }\n return { projectName }\n}\n\nasync function listTemplateSkillNames(templatesDir: string): Promise<string[]> {\n const entries = await fse.readdir(templatesDir, { withFileTypes: true })\n const skillNames: string[] = []\n\n for (const entry of entries) {\n if (!entry.isDirectory() || !entry.name.startsWith('hai-')) {\n continue\n }\n\n const skillFilePath = path.join(templatesDir, entry.name, 'SKILL.md')\n if (await fse.pathExists(skillFilePath)) {\n skillNames.push(entry.name)\n }\n }\n\n return skillNames.sort((a, b) => a.localeCompare(b))\n}\n\nexport function resolveCompatibleSkillNames(\n skillNames: string[],\n appType?: AppType,\n): string[] {\n const excludedSkills = new Set(appType ? SKILL_EXCLUSIONS_BY_APP_TYPE[appType] ?? [] : [])\n return skillNames.filter(skillName => !excludedSkills.has(skillName))\n}\n\n/**\n * 获取 templates/skills/ 目录的绝对路径\n *\n * 兼容两种运行环境:\n * - 构建后:dist/cli-skill-templates.js → ../templates/skills\n * - 测试时:src/commands/cli-skill-templates.ts → ../../templates/skills\n */\nfunction getSkillTemplatesDir(): string {\n const currentDir = path.dirname(fileURLToPath(import.meta.url))\n const distPath = path.resolve(currentDir, '..', 'templates', 'skills')\n if (fse.pathExistsSync(distPath)) {\n return distPath\n }\n return path.resolve(currentDir, '..', '..', 'templates', 'skills')\n}\n\n/**\n * 复制单个 Skill 目录到项目\n *\n * @param templatesDir - Skill 模板根目录\n * @param skillName - Skill 目录名(如 'hai-reldb')\n * @param projectPath - 用户项目根目录\n */\nasync function copySkill(\n templatesDir: string,\n skillName: string,\n projectPath: string,\n targetDirs: readonly string[] = SKILL_TARGET_DIRS,\n overwrite = true,\n): Promise<string[]> {\n const src = path.join(templatesDir, skillName)\n\n if (!(await fse.pathExists(src))) {\n return []\n }\n\n const copiedFiles: string[] = []\n const resources = await fse.readdir(src, { recursive: true, withFileTypes: true })\n const relativeFiles = resources.filter(resource => resource.isFile())\n .map(resource => path.relative(src, path.join(resource.parentPath, resource.name)))\n\n for (const targetDir of targetDirs) {\n const dest = path.join(projectPath, targetDir, skillName)\n await assertProjectOutputPath(projectPath, dest)\n if (!overwrite) {\n // 已有入口不能使新参考资源被跳过;逐文件补缺,同时保留用户修改。\n const missingFiles: string[] = []\n for (const relativeFile of relativeFiles) {\n if (!(await fse.pathExists(path.join(dest, relativeFile)))) {\n missingFiles.push(relativeFile)\n }\n }\n if (missingFiles.length === 0) {\n continue\n }\n for (const relativeFile of missingFiles)\n await assertProjectOutputPath(projectPath, path.join(dest, relativeFile))\n await fse.copy(src, dest, { overwrite: false })\n copiedFiles.push(...missingFiles.map(relativeFile => `${targetDir}/${skillName}/${relativeFile.replaceAll(path.sep, '/')}`))\n }\n else {\n for (const relativeFile of relativeFiles)\n await assertProjectOutputPath(projectPath, path.join(dest, relativeFile))\n await fse.copy(src, dest, { overwrite: true })\n copiedFiles.push(`${targetDir}/${skillName}/SKILL.md`)\n }\n }\n\n return copiedFiles\n}\n\n/** 写入前解析已有目录/文件链接,所有 AI 输出均限制在当前项目内。 */\nasync function assertProjectOutputPath(projectPath: string, destination: string): Promise<void> {\n let ancestor = destination\n while (!(await fse.pathExists(ancestor))) {\n const parent = path.dirname(ancestor)\n if (parent === ancestor)\n throw new Error(cliM('cli_generateOutsideWorkspace'))\n ancestor = parent\n }\n const relativeAncestor = path.relative(await fse.realpath(projectPath), await fse.realpath(ancestor))\n if (relativeAncestor === '..' || relativeAncestor.startsWith(`..${path.sep}`) || path.isAbsolute(relativeAncestor))\n throw new Error(cliM('cli_generateOutsideWorkspace'))\n}\n\nasync function copySkills(\n templatesDir: string,\n skillNames: string[],\n projectPath: string,\n targetDirs: readonly string[] = SKILL_TARGET_DIRS,\n overwrite = true,\n): Promise<string[]> {\n const copiedFiles: string[] = []\n\n for (const skillName of new Set(skillNames)) {\n copiedFiles.push(...await copySkill(templatesDir, skillName, projectPath, targetDirs, overwrite))\n }\n\n return copiedFiles\n}\n\n/**\n * 复制桥接文件到项目\n *\n * @param templatesDir - Skill 模板根目录\n * @param projectPath - 用户项目根目录\n */\nasync function copyBridgeFiles(\n templatesDir: string,\n projectPath: string,\n overwrite = true,\n appType?: string,\n projectName?: string,\n): Promise<string[]> {\n const copiedFiles: string[] = []\n\n for (const file of BRIDGE_FILES) {\n const src = await resolveBridgeSource(templatesDir, file.source, appType, projectName !== undefined)\n const dest = path.join(projectPath, file.destination)\n\n if (!src) {\n continue\n }\n\n if (!overwrite && await fse.pathExists(dest)) {\n continue\n }\n\n await assertProjectOutputPath(projectPath, dest)\n await fse.ensureDir(path.dirname(dest))\n if (src.endsWith('.hbs')) {\n const template = await fse.readFile(src, 'utf8')\n const rendered = Handlebars.compile(template, { noEscape: true })({ projectName })\n await fse.writeFile(dest, rendered, 'utf8')\n }\n else {\n await fse.copy(src, dest, { overwrite })\n }\n copiedFiles.push(file.destination)\n }\n\n return copiedFiles\n}\n\nasync function resolveBridgeSource(\n templatesDir: string,\n source: string,\n appType?: string,\n allowTemplate = false,\n): Promise<string | null> {\n const profile = appType && BRIDGE_PROFILE_REGEX.test(appType) ? appType : 'generic'\n const candidates = [\n ...(allowTemplate ? [path.join(templatesDir, 'bridges', profile, `${source}.hbs`)] : []),\n path.join(templatesDir, 'bridges', profile, source),\n path.join(templatesDir, 'bridges', 'generic', source),\n path.join(templatesDir, source),\n ]\n\n for (const candidate of candidates) {\n if (await fse.pathExists(candidate)) {\n return candidate\n }\n }\n\n return null\n}\n\n/**\n * 为新项目生成完整的 Skill 文件。\n *\n * 默认复制 templates/skills 下所有 hai-* Skill,再按 appType 排除互斥项。\n *\n * @param projectPath - 用户项目根目录\n * @param _features - 预留参数;保留签名兼容 createProject 调用方\n * @param appType - 应用类型(api 类型不复制 UI Skill)\n */\nexport async function generateSkillFiles(\n projectPath: string,\n _features: string[],\n appType?: string,\n projectName?: string,\n): Promise<string[]> {\n const templatesDir = getSkillTemplatesDir()\n\n if (!(await fse.pathExists(templatesDir))) {\n return []\n }\n\n const copiedFiles: string[] = []\n\n const templateSkillNames = await listTemplateSkillNames(templatesDir)\n const compatibleSkillNames = resolveCompatibleSkillNames(templateSkillNames, appType as AppType | undefined)\n\n copiedFiles.push(...await copySkills(templatesDir, compatibleSkillNames, projectPath))\n\n // 复制桥接文件\n copiedFiles.push(...await copyBridgeFiles(templatesDir, projectPath, true, appType, projectName))\n\n return copiedFiles\n}\n\n/**\n * 为已有项目添加单个模块的 Skill 文件\n *\n * 同时补全普通开发所需工作流及缺失参考资源,保留已有文件。\n *\n * @param projectPath - 用户项目根目录\n * @param moduleId - 模块标识(如 'db'、'iam')\n * @returns 复制的文件路径,若模块无对应 Skill 则返回 null\n */\nexport async function generateModuleSkillFile(\n projectPath: string,\n moduleId: string,\n): Promise<string[] | null> {\n const skillName = MODULE_SKILL_MAP[moduleId]\n if (!skillName) {\n return null\n }\n\n const copiedFiles = await generateProjectAiSupport(projectPath, [skillName], {\n overwriteSkills: false,\n overwriteBridgeFiles: false,\n })\n return copiedFiles.length > 0 ? copiedFiles : null\n}\n\nexport function resolveSkillNamesForPackages(packageNames: string[]): string[] {\n const skillNames = [...WORKFLOW_SKILLS]\n\n for (const packageName of packageNames) {\n const skillName = PACKAGE_SKILL_MAP[packageName]\n if (skillName) {\n skillNames.push(skillName)\n }\n }\n\n return [...new Set(skillNames)]\n}\n\nexport async function generateProjectAiSupport(\n projectPath: string,\n skillNames: string[],\n options: {\n overwriteSkills?: boolean\n overwriteBridgeFiles?: boolean\n appType?: string\n projectName?: string\n } = {},\n): Promise<string[]> {\n const templatesDir = getSkillTemplatesDir()\n\n if (!(await fse.pathExists(templatesDir))) {\n return []\n }\n\n const {\n overwriteSkills = true,\n overwriteBridgeFiles = true,\n } = options\n\n const detected = await detectBridgeContext(projectPath)\n const appType = options.appType ?? detected.appType\n const projectName = options.projectName ?? detected.projectName\n // 已确认的样板补全整个兼容目录;其它项目只补工作流与明确请求的模块。\n const selectedSkillNames = appType\n ? [...resolveCompatibleSkillNames(await listTemplateSkillNames(templatesDir), appType as AppType), ...WORKFLOW_SKILLS, ...skillNames]\n : [...WORKFLOW_SKILLS, ...skillNames]\n const copiedFiles: string[] = []\n copiedFiles.push(...await copySkills(templatesDir, selectedSkillNames, projectPath, SKILL_TARGET_DIRS, overwriteSkills))\n copiedFiles.push(...await copyBridgeFiles(templatesDir, projectPath, overwriteBridgeFiles, appType, projectName))\n\n return copiedFiles\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export { generateModuleSkillFile, generateProjectAiSupport, generateSkillFiles, resolveCompatibleSkillNames, resolveSkillNamesForPackages } from './chunk-
|
|
2
|
+
export { generateModuleSkillFile, generateProjectAiSupport, generateSkillFiles, resolveCompatibleSkillNames, resolveSkillNamesForPackages } from './chunk-X3RSYNBG.js';
|
|
3
3
|
import './chunk-2H7UOFLK.js';
|
|
4
|
-
//# sourceMappingURL=cli-skill-templates-
|
|
5
|
-
//# sourceMappingURL=cli-skill-templates-
|
|
4
|
+
//# sourceMappingURL=cli-skill-templates-EZFW7D43.js.map
|
|
5
|
+
//# sourceMappingURL=cli-skill-templates-EZFW7D43.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"cli-skill-templates-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"cli-skill-templates-EZFW7D43.js"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { generateConfigFile } from './chunk-WW2MIO6T.js';
|
|
3
|
-
import { cliM } from './chunk-
|
|
3
|
+
import { cliM } from './chunk-X3RSYNBG.js';
|
|
4
4
|
import './chunk-2H7UOFLK.js';
|
|
5
5
|
import process4 from 'process';
|
|
6
6
|
import { cac } from 'cac';
|
|
@@ -1164,7 +1164,7 @@ PUBLIC_API_BASE=http://127.0.0.1:3000
|
|
|
1164
1164
|
`), { mode: 384 });
|
|
1165
1165
|
}
|
|
1166
1166
|
}
|
|
1167
|
-
const { generateSkillFiles } = await import('./cli-skill-templates-
|
|
1167
|
+
const { generateSkillFiles } = await import('./cli-skill-templates-EZFW7D43.js');
|
|
1168
1168
|
await generateSkillFiles(
|
|
1169
1169
|
projectPath,
|
|
1170
1170
|
resolvedOptions.features,
|
|
@@ -1685,7 +1685,9 @@ function generateAiDevelopmentReadme() {
|
|
|
1685
1685
|
|
|
1686
1686
|
\u4ECE\u672C\u9879\u76EE\u6839\u76EE\u5F55\u6253\u5F00\u6240\u7528\u7F16\u7801\u5DE5\u5177\uFF0C\u5148\u8BFB\u53D6 [AGENTS.md](./AGENTS.md)\u3002Claude Code \u901A\u8FC7 [CLAUDE.md](./CLAUDE.md) \u52A0\u8F7D\u9879\u76EE\u89C4\u5219\uFF1BGitHub Copilot \u4F7F\u7528 [.github/copilot-instructions.md](./.github/copilot-instructions.md)\uFF0COpenCode \u4F7F\u7528 AGENTS.md \u548C [opencode.json](./opencode.json)\u3002
|
|
1687
1687
|
|
|
1688
|
-
Codex\u3001Cursor\u3001Copilot\u3001OpenCode \u4ECE .agents/skills/ \u53D1\u73B0\u5171\u4EAB\u6280\u80FD\uFF1BClaude Code \u901A\u8FC7 CLAUDE.md \u5F15\u7528 AGENTS.md\uFF0C\u5E76\u6309\u9879\u76EE\u6307\u5F15\u8BFB\u53D6 .agents/skills/ \u7684\u540C\u4E00\u4EFD\u6B63\u6587\u3002\u666E\u901A\u65B0\u589E\u3001\u4FEE\u6539\u3001\u4FEE\u590D\u4EFB\u52A1\u4F7F\u7528 [\u5E94\u7528\u5F00\u53D1 Skill](./.agents/skills/hai-app-create/SKILL.md) \u548C [\u5F00\u53D1\u89C4\u8303\u4E0E\u6846\u67B6\u80FD\u529B\u8DEF\u7531](./.agents/skills/hai-app-create/development.md)\uFF1B\u5177\u4F53\u6A21\u5757\u518D\u6309\u9700\u8BFB\u53D6\uFF0C\u4E0D\u80FD\u628A Skill \u5DF2\u4EA4\u4ED8\u5F53\u6210\u4F9D\u8D56\u5DF2\u5B89\u88C5\u6216\u914D\u7F6E\u5DF2\u542F\u7528\u3002
|
|
1688
|
+
Codex\u3001Cursor\u3001Copilot\u3001OpenCode \u4ECE .agents/skills/ \u53D1\u73B0\u5171\u4EAB\u6280\u80FD\uFF1BClaude Code \u901A\u8FC7 CLAUDE.md \u5F15\u7528 AGENTS.md\uFF0C\u5E76\u6309\u9879\u76EE\u6307\u5F15\u8BFB\u53D6 .agents/skills/ \u7684\u540C\u4E00\u4EFD\u6B63\u6587\u3002\u9700\u6C42\u6216\u8BBE\u8BA1\u6587\u6863\u5728\u751F\u6210\u524D\u4F7F\u7528 [\u6587\u6863\u5BA1\u67E5 Skill](./.agents/skills/hai-spec-review/SKILL.md) \u4E25\u683C\u68C0\u67E5\u5B8C\u5907\u6027\u3001\u6B67\u4E49\u3001\u6280\u672F\u6B63\u786E\u6027\u548C\u547D\u540D\u4E00\u81F4\u6027\uFF0C\u95EE\u9898\u89E3\u51B3\u540E\u518D\u751F\u6210\u3002\u666E\u901A\u65B0\u589E\u3001\u4FEE\u6539\u3001\u4FEE\u590D\u4EFB\u52A1\u4F7F\u7528 [\u5E94\u7528\u5F00\u53D1 Skill](./.agents/skills/hai-app-create/SKILL.md) \u548C [\u5F00\u53D1\u89C4\u8303\u4E0E\u6846\u67B6\u80FD\u529B\u8DEF\u7531](./.agents/skills/hai-app-create/development.md)\uFF1B\u5177\u4F53\u6A21\u5757\u518D\u6309\u9700\u8BFB\u53D6\uFF0C\u4E0D\u80FD\u628A Skill \u5DF2\u4EA4\u4ED8\u5F53\u6210\u4F9D\u8D56\u5DF2\u5B89\u88C5\u6216\u914D\u7F6E\u5DF2\u542F\u7528\u3002
|
|
1689
|
+
|
|
1690
|
+
\u6839\u636E\u6587\u6863\u89C4\u5212\u3001\u5B9E\u65BD\u6216\u8FD4\u4FEE\u65F6\uFF0C\u4F7F\u7528 [\u6587\u6863\u5B9E\u65BD Skill](./.agents/skills/hai-spec-implement/SKILL.md)\uFF1A\u6309\u53EF\u9A8C\u6536\u529F\u80FD\u62C6\u5206\uFF0C\u7EF4\u62A4 docs/task-list.md \u4E0E docs/tasks/ \u8BB0\u5F55\uFF0C\u6BCF\u9879\u5728\u72EC\u7ACB\u5206\u652F\u8D70 TDD\u3001\u9A8C\u8BC1\u4E0E\u672C\u5730\u5408\u5E76\uFF1B\u8FD4\u4FEE\u6CBF\u7528\u539F\u4EFB\u52A1\u4E0E\u5206\u652F\u5E76\u8FFD\u52A0\u8BC1\u636E\u3002\u4EC5\u89C4\u5212\u4E0D\u5F00\u59CB\u5B9E\u73B0\uFF0C\u6307\u5B9A\u4EFB\u52A1\u5148\u6838\u9A8C\u4F9D\u8D56\u3002
|
|
1689
1691
|
|
|
1690
1692
|
\u4F18\u5148\u590D\u7528\u9002\u7528\u7684 hai-framework \u516C\u5F00 API \u4E0E\u5DF2\u6709\u4E1A\u52A1\u5B9E\u73B0\u3002\u5B8C\u6210\u65F6\u8BF4\u660E\u590D\u7528\u7684\u80FD\u529B\u3001\u76F8\u5173\u80FD\u529B\u672A\u91C7\u7528\u7684\u539F\u56E0\uFF0C\u4EE5\u53CA\u5B89\u5168\u8FB9\u754C\u548C\u7C7B\u578B\u3001\u914D\u7F6E\u3001\u6587\u6848\u3001\u8C03\u7528\u65B9\u7684\u540C\u6B65\u60C5\u51B5\u3002\u8D28\u91CF\u9A8C\u8BC1\u6309\u5F53\u524D package.json \u6267\u884C typecheck \u2192 lint \u2192 build \u2192 test\uFF1BUI\u3001\u8DEF\u7531\u4E0E\u7AEF\u5230\u7AEF\u6D41\u7A0B\u53E6\u8FD0\u884C test:e2e\uFF0C\u672A\u8FD0\u884C\u9879\u8BF4\u660E\u539F\u56E0\u3002\u5B89\u5168\u4E0E\u8D28\u91CF\u89C4\u5219\u65E2\u8981\u6309\u89C4\u8303\u5BA1\u67E5\uFF0C\u4E5F\u8981\u8FD0\u884C\u95E8\u7981\u9A8C\u8BC1\u3002
|
|
1691
1693
|
|
|
@@ -2116,7 +2118,7 @@ async function addModule(options) {
|
|
|
2116
2118
|
core.logger.info(`\u53EF\u7528\u6A21\u5757: ${Object.keys(MODULE_MAP).join(", ")}`);
|
|
2117
2119
|
return;
|
|
2118
2120
|
}
|
|
2119
|
-
const { generateProjectAiSupport, resolveSkillNamesForPackages } = await import('./cli-skill-templates-
|
|
2121
|
+
const { generateProjectAiSupport, resolveSkillNamesForPackages } = await import('./cli-skill-templates-EZFW7D43.js');
|
|
2120
2122
|
if (moduleDef.packages.every((p) => project.haiPackages.includes(p))) {
|
|
2121
2123
|
const generatedFiles2 = await generateProjectAiSupport(
|
|
2122
2124
|
cwd,
|
|
@@ -2651,7 +2653,7 @@ async function initProject(options) {
|
|
|
2651
2653
|
const { project, existing, missing } = result;
|
|
2652
2654
|
spinner.succeed(`\u68C0\u6D4B\u5230\u9879\u76EE: ${chalk.cyan(project.name)}`);
|
|
2653
2655
|
if (project.isHaiProject) {
|
|
2654
|
-
const { generateProjectAiSupport, resolveSkillNamesForPackages } = await import('./cli-skill-templates-
|
|
2656
|
+
const { generateProjectAiSupport, resolveSkillNamesForPackages } = await import('./cli-skill-templates-EZFW7D43.js');
|
|
2655
2657
|
const generatedFiles = await generateProjectAiSupport(cwd, resolveSkillNamesForPackages(project.haiPackages), {
|
|
2656
2658
|
overwriteSkills: false,
|
|
2657
2659
|
overwriteBridgeFiles: false
|