@lark-apaas/miaoda-cli 0.1.10 → 0.1.12-alpha.0
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/cli/commands/app/index.js +2 -7
- package/dist/cli/commands/skills/index.js +6 -6
- package/dist/cli/handlers/app/init.js +0 -2
- package/dist/cli/handlers/skills/sync.js +8 -11
- package/dist/utils/githooks.js +18 -0
- package/package.json +1 -1
- package/upgrade/templates/design-stack/templates/scripts/dev-local.js +2 -2
- package/upgrade/templates/design-stack/templates/scripts/dev.sh +2 -4
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev-local.js +3 -3
- package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev.sh +2 -4
|
@@ -121,7 +121,7 @@ function registerAppInit(parent) {
|
|
|
121
121
|
.command('init')
|
|
122
122
|
.description('初始化应用代码:抓 template 渲染、同步 upgrade/templates、装 .agent/steering/ skills、写 .spark/meta.json。.spark/meta.json 已存在则直接退出')
|
|
123
123
|
.option('--template <stack>', `技术栈短名(${index_1.SUPPORTED_STACKS.join(' / ')})`)
|
|
124
|
-
.option('--conf <json>', 'init 配置 JSON。支持 {"version": "<template 版本>"}
|
|
124
|
+
.option('--conf <json>', 'init 配置 JSON。支持 {"version": "<template 版本>"},默认 latest')
|
|
125
125
|
.option('--skip-install', '跳过依赖安装', false)
|
|
126
126
|
.addOption((0, shared_1.appIdOption)())
|
|
127
127
|
.addHelpText('after', `
|
|
@@ -161,7 +161,6 @@ JSON 输出
|
|
|
161
161
|
$ miaoda app init --template vite-react
|
|
162
162
|
$ miaoda app init --template nestjs-react-fullstack --app-id app_xxx
|
|
163
163
|
$ miaoda app init --template vite-react --conf '{"version": "0.1.0"}'
|
|
164
|
-
$ miaoda app init --template vite-react --conf '{"steeringVersion": "0.1.0"}'
|
|
165
164
|
$ miaoda app init --template vite-react --skip-install
|
|
166
165
|
$ MIAODA_DEP_CACHE_DIR=/tmp/dep-cache miaoda app init --template vite-react
|
|
167
166
|
`);
|
|
@@ -193,11 +192,7 @@ function parseInitConf(raw) {
|
|
|
193
192
|
if (version !== undefined && typeof version !== 'string') {
|
|
194
193
|
throw new error_1.AppError('ARGS_INVALID', '--conf.version 必须是字符串');
|
|
195
194
|
}
|
|
196
|
-
|
|
197
|
-
if (steeringVersion !== undefined && typeof steeringVersion !== 'string') {
|
|
198
|
-
throw new error_1.AppError('ARGS_INVALID', '--conf.steeringVersion 必须是字符串');
|
|
199
|
-
}
|
|
200
|
-
return { version, steeringVersion };
|
|
195
|
+
return { version };
|
|
201
196
|
}
|
|
202
197
|
function isPlainObject(v) {
|
|
203
198
|
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
@@ -22,8 +22,8 @@ function registerSkillsSync(parent) {
|
|
|
22
22
|
const cmd = parent
|
|
23
23
|
.command('sync')
|
|
24
24
|
.description('同步 coding-steering(latest 或指定版本)到 user app')
|
|
25
|
-
.argument('[version]', 'coding-steering 包版本或 dist-tag,缺省 latest')
|
|
26
25
|
.option('--dir <path>', '项目目录,默认当前目录', '.')
|
|
26
|
+
.option('--version <ver>', 'coding-steering 包版本或 dist-tag,缺省 latest')
|
|
27
27
|
.option('--local', '走本地 dev / agent 输出形态:拷到 .agents/skills 平铺 + 创建 .claude/skills 软链。' +
|
|
28
28
|
'不传时退回老形态:拷到 .agent/skills/steering/<stack>/skills/(跟沙箱端 update-skills.sh 对齐)', false)
|
|
29
29
|
.addHelpText('after', `
|
|
@@ -46,15 +46,15 @@ JSON 输出
|
|
|
46
46
|
"claudeSkillsLink": "created|updated|noop|conflict" // 仅 --local 时}}
|
|
47
47
|
|
|
48
48
|
示例
|
|
49
|
-
$ miaoda skills sync
|
|
50
|
-
$ miaoda skills sync --local
|
|
51
|
-
$ miaoda skills sync 0.2.0
|
|
49
|
+
$ miaoda skills sync # 拉 @latest
|
|
50
|
+
$ miaoda skills sync --local # 本地 dev / agent 用
|
|
51
|
+
$ miaoda skills sync --version 0.2.0 # 显式指定版本
|
|
52
52
|
$ miaoda skills sync --dir ./my-app
|
|
53
53
|
`);
|
|
54
|
-
cmd.action((0, shared_1.withHelp)(cmd, async (
|
|
54
|
+
cmd.action((0, shared_1.withHelp)(cmd, async (rawOpts) => {
|
|
55
55
|
await (0, index_1.handleSkillsSync)({
|
|
56
56
|
dir: rawOpts.dir,
|
|
57
|
-
version,
|
|
57
|
+
version: rawOpts.version,
|
|
58
58
|
local: rawOpts.local,
|
|
59
59
|
});
|
|
60
60
|
}));
|
|
@@ -76,7 +76,6 @@ async function handleAppInit(opts) {
|
|
|
76
76
|
steeringResult = (0, coding_steering_1.syncCodingSteering)({
|
|
77
77
|
stack,
|
|
78
78
|
targetDir,
|
|
79
|
-
version: opts.conf?.steeringVersion,
|
|
80
79
|
logPrefix: 'init',
|
|
81
80
|
outputLayout,
|
|
82
81
|
});
|
|
@@ -98,7 +97,6 @@ async function handleAppInit(opts) {
|
|
|
98
97
|
version: tplResult.version,
|
|
99
98
|
archType: tplResult.archType,
|
|
100
99
|
app_id: opts.appId,
|
|
101
|
-
steeringVersion: steeringResult.version,
|
|
102
100
|
});
|
|
103
101
|
const syncedSummary = syncRunResult.stackFound
|
|
104
102
|
? syncRunResult.rulesApplied.length > 0
|
|
@@ -10,10 +10,13 @@ const spark_meta_1 = require("../../../utils/spark-meta");
|
|
|
10
10
|
const error_1 = require("../../../utils/error");
|
|
11
11
|
const output_1 = require("../../../utils/output");
|
|
12
12
|
/**
|
|
13
|
-
* miaoda skills sync [
|
|
13
|
+
* miaoda skills sync [--dir <path>] [--version <ver>]
|
|
14
14
|
*
|
|
15
|
-
* 从 .spark/meta.json 读 stack
|
|
16
|
-
*
|
|
15
|
+
* 从 .spark/meta.json 读 stack,把 coding-steering 包内对应 stack 的 skills + tech.md
|
|
16
|
+
* 同步到 <dir>/.agent/steering/。需要先跑过 `miaoda app init`。
|
|
17
|
+
*
|
|
18
|
+
* 版本来源:CLI `--version` flag 或默认 `latest`。**不读 meta.json**——steering 版本
|
|
19
|
+
* 不在 meta 里钉,每次 sync 都跟随 `--version` 显式传或退回 @latest。
|
|
17
20
|
*/
|
|
18
21
|
async function handleSkillsSync(opts) {
|
|
19
22
|
await Promise.resolve();
|
|
@@ -22,23 +25,17 @@ async function handleSkillsSync(opts) {
|
|
|
22
25
|
if (meta.stack === undefined || meta.stack === '') {
|
|
23
26
|
throw new error_1.AppError('SKILLS_META_INCOMPLETE', '.spark/meta.json missing stack — run `miaoda app init` first');
|
|
24
27
|
}
|
|
25
|
-
const version = opts.version ?? meta.steeringVersion;
|
|
26
|
-
const versionSource = opts.version
|
|
27
|
-
? 'cli-arg'
|
|
28
|
-
: meta.steeringVersion
|
|
29
|
-
? 'meta.json'
|
|
30
|
-
: 'default-latest';
|
|
31
28
|
const result = (0, coding_steering_1.syncCodingSteering)({
|
|
32
29
|
stack: meta.stack,
|
|
33
30
|
targetDir,
|
|
34
|
-
version,
|
|
31
|
+
version: opts.version,
|
|
35
32
|
outputLayout: opts.local === true ? 'flat' : 'nested',
|
|
36
33
|
});
|
|
37
34
|
(0, output_1.emit)({
|
|
38
35
|
data: {
|
|
39
36
|
stack: meta.stack,
|
|
40
37
|
version: result.version,
|
|
41
|
-
versionSource,
|
|
38
|
+
versionSource: opts.version !== undefined ? 'cli-arg' : 'default-latest',
|
|
42
39
|
syncedSkills: result.syncedSkills,
|
|
43
40
|
techSynced: result.techSynced,
|
|
44
41
|
...(result.claudeSkillsLink !== undefined
|
package/dist/utils/githooks.js
CHANGED
|
@@ -8,6 +8,21 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
9
|
const node_child_process_1 = require("node:child_process");
|
|
10
10
|
const logger_1 = require("../utils/logger");
|
|
11
|
+
const GIT_LEAKED_ENV_KEYS = new Set([
|
|
12
|
+
'GIT_DIR',
|
|
13
|
+
'GIT_WORK_TREE',
|
|
14
|
+
'GIT_INDEX_FILE',
|
|
15
|
+
'GIT_COMMON_DIR',
|
|
16
|
+
'GIT_PREFIX',
|
|
17
|
+
'GIT_OBJECT_DIRECTORY',
|
|
18
|
+
'GIT_ALTERNATE_OBJECT_DIRECTORIES',
|
|
19
|
+
'GIT_CONFIG',
|
|
20
|
+
'GIT_CONFIG_PARAMETERS',
|
|
21
|
+
'GIT_CONFIG_COUNT',
|
|
22
|
+
]);
|
|
23
|
+
function envWithoutGitLeaks() {
|
|
24
|
+
return Object.fromEntries(Object.entries(process.env).filter(([key]) => !GIT_LEAKED_ENV_KEYS.has(key)));
|
|
25
|
+
}
|
|
11
26
|
/**
|
|
12
27
|
* 把 `.githooks/` 注册为本仓库的 git hooks 目录,让 pre-commit 等 hook 立即生效。
|
|
13
28
|
*
|
|
@@ -33,8 +48,10 @@ function activateGitHooks(targetDir) {
|
|
|
33
48
|
if ((currentMode & 0o111) !== 0o111) {
|
|
34
49
|
node_fs_1.default.chmodSync(hookFile, 0o755);
|
|
35
50
|
}
|
|
51
|
+
const env = envWithoutGitLeaks();
|
|
36
52
|
const probe = (0, node_child_process_1.spawnSync)('git', ['config', '--get', 'core.hooksPath'], {
|
|
37
53
|
cwd: targetDir,
|
|
54
|
+
env,
|
|
38
55
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
39
56
|
});
|
|
40
57
|
const currentHooksPath = probe.stdout.toString().trim();
|
|
@@ -43,6 +60,7 @@ function activateGitHooks(targetDir) {
|
|
|
43
60
|
}
|
|
44
61
|
const res = (0, node_child_process_1.spawnSync)('git', ['config', 'core.hooksPath', '.githooks'], {
|
|
45
62
|
cwd: targetDir,
|
|
63
|
+
env,
|
|
46
64
|
stdio: ['ignore', 'ignore', 'pipe'],
|
|
47
65
|
});
|
|
48
66
|
if (res.status !== 0) {
|
package/package.json
CHANGED
|
@@ -47,10 +47,10 @@ if (hasLarkCli) {
|
|
|
47
47
|
warn('lark-cli 未安装,跳过 env pull;请确保 .env.local 已就绪');
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
// skills sync —— --local 切 flat layout
|
|
50
|
+
// skills sync —— --local 切 flat layout;不传 --version,handler 默认 coding-steering@latest。
|
|
51
51
|
console.log('[dev-local] (2/4) miaoda skills sync...');
|
|
52
52
|
try {
|
|
53
|
-
execSync('npx -y @lark-apaas/miaoda-cli@
|
|
53
|
+
execSync('npx -y @lark-apaas/miaoda-cli@latest skills sync --local', { stdio: 'inherit' });
|
|
54
54
|
} catch {
|
|
55
55
|
console.log(' (skills sync 失败,继续启动)');
|
|
56
56
|
}
|
|
@@ -13,14 +13,12 @@ if [ -n "${SANDBOX_ID:-}" ]; then
|
|
|
13
13
|
fi
|
|
14
14
|
|
|
15
15
|
if [ ! -f "$SCRIPT_DIR/dev-local.js" ]; then
|
|
16
|
-
echo "[dev] scripts/dev-local.js 缺失;先跑 \`npx -y @lark-apaas/miaoda-cli@
|
|
16
|
+
echo "[dev] scripts/dev-local.js 缺失;先跑 \`npx -y @lark-apaas/miaoda-cli@latest app sync\` 同步平台脚本" >&2
|
|
17
17
|
exit 1
|
|
18
18
|
fi
|
|
19
19
|
|
|
20
20
|
# 本地启动前先跑一次 miaoda app sync:同步 platform-controlled 内容 + 升 @lark-apaas/* 到
|
|
21
21
|
# latest + 迁移老 npm scripts。沙箱不走这里(SANDBOX_ID 分支已经 exec return)。
|
|
22
|
-
|
|
23
|
-
# latest 后切回 @latest。
|
|
24
|
-
npx -y @lark-apaas/miaoda-cli@alpha app sync || echo "[dev] miaoda app sync 失败,按现状继续" >&2
|
|
22
|
+
npx -y @lark-apaas/miaoda-cli@latest app sync || echo "[dev] miaoda app sync 失败,按现状继续" >&2
|
|
25
23
|
|
|
26
24
|
exec node "$SCRIPT_DIR/dev-local.js" "$@"
|
|
@@ -56,11 +56,11 @@ if (hasLarkCli) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
// 2. skills sync —— --local 切到 flat layout (.agents/skills + .claude/skills 软链),
|
|
59
|
-
// 跟沙箱 nested layout
|
|
60
|
-
//
|
|
59
|
+
// 跟沙箱 nested layout 区分。不传 --version,handler 默认拉 coding-steering@latest,
|
|
60
|
+
// 保证每次本地 npm run dev 都把 skills 升到最新。
|
|
61
61
|
console.log('[dev-local] (2/4) miaoda skills sync...');
|
|
62
62
|
try {
|
|
63
|
-
execSync('npx -y @lark-apaas/miaoda-cli@
|
|
63
|
+
execSync('npx -y @lark-apaas/miaoda-cli@latest skills sync --local', { stdio: 'inherit' });
|
|
64
64
|
} catch {
|
|
65
65
|
console.log(' (skills sync 失败,继续启动)');
|
|
66
66
|
}
|
|
@@ -13,14 +13,12 @@ if [ -n "${SANDBOX_ID:-}" ]; then
|
|
|
13
13
|
fi
|
|
14
14
|
|
|
15
15
|
if [ ! -f "$SCRIPT_DIR/dev-local.js" ]; then
|
|
16
|
-
echo "[dev] scripts/dev-local.js 缺失;先跑 \`npx -y @lark-apaas/miaoda-cli@
|
|
16
|
+
echo "[dev] scripts/dev-local.js 缺失;先跑 \`npx -y @lark-apaas/miaoda-cli@latest app sync\` 同步平台脚本" >&2
|
|
17
17
|
exit 1
|
|
18
18
|
fi
|
|
19
19
|
|
|
20
20
|
# 本地启动前先跑一次 miaoda app sync:同步 platform-controlled 内容 + 升 @lark-apaas/* 到
|
|
21
21
|
# latest + 迁移老 npm scripts。沙箱不走这里(SANDBOX_ID 分支已经 exec return)。
|
|
22
|
-
|
|
23
|
-
# latest 后切回 @latest。
|
|
24
|
-
npx -y @lark-apaas/miaoda-cli@alpha app sync || echo "[dev] miaoda app sync 失败,按现状继续" >&2
|
|
22
|
+
npx -y @lark-apaas/miaoda-cli@latest app sync || echo "[dev] miaoda app sync 失败,按现状继续" >&2
|
|
25
23
|
|
|
26
24
|
exec node "$SCRIPT_DIR/dev-local.js" "$@"
|