@h-ai/cli 0.1.0-alpha.51 → 0.1.0-alpha.53
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/dist/index.js +125 -22
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/templates/apps/api/Dockerfile.hbs +6 -3
- package/templates/apps/api/apps/{{projectName}}-service/data/.gitkeep.hbs +1 -0
- package/templates/apps/fullstack/.dockerignore.hbs +2 -0
- package/templates/apps/fullstack/Dockerfile.hbs +23 -36
- package/templates/apps/fullstack/apps/{{projectName}}-web/index.html.hbs +2 -1
- package/templates/apps/fullstack/apps/{{projectName}}-web/public/runtime-config.js.hbs +1 -0
- package/templates/apps/fullstack/apps/{{projectName}}-web/tests/api.test.ts.hbs +27 -0
- package/templates/apps/fullstack/docker/19-runtime-config.envsh.hbs +5 -0
- package/templates/apps/fullstack/docker/nginx.conf.hbs +6 -0
- package/templates/apps/fullstack/docker/runtime-config.js.template.hbs +3 -0
- package/templates/apps/fullstack/package.json.hbs +2 -4
- package/templates/apps/fullstack/packages/{{projectName}}-serv/README.md.hbs +3 -2
- package/templates/apps/fullstack/packages/{{projectName}}-serv/data/.gitkeep.hbs +1 -0
- package/templates/apps/fullstack/packages/{{projectName}}-shared/src/lib/api/api-client.ts.hbs +9 -1
- package/templates/base/.gitignore.hbs +2 -1
- package/templates/base/Dockerfile.hbs +10 -4
- package/templates/base/package.json.hbs +1 -1
- package/templates/skills/hai-ai/SKILL.md +4 -0
- package/templates/skills/hai-app-create/SKILL.md +3 -1
- package/templates/apps/fullstack/docker/fullstack-server.mjs.hbs +0 -194
package/dist/index.js
CHANGED
|
@@ -1617,15 +1617,20 @@ function generateReadme(name, appTypeLabel, pm, appType) {
|
|
|
1617
1617
|
const isStaticImage = appType === "mobile-app";
|
|
1618
1618
|
const containerPort = isStaticImage ? 8080 : 3e3;
|
|
1619
1619
|
const runtimeOptions = isStaticImage ? "" : ` --env-file .env --mount type=bind,source=/absolute/path/to/config,target=/app/config,readonly --mount type=volume,source=${name}-data,target=/app/data`;
|
|
1620
|
-
const
|
|
1621
|
-
\
|
|
1622
|
-
|
|
1623
|
-
\`\`\`bash
|
|
1620
|
+
const embeddedDataBuild = isStaticImage ? "" : `
|
|
1621
|
+
# \u5E26 data/ \u521D\u59CB\u6570\u636E\u6784\u5EFA\uFF08\u4E8C\u9009\u4E00\uFF09
|
|
1624
1622
|
${getRunCommand(pm, "docker:build:data")}
|
|
1625
|
-
|
|
1623
|
+
${getRunCommand(pm, "podman:build:data")}`;
|
|
1624
|
+
const runtimeNotes = isStaticImage ? "- \u8BE5\u6A21\u677F\u751F\u6210\u9759\u6001 Web \u955C\u50CF\uFF0C\u4E0D\u5305\u542B\u53EF\u5199\u6570\u636E\u5E93\u76EE\u5F55\u3002" : `\u4EE5\u4E0A\u4E09\u4E2A\u8FD0\u884C\u65F6\u53C2\u6570\u5747\u53EF\u6309\u9700\u5220\u9664\uFF1A
|
|
1626
1625
|
|
|
1627
|
-
\
|
|
1628
|
-
|
|
1626
|
+
| \u53C2\u6570 | \u7528\u9014 | \u53EF\u9009\u6027 |
|
|
1627
|
+
| --- | --- | --- |
|
|
1628
|
+
| \`--env-file .env\` | \u6279\u91CF\u4F20\u5165\u73AF\u5883\u53D8\u91CF\uFF1B\u4E5F\u53EF\u6539\u7528\u591A\u4E2A \`-e NAME=value\`\u3002 | \u53EF\u9009\uFF1B\u5220\u9664\u540E\u4F7F\u7528\u955C\u50CF\u548C YAML \u9ED8\u8BA4\u503C\u3002 |
|
|
1629
|
+
| \`--mount type=bind,...target=/app/config,readonly\` | \u7528\u5BBF\u4E3B\u673A\u914D\u7F6E\u76EE\u5F55\u8986\u76D6\u955C\u50CF\u5185 \`/app/config\`\uFF1B\u5FC5\u987B\u628A \`source\` \u6539\u6210\u771F\u5B9E\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\`readonly\` \u9632\u6B62\u5BB9\u5668\u4FEE\u6539\u914D\u7F6E\u3002 | \u53EF\u9009\uFF1B\u5220\u9664\u540E\u4F7F\u7528\u955C\u50CF\u81EA\u5E26\u914D\u7F6E\u3002 |
|
|
1630
|
+
| \`--mount type=volume,...target=/app/data\` | \u521B\u5EFA\u6216\u590D\u7528 named volume\uFF0C\u6301\u4E45\u5316 SQLite \u548C\u672C\u5730\u5B58\u50A8\u3002 | \u53EF\u9009\u4F46\u751F\u4EA7\u73AF\u5883\u5EFA\u8BAE\u4FDD\u7559\uFF1B\u5220\u9664\u540E\u6570\u636E\u53EA\u5199\u5165\u5BB9\u5668\u5C42\uFF0C\u4F7F\u7528 \`--rm\` \u5220\u9664\u5BB9\u5668\u65F6\u4F1A\u4E22\u5931\u3002 |
|
|
1631
|
+
|
|
1632
|
+
- \u5E26\u6570\u636E\u6784\u5EFA\u4F1A\u628A\u5F53\u524D \`data/\`\uFF08\u4F8B\u5982\u9884\u7F6E SQLite \u6587\u4EF6\uFF09\u56FA\u5316\u4E3A\u955C\u50CF\u521D\u59CB\u5FEB\u7167\uFF1B\u8FD0\u884C\u540E\u4EA7\u751F\u7684\u65B0\u6570\u636E\u4ECD\u5E94\u5199\u5165 \`/app/data\` volume\u3002`;
|
|
1633
|
+
const testPath = isStaticImage ? "/health" : "/";
|
|
1629
1634
|
return `# ${name}
|
|
1630
1635
|
|
|
1631
1636
|
\u57FA\u4E8E hai Agent Framework \u6784\u5EFA\u7684${appTypeLabel}\u5E94\u7528\u3002
|
|
@@ -1645,13 +1650,31 @@ ${getRunCommand(pm, "i18n:compile")}
|
|
|
1645
1650
|
${getRunCommand(pm, "preview")}
|
|
1646
1651
|
\`\`\`
|
|
1647
1652
|
|
|
1648
|
-
##
|
|
1653
|
+
## \u5BB9\u5668\u8FD0\u884C
|
|
1654
|
+
|
|
1655
|
+
### \u6784\u5EFA\u955C\u50CF
|
|
1649
1656
|
|
|
1650
1657
|
\`\`\`bash
|
|
1658
|
+
# \u666E\u901A\u6784\u5EFA\uFF08\u4E8C\u9009\u4E00\uFF09
|
|
1651
1659
|
${getRunCommand(pm, "docker:build")}
|
|
1652
|
-
|
|
1660
|
+
${getRunCommand(pm, "podman:build")}${embeddedDataBuild}
|
|
1653
1661
|
\`\`\`
|
|
1654
|
-
|
|
1662
|
+
|
|
1663
|
+
### \u8FD0\u884C\u955C\u50CF
|
|
1664
|
+
|
|
1665
|
+
\`\`\`bash
|
|
1666
|
+
# Docker\uFF1B\u4F7F\u7528 Podman \u65F6\u5C06 docker \u66FF\u6362\u4E3A podman
|
|
1667
|
+
docker run --rm -d --name ${name} -p ${containerPort}:${containerPort}${runtimeOptions} ${name}:latest
|
|
1668
|
+
\`\`\`
|
|
1669
|
+
|
|
1670
|
+
### \u6D4B\u8BD5\u955C\u50CF
|
|
1671
|
+
|
|
1672
|
+
\`\`\`bash
|
|
1673
|
+
curl --fail http://127.0.0.1:${containerPort}${testPath}
|
|
1674
|
+
docker stop ${name}
|
|
1675
|
+
\`\`\`
|
|
1676
|
+
|
|
1677
|
+
${runtimeNotes}
|
|
1655
1678
|
|
|
1656
1679
|
## \u6587\u6863
|
|
1657
1680
|
|
|
@@ -1686,18 +1709,50 @@ ${pm} test
|
|
|
1686
1709
|
${pm} test:e2e
|
|
1687
1710
|
\`\`\`
|
|
1688
1711
|
|
|
1689
|
-
##
|
|
1712
|
+
## \u5BB9\u5668\u8FD0\u884C
|
|
1713
|
+
|
|
1714
|
+
### \u6784\u5EFA\u955C\u50CF
|
|
1690
1715
|
|
|
1691
1716
|
\`\`\`bash
|
|
1717
|
+
# \u666E\u901A\u6784\u5EFA\uFF08\u4E8C\u9009\u4E00\uFF09
|
|
1692
1718
|
${pm} docker:build
|
|
1693
|
-
|
|
1719
|
+
${pm} podman:build
|
|
1720
|
+
|
|
1721
|
+
# \u5C06 apps/${name}-service/data \u4F5C\u4E3A\u955C\u50CF\u521D\u59CB\u6570\u636E\u6784\u5EFA\uFF08\u4E8C\u9009\u4E00\uFF09
|
|
1722
|
+
${pm} docker:build:data
|
|
1723
|
+
${pm} podman:build:data
|
|
1724
|
+
\`\`\`
|
|
1725
|
+
|
|
1726
|
+
### \u8FD0\u884C\u955C\u50CF
|
|
1727
|
+
|
|
1728
|
+
\`\`\`bash
|
|
1729
|
+
# \u4F7F\u7528 Podman \u65F6\u5C06 docker \u66FF\u6362\u4E3A podman
|
|
1730
|
+
docker run --rm -d --name ${name} -p 3000:3000 --env-file .env \\
|
|
1694
1731
|
--mount type=bind,source=/absolute/path/to/config,target=/app/config,readonly \\
|
|
1695
1732
|
--mount type=volume,source=${name}-data,target=/app/data \\
|
|
1696
1733
|
${name}:latest
|
|
1697
1734
|
\`\`\`
|
|
1698
1735
|
|
|
1736
|
+
### \u6D4B\u8BD5\u955C\u50CF
|
|
1737
|
+
|
|
1738
|
+
\`\`\`bash
|
|
1739
|
+
curl --fail http://127.0.0.1:3000/health
|
|
1740
|
+
curl --fail http://127.0.0.1:3000/ready
|
|
1741
|
+
curl --fail --request POST http://127.0.0.1:3000/api/v1/app/info \\
|
|
1742
|
+
--header "Content-Type: application/json" --data '{}'
|
|
1743
|
+
docker stop ${name}
|
|
1744
|
+
\`\`\`
|
|
1745
|
+
|
|
1699
1746
|
- \u914D\u7F6E\u9ED8\u8BA4\u6765\u81EA \`apps/${name}-service/config\`\uFF1B\u8FD0\u884C\u65F6\u53EF\u53EA\u8BFB\u6302\u8F7D\u5230 \`/app/config\` \u8986\u76D6\uFF0C\u5E76\u7528 YAML \u7684 \`\${ENV_NAME:default}\` \u5360\u4F4D\u7B26\u63A5\u6536\u73AF\u5883\u53D8\u91CF\u3002
|
|
1700
|
-
- \
|
|
1747
|
+
- \u5E26\u6570\u636E\u6784\u5EFA\u4F1A\u628A \`apps/${name}-service/data\` \u56FA\u5316\u4E3A\u955C\u50CF\u521D\u59CB\u6570\u636E\uFF1B\u751F\u4EA7\u5199\u5165\u4ECD\u5EFA\u8BAE\u4F7F\u7528 \`/app/data\` volume\u3002
|
|
1748
|
+
|
|
1749
|
+
\u4EE5\u4E0A\u4E09\u4E2A\u8FD0\u884C\u65F6\u53C2\u6570\u5747\u53EF\u6309\u9700\u5220\u9664\uFF1A
|
|
1750
|
+
|
|
1751
|
+
| \u53C2\u6570 | \u7528\u9014 | \u53EF\u9009\u6027 |
|
|
1752
|
+
| --- | --- | --- |
|
|
1753
|
+
| \`--env-file .env\` | \u6279\u91CF\u4F20\u5165\u73AF\u5883\u53D8\u91CF\uFF1B\u4E5F\u53EF\u6539\u7528\u591A\u4E2A \`-e NAME=value\`\u3002 | \u53EF\u9009\uFF1B\u5220\u9664\u540E\u4F7F\u7528\u955C\u50CF\u548C YAML \u9ED8\u8BA4\u503C\u3002 |
|
|
1754
|
+
| \`--mount type=bind,...target=/app/config,readonly\` | \u7528\u5BBF\u4E3B\u673A\u914D\u7F6E\u76EE\u5F55\u8986\u76D6\u955C\u50CF\u5185 \`/app/config\`\uFF1B\u5FC5\u987B\u628A \`source\` \u6539\u6210\u771F\u5B9E\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\`readonly\` \u9632\u6B62\u5BB9\u5668\u4FEE\u6539\u914D\u7F6E\u3002 | \u53EF\u9009\uFF1B\u5220\u9664\u540E\u4F7F\u7528\u955C\u50CF\u81EA\u5E26\u914D\u7F6E\u3002 |
|
|
1755
|
+
| \`--mount type=volume,...target=/app/data\` | \u521B\u5EFA\u6216\u590D\u7528 named volume\uFF0C\u6301\u4E45\u5316 SQLite \u548C\u672C\u5730\u5B58\u50A8\u3002 | \u53EF\u9009\u4F46\u751F\u4EA7\u73AF\u5883\u5EFA\u8BAE\u4FDD\u7559\uFF1B\u5220\u9664\u540E\u6570\u636E\u53EA\u5199\u5165\u5BB9\u5668\u5C42\uFF0C\u4F7F\u7528 \`--rm\` \u5220\u9664\u5BB9\u5668\u65F6\u4F1A\u4E22\u5931\u3002 |
|
|
1701
1756
|
|
|
1702
1757
|
## \u6269\u5C55\u5EFA\u8BAE
|
|
1703
1758
|
|
|
@@ -1715,6 +1770,20 @@ docker run --rm -p 3000:3000 --env-file .env \\
|
|
|
1715
1770
|
}
|
|
1716
1771
|
function generateFullstackReadme(name, pm, frontends) {
|
|
1717
1772
|
const enabledFrontends = frontends.map((target) => FRONTEND_TARGETS[target].name).join(" / ");
|
|
1773
|
+
const webBuildCommands = frontends.includes("web") ? `
|
|
1774
|
+
# Web \u9759\u6001\u955C\u50CF\uFF08\u4E8C\u9009\u4E00\uFF09
|
|
1775
|
+
${pm} docker:build:web
|
|
1776
|
+
${pm} podman:build:web` : "";
|
|
1777
|
+
const webRunCommand = frontends.includes("web") ? `
|
|
1778
|
+
|
|
1779
|
+
# Web\uFF1BPUBLIC_API_BASE \u5728\u5BB9\u5668\u542F\u52A8\u65F6\u6CE8\u5165\uFF0C\u4E0D\u9700\u8981\u91CD\u65B0\u6784\u5EFA\u955C\u50CF
|
|
1780
|
+
docker run --rm -d --name ${name}-web -p 8080:8080 \\
|
|
1781
|
+
-e PUBLIC_API_BASE=https://api.example.com \\
|
|
1782
|
+
${name}-web:latest` : "";
|
|
1783
|
+
const webTestCommands = frontends.includes("web") ? `curl --fail http://127.0.0.1:8080/health
|
|
1784
|
+
curl --fail http://127.0.0.1:8080/runtime-config.js
|
|
1785
|
+
` : "";
|
|
1786
|
+
const containerNames = frontends.includes("web") ? `${name} ${name}-web` : name;
|
|
1718
1787
|
return `# ${name}
|
|
1719
1788
|
|
|
1720
1789
|
\u57FA\u4E8E hai Agent Framework \u6784\u5EFA\u7684\u524D\u540E\u7AEF\u5206\u79BB\u591A\u5305\u5DE5\u7A0B\u3002
|
|
@@ -1747,22 +1816,56 @@ ${pm} package
|
|
|
1747
1816
|
${pm} deploy
|
|
1748
1817
|
\`\`\`
|
|
1749
1818
|
|
|
1750
|
-
##
|
|
1819
|
+
## \u5BB9\u5668\u8FD0\u884C
|
|
1820
|
+
|
|
1821
|
+
\u9ED8\u8BA4\u955C\u50CF\u76F4\u63A5\u8FD0\u884C API Service\uFF0C\u5916\u90E8\u7AEF\u53E3\u4E3A 3000\u3002
|
|
1751
1822
|
|
|
1752
|
-
\
|
|
1823
|
+
### \u6784\u5EFA\u955C\u50CF
|
|
1753
1824
|
|
|
1754
1825
|
\`\`\`bash
|
|
1826
|
+
# Service \u666E\u901A\u6784\u5EFA\uFF08\u4E8C\u9009\u4E00\uFF09
|
|
1755
1827
|
${pm} docker:build
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1828
|
+
${pm} podman:build
|
|
1829
|
+
|
|
1830
|
+
# \u5C06 packages/${name}-serv/data \u4F5C\u4E3A\u955C\u50CF\u521D\u59CB\u6570\u636E\u6784\u5EFA\uFF08\u4E8C\u9009\u4E00\uFF09
|
|
1831
|
+
${pm} docker:build:data
|
|
1832
|
+
${pm} podman:build:data
|
|
1833
|
+
${webBuildCommands}
|
|
1834
|
+
\`\`\`
|
|
1835
|
+
|
|
1836
|
+
### \u8FD0\u884C\u955C\u50CF
|
|
1837
|
+
|
|
1838
|
+
\`\`\`bash
|
|
1839
|
+
# Service\uFF1B\u4F7F\u7528 Podman \u65F6\u5C06 docker \u66FF\u6362\u4E3A podman
|
|
1840
|
+
docker run --rm -d --name ${name} -p 3000:3000 --env-file .env \\
|
|
1841
|
+
--mount type=bind,source=/absolute/path/to/config,target=/app/config,readonly \\
|
|
1842
|
+
--mount type=volume,source=${name}-data,target=/app/data \\
|
|
1759
1843
|
${name}:latest
|
|
1844
|
+
${webRunCommand}
|
|
1845
|
+
\`\`\`
|
|
1846
|
+
|
|
1847
|
+
### \u6D4B\u8BD5\u955C\u50CF
|
|
1848
|
+
|
|
1849
|
+
\`\`\`bash
|
|
1850
|
+
curl --fail http://127.0.0.1:3000/health
|
|
1851
|
+
curl --fail http://127.0.0.1:3000/ready
|
|
1852
|
+
curl --fail --request POST http://127.0.0.1:3000/api/v1/app/info \\
|
|
1853
|
+
--header "Content-Type: application/json" --data '{}'
|
|
1854
|
+
${webTestCommands}docker stop ${containerNames}
|
|
1760
1855
|
\`\`\`
|
|
1761
1856
|
|
|
1762
|
-
- \u914D\u7F6E\u9ED8\u8BA4\u6765\u81EA \`packages/${name}-serv/config\`\uFF0C\u4E5F\u53EF\u6302\u8F7D\u5230 \`/app/
|
|
1763
|
-
- \
|
|
1764
|
-
- \`
|
|
1765
|
-
|
|
1857
|
+
- \u914D\u7F6E\u9ED8\u8BA4\u6765\u81EA \`packages/${name}-serv/config\`\uFF0C\u4E5F\u53EF\u6302\u8F7D\u5230 \`/app/config\`\uFF1BYAML \u4E2D\u7684 \`\${ENV_NAME:default}\` \u53EF\u7531 \`--env-file\` \u6216 \`-e\` \u6CE8\u5165\u3002
|
|
1858
|
+
- \u5E26\u6570\u636E\u6784\u5EFA\u4F1A\u628A \`packages/${name}-serv/data\` \u56FA\u5316\u4E3A\u955C\u50CF\u521D\u59CB\u6570\u636E\uFF1B\u6301\u4E45\u5316\u5199\u5165\u4ECD\u5E94\u4F7F\u7528 volume\u3002
|
|
1859
|
+
- Service \u7531 \`@h-ai/serv\` \u76F4\u63A5\u5BF9\u5916\u76D1\u542C\uFF0C\u4E0D\u989D\u5916\u542F\u52A8 Web \u8F6C\u53D1\u5C42\u3002
|
|
1860
|
+
${frontends.includes("web") ? `- Web \u4F7F\u7528\u72EC\u7ACB\u9759\u6001\u955C\u50CF\u5E76\u652F\u6301\u4E00\u6B21\u6784\u5EFA\u3001\u591A\u73AF\u5883\u90E8\u7F72\uFF1B\u6784\u5EFA\u53EA\u9700\u8FD0\u884C \`${pm} docker:build:web\`\uFF0C\u542F\u52A8\u5BB9\u5668\u65F6\u901A\u8FC7 \`-e PUBLIC_API_BASE=https://api.example.com\` \u6307\u5411 Service \u5BF9\u5916\u5730\u5740\u3002\u672A\u8BBE\u7F6E\u65F6\u9ED8\u8BA4\u4F7F\u7528 Web \u9875\u9762\u81EA\u8EAB origin\u3002` : ""}
|
|
1861
|
+
|
|
1862
|
+
\u4EE5\u4E0A\u4E09\u4E2A Service \u8FD0\u884C\u65F6\u53C2\u6570\u5747\u53EF\u6309\u9700\u5220\u9664\uFF1A
|
|
1863
|
+
|
|
1864
|
+
| \u53C2\u6570 | \u7528\u9014 | \u53EF\u9009\u6027 |
|
|
1865
|
+
| --- | --- | --- |
|
|
1866
|
+
| \`--env-file .env\` | \u6279\u91CF\u4F20\u5165\u73AF\u5883\u53D8\u91CF\uFF1B\u4E5F\u53EF\u6539\u7528\u591A\u4E2A \`-e NAME=value\`\u3002 | \u53EF\u9009\uFF1B\u5220\u9664\u540E\u4F7F\u7528\u955C\u50CF\u548C YAML \u9ED8\u8BA4\u503C\u3002 |
|
|
1867
|
+
| \`--mount type=bind,...target=/app/config,readonly\` | \u7528\u5BBF\u4E3B\u673A\u914D\u7F6E\u76EE\u5F55\u8986\u76D6\u955C\u50CF\u5185 \`/app/config\`\uFF1B\u5FC5\u987B\u628A \`source\` \u6539\u6210\u771F\u5B9E\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\`readonly\` \u9632\u6B62\u5BB9\u5668\u4FEE\u6539\u914D\u7F6E\u3002 | \u53EF\u9009\uFF1B\u5220\u9664\u540E\u4F7F\u7528\u955C\u50CF\u81EA\u5E26\u914D\u7F6E\u3002 |
|
|
1868
|
+
| \`--mount type=volume,...target=/app/data\` | \u521B\u5EFA\u6216\u590D\u7528 named volume\uFF0C\u6301\u4E45\u5316 SQLite \u548C\u672C\u5730\u5B58\u50A8\u3002 | \u53EF\u9009\u4F46\u751F\u4EA7\u73AF\u5883\u5EFA\u8BAE\u4FDD\u7559\uFF1B\u5220\u9664\u540E\u6570\u636E\u53EA\u5199\u5165\u5BB9\u5668\u5C42\uFF0C\u4F7F\u7528 \`--rm\` \u5220\u9664\u5BB9\u5668\u65F6\u4F1A\u4E22\u5931\u3002 |
|
|
1766
1869
|
|
|
1767
1870
|
\u524D\u7AEF\u5355\u72EC\u4EA4\u4ED8\u547D\u4EE4\uFF1A
|
|
1768
1871
|
|