@netpilot/skills 0.3.2 → 0.4.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.
Files changed (84) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/AGENTS.md +25 -9
  5. package/CHANGELOG.md +21 -0
  6. package/README.md +78 -112
  7. package/THIRD_PARTY_NOTICES.md +1 -1
  8. package/agents/codex/architecture-designer.toml +2 -1
  9. package/agents/codex/backend-reviewer.toml +3 -1
  10. package/agents/codex/frontend-reviewer.toml +3 -1
  11. package/agents/codex/test-verifier.toml +4 -1
  12. package/bin/netpilot-skills.mjs +130 -6
  13. package/docs/agent-authoring.md +15 -5
  14. package/package.json +1 -1
  15. package/scripts/sync.mjs +965 -99
  16. package/scripts/validate.mjs +68 -14
  17. package/skills/ask/SKILL.md +51 -47
  18. package/skills/ask/agents/openai.yaml +3 -3
  19. package/skills/code-review/SKILL.md +68 -52
  20. package/skills/code-review/agents/openai.yaml +2 -2
  21. package/skills/codebase-design/SKILL.md +87 -50
  22. package/skills/codebase-design/agents/openai.yaml +2 -2
  23. package/skills/codebase-design/references/deepening.md +60 -0
  24. package/skills/codebase-design/references/design-it-twice.md +54 -0
  25. package/skills/diagnosing-bugs/SKILL.md +124 -54
  26. package/skills/diagnosing-bugs/agents/openai.yaml +2 -2
  27. package/skills/diagnosing-bugs/scripts/hitl-loop.template.mjs +52 -0
  28. package/skills/domain-modeling/SKILL.md +65 -55
  29. package/skills/domain-modeling/agents/openai.yaml +2 -2
  30. package/skills/domain-modeling/references/adr-format.md +47 -0
  31. package/skills/domain-modeling/references/context-format.md +60 -0
  32. package/skills/domain-modeling/references/domain-docs.md +53 -0
  33. package/skills/grill-me/SKILL.md +13 -0
  34. package/skills/grill-me/agents/openai.yaml +6 -0
  35. package/skills/grill-with-docs/SKILL.md +16 -63
  36. package/skills/grill-with-docs/agents/openai.yaml +3 -3
  37. package/skills/grilling/SKILL.md +10 -54
  38. package/skills/grilling/agents/openai.yaml +2 -2
  39. package/skills/handoff/SKILL.md +24 -42
  40. package/skills/handoff/agents/openai.yaml +3 -3
  41. package/skills/implement/SKILL.md +18 -55
  42. package/skills/implement/agents/openai.yaml +3 -3
  43. package/skills/improve-codebase-architecture/SKILL.md +88 -0
  44. package/skills/improve-codebase-architecture/agents/openai.yaml +6 -0
  45. package/skills/improve-codebase-architecture/references/html-report.md +158 -0
  46. package/skills/prototype/SKILL.md +21 -53
  47. package/skills/prototype/agents/openai.yaml +2 -2
  48. package/skills/prototype/references/logic.md +87 -0
  49. package/skills/prototype/references/ui.md +108 -0
  50. package/skills/research/SKILL.md +9 -66
  51. package/skills/research/agents/openai.yaml +2 -2
  52. package/skills/resolving-merge-conflicts/SKILL.md +94 -0
  53. package/skills/resolving-merge-conflicts/agents/openai.yaml +6 -0
  54. package/skills/tdd/SKILL.md +30 -46
  55. package/skills/tdd/agents/openai.yaml +2 -2
  56. package/skills/tdd/references/mocking.md +70 -0
  57. package/skills/tdd/references/tests.md +95 -0
  58. package/skills/teach/SKILL.md +115 -47
  59. package/skills/teach/agents/openai.yaml +3 -3
  60. package/skills/teach/references/glossary-format.md +35 -10
  61. package/skills/teach/references/learning-record-format.md +41 -11
  62. package/skills/teach/references/mission-format.md +20 -17
  63. package/skills/teach/references/resources-format.md +34 -16
  64. package/skills/to-spec/SKILL.md +56 -51
  65. package/skills/to-spec/agents/openai.yaml +3 -3
  66. package/skills/to-tickets/SKILL.md +84 -45
  67. package/skills/to-tickets/agents/openai.yaml +3 -3
  68. package/skills/triage/SKILL.md +171 -0
  69. package/skills/triage/agents/openai.yaml +6 -0
  70. package/skills/triage/references/agent-brief.md +168 -0
  71. package/skills/triage/references/issue-tracker-github.md +42 -0
  72. package/skills/triage/references/issue-tracker-gitlab.md +42 -0
  73. package/skills/triage/references/issue-tracker-local.md +28 -0
  74. package/skills/triage/references/out-of-scope.md +113 -0
  75. package/skills/triage/references/project-config.md +57 -0
  76. package/skills/triage/references/triage-labels.md +13 -0
  77. package/skills/wayfinder/SKILL.md +158 -51
  78. package/skills/wayfinder/agents/openai.yaml +3 -3
  79. package/skills/writing-great-skills/SKILL.md +96 -54
  80. package/skills/writing-great-skills/agents/openai.yaml +3 -3
  81. package/skills/writing-great-skills/references/glossary.md +279 -0
  82. package/agents/codex/code-reader.toml +0 -11
  83. package/skills/grill/SKILL.md +0 -54
  84. package/skills/grill/agents/openai.yaml +0 -6
@@ -10,7 +10,7 @@
10
10
  "name": "netpilot-skills",
11
11
  "source": "./",
12
12
  "description": "中文工程协作 skills 与可组合工作流",
13
- "version": "0.3.2",
13
+ "version": "0.4.0",
14
14
  "author": {
15
15
  "name": "NetPilot"
16
16
  },
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "netpilot-skills",
4
4
  "displayName": "NetPilot Skills",
5
- "version": "0.3.2",
5
+ "version": "0.4.0",
6
6
  "description": "面向 Claude Code 的中文工程协作 skills 与可组合工作流",
7
7
  "author": {
8
8
  "name": "NetPilot"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "netpilot-skills",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "面向 Codex 的中文工程协作 skills 与可组合工作流",
5
5
  "author": {
6
6
  "name": "NetPilot"
package/AGENTS.md CHANGED
@@ -6,27 +6,37 @@
6
6
 
7
7
  - 默认使用中文沟通、中文正文和中文 description;`display_name` 使用由 canonical skill name 派生的英文标题,`short_description` 与 `default_prompt` 使用中文。
8
8
  - skill 目录、frontmatter `name`、代码标识符、命令与技术字段使用英文。
9
+ - 普通过程标题和说明使用中文。对行为有锚定作用的 leading word、领域词、协议字段、label 和代码术语保留英文,并在首次出现时用中文解释;不得让普通导航标题无理由保持全英文。
9
10
  - 同一职责只保留一个主名称;触发与产物重叠时优先合并。
10
11
  - `ask` 是唯一工作流路由入口;不得新增 `clarify`、`ask-*` 等同义入口。
11
- - `grill` 是可由用户或路由器启动的访谈入口,`grilling` 是可复用访谈引擎,两者不得复制同一套流程。
12
+ - `grill-me` 是 stateless、只读且不创建任何本地或远程 artifact 的显式访谈入口;需要文档时显式改用 `grill-with-docs`。`grilling` 是模型可调用的复用访谈引擎;三者不得复制同一套流程。
12
13
 
13
14
  ## Skill 编写
14
15
 
15
16
  - 修改 skill 前读取 `skills/writing-great-skills/SKILL.md`。
16
- - 每个 `SKILL.md` 必须包含清楚的触发条件、不适用边界、完成标准和反模式。
17
+ - 每个 `SKILL.md` 的 description 必须说明触发范围和关键边界。Skill 真正包含顺序 steps 时,每一步在原位置结束于可检查的 completion criterion;reference-only skill 不为此伪造步骤。不得强制追加全局“完成标准”或“反模式”模板,反模式只在它提供上游方法本身的诊断价值时保留。
17
18
  - 新 skill 使用 kebab-case,并通过官方 skill 脚手架创建。
18
19
  - 每个 skill 必须提供 `agents/openai.yaml`;`default_prompt` 显式提到 `$skill-name`。
19
20
  - `display_name` 必须与目录名和 frontmatter `name` 一一对应,例如 `code-review` 显示为 `Code Review`、`tdd` 显示为 `TDD`;不得另造中文别名。
20
- - 当前采用跨宿主单源策略,所有 skill `policy.allow_implicit_invocation` 保持 `true`,通过正文中的权限门禁限制动作。若未来确实需要宿主级禁用隐式调用,必须先建立可验证的宿主专用生成层,不能只修改 Codex metadata。
21
+ - 当前采用跨宿主成对标记:只能由用户启动的 skill Claude frontmatter 设置 `disable-model-invocation: true`,并在 Codex metadata 设置 `policy.allow_implicit_invocation: false`;模型可调用的 skill 省略前者并将后者设为 `true`。校验器必须阻止两端分类不一致。
22
+ - 仓库保存完整的双宿主单源;同步到 Codex 时必须生成确定性投影,移除 `argument-hint`、`disable-model-invocation` 等 Claude-only frontmatter,并保留 `agents/openai.yaml` 中对应的 Codex 行为。官方 skill validator 应验证临时安装后的 Codex 投影,而不是原始双宿主源。
23
+ - user-invoked skill 只能由用户显式调用;其他 skill 可以推荐它,但不能把路由或上游调用自动视为授权。model-invoked skill 可以按正文中声明的调用关系启动。
21
24
  - skill 调用另一 skill 时,说明触发条件、宿主调用形式和返回关系,禁止循环依赖。
22
25
  - 只加入实际需要的 `scripts/`、`references/` 或 `assets/`,不要建立空目录。
23
26
 
24
27
  ## 上游吸收
25
28
 
26
- - 可以吸收优秀方法,但必须重新表达并适配本项目的语言、权限和工具边界。
27
- - 不建立 upstream registry、adoption map 或逐 skill 吸收台账。
29
+ - 吸收上游时采用“保留优先”而不是“摘要优先”:默认认为上游的限定词、判断规则、失败边界、示例和重复强调都可能改变 agent 行为。以语义、步骤顺序、leading words、completion criteria 原位置、示例作用和 progressive disclosure 结构的忠实度为首要目标;不能仅因本地总结更整齐或更短就替换上游方法。
30
+ - 合并或删除上游语句前必须证明它属于允许适配、真正重复或经前向测试确认的 no-op;不得把 `where possible`、`each claim`、`before`/`after`、`only` 等限定词概括成更宽松或更严格的规则。无法证明时保留并翻译。
31
+ - 上游的具体例子只在个人化、失效或与真实宿主冲突时替换;替换后仍须保留例子原本承担的诊断、反例或选择功能。不能用抽象总结代替会帮助 agent 区分相邻分支的例子。
32
+ - 允许的适配限于:去除个人角色与作者口吻、移除不存在的 setup/命令、中文化普通说明、映射真实宿主工具与路径、加入必要权限门禁,以及修复有测试或明确证据支持的矛盾。
33
+ - 不统一扩写短 orchestration skill,不给 reference-first skill 强加流程,不把每个 skill 改成同一套章节。若新增内容与项目通用规则重复,应保留在 `AGENTS.md` 而不是复制进所有 skill。
34
+ - 上游 skill 自带的 `references/`、Markdown 资料和可移植脚本默认保留;若原 skill 因个人化 setup 被移除,把仍有方法价值的资料迁移到职责最接近的现有 skill,并更新 context pointer。
35
+ - 不建立需要长期人工维护的 upstream registry、adoption map 或逐 skill 吸收台账;但测试必须固定本地运行时不可丢失的行为契约和附件。
28
36
  - 复制或实质改编受许可证约束的内容时,只在 `THIRD_PARTY_NOTICES.md` 保留必要声明。
29
- - 不引入个人化角色、作者口吻、默认 commit/push、未经授权的远程 issue 写入或其他扩大权限的行为。
37
+ - 不引入个人化角色、作者口吻或不存在的 setup/命令。
38
+ - 显式调用且仓库、branch、tracker item 与目标状态唯一时,相关 skill 可以按正文执行本地 branch/commit,以及 issue、comment、label、assignment、status 和 close 等 tracker 动作;目标不明时必须预览并询问。
39
+ - 上述授权永不隐式扩展到 push、PR、merge、deploy、publish 或相邻任务;这些动作必须由用户单独明确授权。
30
40
 
31
41
  ## Codex Agent 编写
32
42
 
@@ -35,17 +45,23 @@
35
45
  - agent 保持窄职责和固定返回契约,只保存角色、推理强度与 sandbox;完整前后端规范继续由项目 `AGENTS.md` 和 standards 提供。
36
46
  - 分发 agent 默认不固定 `model`,继承当前会话实际可用模型;用户或项目层可以在确认账号能力后覆盖。代码探索使用低推理只读配置;复杂审查和架构判断根据风险提高推理强度,不能只按“读/写”机械分档。
37
47
  - reviewer 默认 `read-only`。需要运行测试而写缓存的 verifier 可以使用 `workspace-write`,但正文必须禁止修改受版本控制文件、安装依赖和更新快照。
38
- - 用户级 agent 只由 CLI 显式组件安装;项目级 `.codex/agents/` 仍由独立 harness 或项目初始化工具负责。
48
+ - 用户级 agent `@netpilot/skills` 的用户安装流程管理,常规安装默认包含;`--component system-agents` 只用于局部安装。项目级 `.codex/agents/` 仍由独立 harness 或项目初始化工具负责。
39
49
  - skill 引用 custom agent 时使用 `` `agent:<name>` ``,仓库校验必须阻止不存在的 agent 引用。
40
50
 
41
51
  ## 同步与安全
42
52
 
43
53
  - `npm run sync` 默认必须是 dry-run;只有显式 `--apply` 才能写入用户目录。
44
- - 默认组件只有 skills;只有显式 `--component agents` 或 `--component all` 才能写入 `~/.codex/agents`。
54
+ - `npx @netpilot/skills` CLI `install` 默认直接执行用户级安装:默认 host 为 Codex,默认 components 为 skills + agents;`preview` 或 `--dry-run` 才只展示计划。只有显式 `--host claude` 或 `--host all` 才安装 Claude Code Skills。底层 `npm run sync` 仍保持 Codex-only dry-run 默认。npm 在包选择发生前可能复用项目已有本地版本,因此文档必须同时给出强制远程 `latest` 的 `npx @netpilot/skills@latest`,不能把无版本命令错误描述成任何环境下都保证 latest。
55
+ - `--local` 把 Codex skills 安装到当前项目,`--project PATH` 安装到指定项目;Codex 使用项目的 `.agents/skills`。只有显式 `--host claude` 或 `--host all` 才写入 `.claude/skills`。项目范围不安装 agents,项目 `.codex/agents` 仍由独立 harness 或项目工具管理。
45
56
  - 同步只覆盖 manifest 记录且自上次同步后未被用户修改的文件。
57
+ - manifest key 必须采用 canonical 形式并唯一映射到目标文件;非规范 key 或目标碰撞必须整批冲突,不能进入 stale removal。
58
+ - 源中已经删除或改名的受管理文件,仅在安装副本仍与 manifest hash 一致时移除;删除前先在同卷事务目录中原子隔离并复核 hash,再安全清理空的受管理子目录。用户修改过的旧文件必须作为冲突保留。
46
59
  - 未受管理的同名文件必须报冲突并整批停止,不得提供隐式强制覆盖。
60
+ - apply 模式的同步锁必须覆盖 source discovery、manifest 读取、规划和提交;owner 已退出的 stale lock 只能经内容比对后回收,存活 owner 或无法验证的锁不得删除。
61
+ - create、update、remove、manifest 发布及 rollback 都必须使用逐目标 compare-and-swap:最终提交不得覆盖刚出现的文件,回滚不得删除或覆盖事务期间变化的内容;父目录在每次提交前重新检查。
62
+ - 事务 staging 与目标必须位于同一文件系统;合法但跨设备的 mount 必须在写入前给出稳定冲突,不能退化为可覆盖复制或非原子回滚。
47
63
  - 测试必须使用临时 home,禁止触碰真实 `~/.agents`、`~/.claude` 或宿主配置。
48
- - 本仓库不默认安装插件、不修改宿主 settings,也不执行 commit、push、发布或远程写入。
64
+ - 安装器不默认安装插件、不修改宿主 settings,也不替用户执行项目 commit、push、发布或远程写入;skill 运行时的受控动作只以对应 skill 正文为准。
49
65
 
50
66
  ## 交付门禁
51
67
 
package/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  本文件记录用户可观察的版本变化。版本遵循 SemVer;`0.x` 阶段仍可能包含明确说明的兼容性调整。
4
4
 
5
+ ## Unreleased
6
+
7
+ ## 0.4.0
8
+
9
+ - 将工程与生产力方法扩展为 21 个去个人化 skills,按上游原有结构恢复完整工作流、步骤内门禁、方法自身的反模式,以及有实际价值的 `references/` 和跨平台脚本;不再为每个 skill 强加统一尾部章节。
10
+ - 将无文档访谈入口从 `grill` 更名为 canonical `grill-me`,并新增 `improve-codebase-architecture`、`triage` 与 `resolving-merge-conflicts`。
11
+ - 为 Claude Code 与 Codex 建立成对的 user-invoked / model-invoked metadata,并由校验器阻止两端分类漂移和失效的相对文档链接。
12
+ - Codex 同步改为生成确定性的宿主投影:保留双宿主源中的 Claude-only frontmatter,但不再把这些字段写入 Codex skill 安装目录。
13
+ - 显式调用且目标唯一时,相关 workflows 可按正文执行本地 branch/commit 和受控 tracker 写入;push、PR、merge、deploy 与 publish 仍需单独授权。
14
+ - `npx @netpilot/skills` 现在零参数直接安装 Codex 用户 Skills 与 Agents;只有 Claude Code 或双宿主安装才需要显式 `--host claude|all`。`npx @netpilot/skills@latest` 可绕过本地依赖匹配并保证使用 npm `latest`;`--dry-run` 用于预览,底层 `npm run sync` 仍保持 Codex-only dry-run 默认。
15
+ - 新增等价的 `preview` 预览命令;`--local` 与 `--project PATH` 默认只把 Codex Skills 安装到项目范围,显式 `--host all` 时才同步双宿主 Skills,项目 Agent 继续由 Harness 管理。
16
+ - 删除与 Codex 内置 `explorer` 重叠且没有真实调用方的 `code-reader`;reviewer 统一 P0–P3 证据契约,`test-verifier` 增加执行前后工作树完整性证据。
17
+ - apply 锁现在覆盖 source discovery、manifest 读取、规划与提交;owner 已退出的 stale lock 经内容比对后自动回收,存活 owner 或无法验证的锁保持不动。
18
+ - create、update、remove、manifest 发布与 rollback 都采用逐目标 compare-and-swap:旧文件先原子隔离并复核 hash,新文件以无覆盖 hard link 发布,事务期间出现或变化的用户内容不会被覆盖或删除;父目录在每次提交前重新检查,源中已删除或改名的受管理文件仍会安全清理。
19
+ - 同步锁记录先写入完整临时文件再以 hard link 原子发布,避免进程中断留下空锁;若目标目录是 home 内合法但不同设备的 mount,会在写入前给出稳定冲突,而不是降级为非原子复制。
20
+ - 非规范 manifest key、目标碰撞、home 根 symlink/junction 和用户修改过的旧文件继续作为冲突保留;参数错误只输出稳定消息,不泄露 Node 堆栈。
21
+ - 增加 21-skill 集合、附属资料、双宿主调用分类、HITL 脚本和安装包完整性的回归验证。
22
+ - 上游本地化改为 conservation-first:保留会改变执行行为的限定词、失败边界和诊断例子,并以契约测试阻止 `where possible`、`each claim`、提前 handoff、stateless 访谈等语义再次被摘要弱化。
23
+ - 补齐 `wayfinder → prototype` 的窄授权链:明确 prototype ticket 可以生成并提交 throwaway artifact,但仍需另行授权 `implement` 才能写入正式代码。
24
+ - 用零配置发现与可选项目级文档替代个人化 setup:优先读取项目规则和兼容配置,其次从唯一 Git remote 推断 GitHub/GitLab,再回退 Local Markdown;自定义 labels 和 PR/MR request surface 不再通过修改已安装 Skill 保存。
25
+
5
26
  ## 0.3.2
6
27
 
7
28
  - 首次发布公开 npm 包 `@netpilot/skills`,README 默认使用 npm `latest`,团队和 CI 可固定完整版本。
package/README.md CHANGED
@@ -1,151 +1,117 @@
1
1
  # NetPilot Skills
2
2
 
3
- 一套以中文为主、面向 Codex 并兼容 Claude Code 的工程协作 skills,以及少量可选的 Codex custom agents。本仓库只管理跨项目工作流和用户级角色;项目规则、文档骨架与技术栈组合由 [NetPilot Harness](https://github.com/netpilot-z/harness) 管理。
3
+ 面向 Codex、兼容 Claude Code 的中文工程协作 Skills,并附带少量 Codex custom agents。内容覆盖需求澄清、研究、设计、实现、测试、审查、分诊和交接。
4
4
 
5
- ## 安装
5
+ ## 快速安装
6
6
 
7
- 前提:Node.js 版本满足 [`package.json`](package.json) 中的 `engines`。CLI 默认 dry-run,未加 `--apply` 时不会写入用户目录。
8
-
9
- 预览安装计划:
7
+ 要求 Node.js 满足 [`package.json`](package.json) `engines`。推荐直接安装 npm 已发布的 `latest`:
10
8
 
11
9
  ```shell
12
- npx --yes @netpilot/skills install
10
+ npx @netpilot/skills@latest
13
11
  ```
14
12
 
15
- 安装 Codex Skills,或同时安装可选 Agents:
13
+ 也可以使用短命令:
16
14
 
17
15
  ```shell
18
- npx --yes @netpilot/skills install --host codex --apply
19
- npx --yes @netpilot/skills install --host codex --component all --apply
16
+ npx @netpilot/skills
20
17
  ```
21
18
 
22
- Claude Code 使用 `--host claude`。默认只安装 Skills;Codex Agents 不会进入 Claude Code。
19
+ 默认一次性安装当前用户的 Codex Skills(`~/.agents/skills`)和 Codex 用户 Agents(`~/.codex/agents`),不会安装 Claude Code Skills,也不需要额外传入 `--host codex`、`--component all` `--apply`。
20
+
21
+ `npx` 可能优先匹配当前项目中的同名本地依赖;需要保证选择 npm `latest` 时使用带 `@latest` 的命令。团队或 CI 需要可复现安装时,应固定完整 SemVer。
22
+
23
+ 常用高级选项:
23
24
 
24
25
  ```shell
25
- npx --yes @netpilot/skills doctor
26
- npx --yes @netpilot/skills validate
26
+ npx @netpilot/skills preview # 只预览
27
+ npx @netpilot/skills --dry-run # 只预览
28
+ npx @netpilot/skills --host claude # 只安装 Claude Code Skills
29
+ npx @netpilot/skills --host all # 同时安装 Claude Code Skills
30
+ npx @netpilot/skills --component skills # 只安装 Skills
31
+ npx @netpilot/skills --component system-agents
32
+ npx @netpilot/skills --local # 安装到当前项目
33
+ npx @netpilot/skills --project PATH # 安装到指定项目
34
+ npx @netpilot/skills doctor
35
+ npx @netpilot/skills validate
27
36
  ```
28
37
 
29
- 省略版本时使用 npm 的 `latest`。团队或 CI 需要可复现安装时,可在包名后追加经过验证的完整 SemVer。
30
-
31
38
  频繁使用时可以全局安装:
32
39
 
33
40
  ```shell
34
41
  npm install --global @netpilot/skills
35
- netpilot-skills doctor
36
- netpilot-skills install --host codex --component all --apply
42
+ netpilot-skills
37
43
  ```
38
44
 
39
- ## 推荐的初始工作流
45
+ 安装器不会覆盖未受管理或用户修改过的同名文件;发生冲突时整批停止。项目范围只安装 Skills,项目级 Agents 仍由 [NetPilot Harness](https://github.com/netpilot-z/harness) 管理。
40
46
 
41
- Skills 是可组合工具,不是固定瀑布流程。入口不确定时使用 `ask`;主 skill 已经明确时直接调用它。
47
+ ## 核心用法
42
48
 
43
- 首次进入陌生项目,可先让 agent 只读建立最小上下文:
44
-
45
- ```text
46
- 请使用 $ask,只读检查项目规则、README、与当前任务相关的入口、测试和工作树状态,
47
- 不要修改文件;然后为当前任务选择最短且合适的 workflow。
48
- ```
49
+ Codex 使用 `$skill-name`;Claude Code 用户级安装使用 `/skill-name`。入口不确定时从 `ask` 开始,主 Skill 已明确时直接调用。
49
50
 
50
51
  | 场景 | 推荐链路 |
51
52
  | --- | --- |
52
- | 跨会话学习 | `teach按需 research / grilling下一节课` |
53
- | 模糊方向 | `askwayfinderresearch / prototype grillto-spec` |
54
- | 重要新功能 | `grill-with-docs → to-spec → to-tickets → tdd / implement → code-review` |
55
- | 明确的小改动 | `implement → 定向验证` |
53
+ | 模糊方向 | `askwayfinder research / prototypegrill-me → to-spec` |
54
+ | 重要新功能 | `grill-with-docsto-specto-ticketsimplementcode-review` |
55
+ | 明确小改动 | `implement → 定向验证` |
56
56
  | Bug 根因未知 | `diagnosing-bugs → tdd → code-review` |
57
- | 跨会话交付 | `to-specto-tickets 分切片实现与审查handoff` |
57
+ | 跨会话学习 | `teach按需 research / grilling 下一节课` |
58
+ | 跨会话交付 | `to-spec → to-tickets → implement → handoff` |
58
59
 
59
- `grill-with-docs` 仅在需要边访谈边维护 `CONTEXT.md`、领域术语或 ADR 时使用;不写项目文档时改用 `grill`。
60
+ `grill-me` stateless、只读且不创建本地或远程 artifact 的访谈入口;需要同步维护领域文档或 ADR 时使用 `grill-with-docs`。
60
61
 
61
- ## Skill 体系
62
+ 显式调用且目标唯一时,相关 Skills 可以按正文创建本地 branch/commit,或操作明确的 issue、label、assignment 和状态。push、PR、merge、deploy、npm publish 等动作始终需要单独授权。
62
63
 
63
- Codex 使用 `$skill-name`;Claude Code 用户级同步使用 `/skill-name`;Claude Code 插件模式使用 `/netpilot-skills:skill-name`。canonical name 和 UI 标题保持英文,说明与默认提示使用中文。
64
+ ## Skill 体系
64
65
 
65
- | 阶段 | Skill | 作用与适用时机 | 主要产物 |
66
+ | 阶段 | Skill | 适用时机 | 主要产物 |
66
67
  | --- | --- | --- | --- |
67
- | 路由 | `ask` | 入口不确定或关键边界缺失时选择主 skill | 主 skill、已确认边界与下一步 |
68
- | 学习 | `teach` | 在专用目录中跨会话学习一个主题 | Mission、资料、课程、术语与学习记录 |
69
- | 深入确认 | `grill` | 对计划或关键决策进行只读逐题深访 | 事实、决策、假设与未决问题 |
70
- | 深入确认 | `grill-with-docs` | 访谈时同步维护领域文档和 ADR | 更新后的领域文档与决策记录 |
71
- | 深入确认 | `grilling` | 供其他 skill 复用的一次一题访谈引擎 | 可继续执行的共识 |
72
- | 探索 | `wayfinder` | 把巨大或模糊想法收敛成可验证路线 | 候选路径、实验与路线图 |
73
- | 探索 | `research` | 用一手资料核验陌生或快速变化的事实 | 来源、事实、比较与建议 |
74
- | 探索 | `prototype` | 用最小可运行实验验证关键假设 | 实验、证据与继续/停止结论 |
75
- | 设计 | `domain-modeling` | 统一术语、状态、关系和业务不变量 | 术语表、模型与必要 ADR |
76
- | 设计 | `codebase-design` | 设计模块职责、接口、依赖和测试接缝 | 模块边界与测试策略 |
77
- | 交付 | `to-spec` | 将已明确结论整理成可实现规格 | 范围、规则与验收标准 |
78
- | 交付 | `to-tickets` | 将规格拆成可独立验证的垂直任务 | 任务、依赖与验证要求 |
79
- | 交付 | `implement` | 在已批准边界内实施明确任务 | 范围内改动与验证证据 |
80
- | 质量 | `tdd` | RED/GREEN/REFACTOR 保护行为变更 | 测试证据与实现 |
81
- | 质量 | `diagnosing-bugs` | 系统定位尚未证实的根因 | 最小复现、根因与回归建议 |
82
- | 质量 | `code-review` | 审查正确性、风险、测试和架构边界 | 按严重度排列的 findings |
83
- | 连续性 | `handoff` | 为跨会话、agent 或人员交接建立恢复点 | 状态、证据、决策与下一步 |
84
- | 维护 | `writing-great-skills` | 创建、改写、本地化或测试 skill | 可验证的 skill |
85
-
86
- `ask` 始终只有一个。`grill` 是默认访谈入口,`grill-with-docs` 负责同步项目文档,`grilling` 是内部访谈引擎。
87
-
88
- ## Teach:跨会话学习工作区
89
-
90
- `teach` 用于围绕明确目标持续学习,并通过短课程、主动练习、反馈和复习保存可靠进度。它不是 `research` 或工程实施的别名:一次性事实问题使用 `research`,需要修改项目则进入工程工作流。
91
-
92
- | 教学资产 | 作用 |
93
- | --- | --- |
94
- | `MISSION.md` | 学习目标、成功标准、约束和非目标 |
95
- | `RESOURCES.md` | 经筛选并带用途说明的可信资料 |
96
- | `GLOSSARY.md` | 已经理解并能正确使用的术语 |
97
- | `lessons/` | 每次一个目标的短课程与练习 |
98
- | `learning-records/` | 有练习证据支持的掌握记录 |
99
- | `NOTES.md` | 稳定教学偏好和必要工作笔记 |
100
-
101
- 开始时可直接说:
102
-
103
- ```text
104
- 请使用 $teach,在我指定的独立学习目录中建立学习项目。
105
- 先确认可观察的成功标准并做简短基础诊断,再安排第一节最小课程。
106
- ```
107
-
108
- `teach` 只维护用户确认的教学目录,不修改业务代码、项目配置、Git 状态或远程资源。
109
-
110
- ## Codex Subagents(可选)
111
-
112
- 完整规则保存在项目 `AGENTS.md` 和 standards 中;skill 保存跨宿主工作流;custom agent 只定义窄职责、推理强度、sandbox 和返回格式。模型默认继承当前 Codex 会话,避免绑定特定账号能力。
113
-
114
- | Agent type | 作用 | Model | Reasoning | Sandbox |
115
- | --- | --- | --- | --- | --- |
116
- | `code-reader` | 快速只读定位职责、调用链、配置和测试 | 继承会话 | `low` | `read-only` |
117
- | `frontend-reviewer` | 审查前端状态、交互、可访问性和测试风险 | 继承会话 | `high` | `read-only` |
118
- | `backend-reviewer` | 审查接口、权限、事务、幂等和数据一致性 | 继承会话 | `high` | `read-only` |
119
- | `architecture-designer` | 比较模块边界、依赖、数据流和迁移路径 | 继承会话 | `high` | `read-only` |
120
- | `test-verifier` | 执行测试、类型检查、lint 和构建并压缩证据 | 继承会话 | `medium` | `workspace-write` |
121
-
122
- 配置位于 `agents/codex/*.toml`。完整边界见 [`docs/agent-authoring.md`](docs/agent-authoring.md)。
123
-
124
- ## 从源码或插件使用
125
-
126
- 从源码同步默认只展示计划:
127
-
128
- ```shell
129
- npm run sync
130
- npm run sync -- --apply
131
- npm run sync -- --host codex --component all --apply
132
- ```
133
-
134
- 同步器只更新由本项目管理且用户未修改的文件;冲突会在写入前整批停止,不提供 `--force`。写入前会拒绝 symlink/junction 目标;异常中断时保留 staging 证据,不承诺断电级事务。状态保存在 `~/.netpilot-skills/manifest.json`。
135
-
136
- 仓库也包含 Codex 与 Claude Code plugin manifest。不要同时安装插件副本和普通用户级 Skills,以免出现重复名称。Claude Code 本地验证:
137
-
138
- ```shell
139
- claude plugin validate ./.claude-plugin/plugin.json --strict
140
- claude plugin validate ./.claude-plugin/marketplace.json --strict
141
- claude --plugin-dir .
142
- ```
143
-
144
- ## 开发与验证
68
+ | 路由 | `ask` | 入口或关键边界不清楚 | 主 Skill 与已确认边界 |
69
+ | 学习 | `teach` | 建立跨会话学习项目 | 课程、资料与学习记录 |
70
+ | 访谈 | `grill-me` | 深入盘问但不写文档 | 当前对话中的共识 |
71
+ | 访谈 | `grill-with-docs` | 访谈时同步沉淀文档 | 领域文档与 ADR |
72
+ | 访谈 | `grilling` | 供其他 Skills 复用访谈 | 已确认决定与未决分支 |
73
+ | 探索 | `wayfinder` | 大型工作仍处于 fog of war | Decision map 与 frontier |
74
+ | 探索 | `research` | 核验陌生或变化中的事实 | 带一手引用的研究文档 |
75
+ | 探索 | `prototype` | 用低成本实验验证假设 | Throwaway artifact 与 verdict |
76
+ | 设计 | `domain-modeling` | 统一术语、状态和不变量 | Glossary、模型与必要 ADR |
77
+ | 设计 | `codebase-design` | 判断 Module、Interface 和 Seam | 设计词汇与接口比较 |
78
+ | 设计 | `improve-codebase-architecture` | 扫描架构摩擦和 deepening 机会 | HTML 报告与候选项 |
79
+ | 交付 | `to-spec` | 把已确认结论整理为规格 | Spec issue 与验收标准 |
80
+ | 交付 | `to-tickets` | 把规格拆成垂直任务 | Tickets、blocking 与 frontier |
81
+ | 交付 | `implement` | 按明确规格实际实施 | 代码、验证与受控 commit |
82
+ | 质量 | `tdd` | 可观察行为需要 RED/GREEN | 测试与最小实现 |
83
+ | 质量 | `diagnosing-bugs` | 真实根因尚不明确 | 最小复现、根因与证据 |
84
+ | 质量 | `code-review` | 审查 diff、commit 或 PR | Standards + Spec findings |
85
+ | 质量 | `resolving-merge-conflicts` | 解决 merge/rebase 冲突 | 已验证的冲突解决结果 |
86
+ | 维护 | `triage` | 推进 issue 或外部 PR | 标签、brief、评论或关闭结果 |
87
+ | 连续性 | `handoff` | 跨会话或人员交接 | 可恢复的状态与下一步 |
88
+ | 维护 | `writing-great-skills` | 创建、本地化或审查 Skill | 可验证的 Skill |
89
+
90
+ ## Codex Agents
91
+
92
+ | Agent | 用途 | 默认配置 |
93
+ | --- | --- | --- |
94
+ | `frontend-reviewer` | 前端状态、交互、可访问性和测试审查 | high / read-only |
95
+ | `backend-reviewer` | 接口、权限、事务和数据一致性审查 | high / read-only |
96
+ | `architecture-designer` | 模块边界、依赖和迁移方案比较 | high / read-only |
97
+ | `test-verifier` | 执行测试、类型检查、lint 和构建 | medium / workspace-write |
98
+
99
+ Agents 默认继承当前 Codex 会话模型。代码定位直接使用 Codex 内置 `explorer`;详细配置见 [`docs/agent-authoring.md`](docs/agent-authoring.md)。
100
+
101
+ ## 项目配置与安全
102
+
103
+ - Tracker 默认从项目规则和唯一 Git remote 自动发现;自定义配置见 [`skills/triage/references/project-config.md`](skills/triage/references/project-config.md)。
104
+ - 双宿主调用 metadata 由仓库校验器保持一致;调用分类不等于写入权限。
105
+ - 同步器只更新本项目管理且用户未修改的文件,不提供隐式强制覆盖。
106
+ - 上游方法采用 conservation-first 本地化:保留限定词、步骤顺序、失败边界、诊断例子和有方法价值的附件,只移除个人化表达、不存在的命令,并适配真实宿主权限。
107
+
108
+ ## 开发
145
109
 
146
110
  ```shell
147
111
  npm run verify
148
112
  npm run doctor
113
+ npm run sync # dry-run
114
+ npm run sync -- --apply # 写入用户目录
149
115
  ```
150
116
 
151
- 项目规范见 [AGENTS.md](./AGENTS.md),版本变化见 [CHANGELOG.md](./CHANGELOG.md),第三方声明见 [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md)。本项目使用 MIT License;上游内容经过中文化、去个人化和权限收敛,不全量复制上游仓库。
117
+ 项目规范见 [AGENTS.md](AGENTS.md),版本变化见 [CHANGELOG.md](CHANGELOG.md),安全政策见 [SECURITY.md](SECURITY.md),第三方声明见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)
@@ -1,6 +1,6 @@
1
1
  # 第三方声明
2
2
 
3
- 本仓库的部分工作流结构与方法由 [mattpocock/skills](https://github.com/mattpocock/skills) 翻译、蒸馏并重新适配。本地版本去除了个人化角色,改写为中文,并增加了权限、安全、验证与双宿主约束。
3
+ 本仓库的部分工作流结构、方法与附属资料源自 [mattpocock/skills](https://github.com/mattpocock/skills)。本地版本以保留原有语义、步骤顺序、leading words、示例作用和 progressive-disclosure 关系为目标,在此基础上完成中文化、去个人化、宿主映射与必要的权限和安全适配。
4
4
 
5
5
  无需维护逐 skill 的来源表或吸收记录;本文件仅保留许可证要求所需的最小声明。
6
6
 
@@ -7,5 +7,6 @@ developer_instructions = """
7
7
  明确目标、质量属性和不可改变的边界,再画出现状模块、依赖、数据流、失败面和测试接缝。
8
8
  提出最少数量的可行方案,用一致维度比较复杂度、耦合、演进性、迁移成本、可逆性和风险,并给出推荐及反对理由。
9
9
  不要修改代码或文档,不要创建 ADR,不要为了未来可能性提前抽象,也不要脱离仓库证据设计理想化系统。
10
- 向主 agent 返回现状证据、候选方案、推荐边界、迁移切片、需要用户决定的取舍和验证方式。
10
+ 返回固定结果:status 只能是 completed 或 blocked,并包含 current_state、options、recommendation、migration_slices、validation、decisions 和 unknowns。
11
+ current_state 和每个 option 必须带可定位仓库证据;关键上下文不足以比较方案时返回 blocked,不能用理想化假设补齐。
11
12
  """
@@ -7,5 +7,7 @@ developer_instructions = """
7
7
  先读取适用的 AGENTS.md、规格、后端标准、接口契约、数据模型和完整 diff,再追踪必要的调用方、迁移与测试。
8
8
  重点检查输入验证、认证授权、租户隔离、事务边界、并发与竞态、幂等、错误语义、重试、资源释放、日志与指标以及回归测试。
9
9
  不要修改文件,不要执行生产或数据写入,不要把缺少个人偏好的抽象当成问题。
10
- 每个 finding 返回严重度、文件与行、可复现路径、影响和最小修复方向;明确区分已证实问题、未知项和建议验证。
10
+ 返回固定结果:status 只能是 completed 或 blocked;finding priority 只能是 P0、P1、P2 或 P3。
11
+ 每个 finding 返回 file 与 line、trigger、impact、evidence 和 minimal fix,并明确区分已证实问题、未知项和建议验证。
12
+ 没有可执行问题时显式返回 no findings;最后列出 unknowns 与未执行验证,不用建议代替证据。
11
13
  """
@@ -7,5 +7,7 @@ developer_instructions = """
7
7
  先读取适用的 AGENTS.md、规格、前端标准、设计系统约束和完整 diff,再检查必要的调用方与测试。
8
8
  重点检查行为正确性、状态同步、竞态与取消、错误和加载状态、键盘与屏幕阅读器可用性、组件职责、渲染成本以及测试缺口。
9
9
  不要修改文件,不要安装依赖,不要把纯风格偏好或无法证明影响的猜测列为 finding。
10
- 每个 finding 返回严重度、文件与行、触发条件、实际影响和最小修复方向;最后列出未决问题与未执行验证。
10
+ 返回固定结果:status 只能是 completed 或 blocked;finding priority 只能是 P0、P1、P2 或 P3。
11
+ 每个 finding 返回 file 与 line、trigger、impact、evidence 和 minimal fix,并明确区分已证实问题与推断。
12
+ 没有可执行问题时显式返回 no findings;最后列出 unknowns 与未执行验证,不用建议代替证据。
11
13
  """
@@ -4,8 +4,11 @@ model_reasoning_effort = "medium"
4
4
  sandbox_mode = "workspace-write"
5
5
  developer_instructions = """
6
6
  先读取适用的 AGENTS.md、package scripts、测试说明和主 agent 给出的变更范围,选择最小充分的现有验证命令。
7
+ 执行前后运行 `git status --short` 或项目认可的等价检查,记录基线和新增变化;不得清理、回滚或隐藏用户已有改动。
7
8
  可以运行会产生正常缓存、coverage 或临时构建产物的测试工具,但不得修改受版本控制的源码、测试、配置或快照。
8
9
  不要安装或升级依赖,不要删除文件,不要弱化断言,不要用跳过检查换取绿色结果。
9
10
  记录实际命令、退出码和关键输出;失败时定位到最可能的阶段并保留原始错误含义,不擅自修复。
10
- 向主 agent 返回已通过、失败、未执行及其原因,并区分由当前变更引起的失败和环境限制。
11
+ 固定返回 status、commands、passed_checks、failed_checks、skipped_checks、baseline_worktree、final_worktree、workspace_change 和 environment_limits。
12
+ status 只能是 passed、failed 或 blocked:全部必需检查成功且没有新增受版本控制 diff 才能是 passed;检查发现失败时是 failed;命令、依赖或环境不可用导致必需检查无法执行时是 blocked。
13
+ 区分由当前变更引起的失败和环境限制。若验证新增了受版本控制的 diff,结果不得返回 passed,必须保留现场并交给主 agent 判断。
11
14
  """
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { spawnSync } from "node:child_process";
4
- import { readFileSync } from "node:fs";
4
+ import { lstatSync, readFileSync } from "node:fs";
5
5
  import path from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
 
8
8
  const packageRoot = fileURLToPath(new URL("..", import.meta.url));
9
9
  const commands = Object.freeze({
10
10
  install: "scripts/sync.mjs",
11
+ preview: "scripts/sync.mjs",
11
12
  sync: "scripts/sync.mjs",
12
13
  doctor: "scripts/doctor.mjs",
13
14
  validate: "scripts/validate.mjs",
@@ -17,13 +18,21 @@ function printHelp() {
17
18
  console.log(`NetPilot Skills CLI
18
19
 
19
20
  用法:
20
- netpilot-skills [install] [--host codex|claude|all] [--component skills|agents|all] [--home PATH] [--apply]
21
+ netpilot-skills [install] [--host codex|claude|all] [--component skills|system-agents|agents|all] [--home PATH] [--dry-run]
22
+ netpilot-skills preview [--host codex|claude|all] [--component skills|system-agents|agents|all] [--home PATH]
23
+ netpilot-skills [install|preview] --local [--host codex|claude|all]
24
+ netpilot-skills [install|preview] --project PATH [--host codex|claude|all]
25
+ netpilot-skills sync [--host codex|claude|all] [--component skills|system-agents|agents|all] [--home PATH] [--apply]
21
26
  netpilot-skills doctor
22
27
  netpilot-skills validate
23
28
  netpilot-skills --version
24
29
 
25
- install 默认只执行 dry-run。确认计划无冲突后,再追加 --apply。
26
- 默认只安装 skills;Codex agents 必须显式选择 --component agents all。
30
+ install 默认直接写入,默认安装 Codex skills 与 agents;--dry-run 或 preview 仅预览。
31
+ sync npm run sync 保持默认 dry-run,只有显式 --apply 才写入。
32
+ --local 安装到当前项目;--project PATH 安装到指定项目。项目范围默认安装 Codex skills。
33
+ 只有安装 Claude Code skills 时才显式传入 --host claude 或 --host all。
34
+ --host、--component 和 --home 用于宿主、组件或自定义用户目录等高级覆盖。
35
+ system-agents 是用户全局 agents 的语义化别名,目标为 ~/.codex/agents。
27
36
  省略命令或直接传入安装参数时,等同于 install。`);
28
37
  }
29
38
 
@@ -32,11 +41,114 @@ function packageVersion() {
32
41
  return manifest.version;
33
42
  }
34
43
 
44
+ function hasOption(arguments_, option) {
45
+ return arguments_.includes(option);
46
+ }
47
+
48
+ function assertProjectDirectory(projectDir) {
49
+ const stats = lstatSync(projectDir, { throwIfNoEntry: false });
50
+ if (!stats) throw new Error(`项目目录不存在:${projectDir}`);
51
+ if (!stats.isDirectory() || stats.isSymbolicLink()) {
52
+ throw new Error(`项目目标必须是普通目录:${projectDir}`);
53
+ }
54
+ }
55
+
56
+ function prepareInstallArguments(rawArguments, { preview = false } = {}) {
57
+ const commandArguments = [];
58
+ let projectDir = null;
59
+ let scopeOption = null;
60
+ let homeSpecified = false;
61
+ let component = null;
62
+
63
+ for (let index = 0; index < rawArguments.length; index += 1) {
64
+ const argument = rawArguments[index];
65
+ if (argument === "--local") {
66
+ if (scopeOption) throw new Error("--local 与 --project 不能同时使用");
67
+ scopeOption = "--local";
68
+ projectDir = path.resolve(process.cwd());
69
+ continue;
70
+ }
71
+ if (argument === "--project") {
72
+ if (scopeOption) throw new Error("--local 与 --project 不能同时使用");
73
+ const requestedProject = rawArguments[index + 1];
74
+ if (!requestedProject || requestedProject.startsWith("-")) {
75
+ throw new Error("--project 需要一个目录路径");
76
+ }
77
+ scopeOption = "--project";
78
+ projectDir = path.resolve(requestedProject);
79
+ index += 1;
80
+ continue;
81
+ }
82
+ if (argument === "--home") {
83
+ const requestedHome = rawArguments[index + 1];
84
+ if (!requestedHome || requestedHome.startsWith("-")) {
85
+ throw new Error("--home 需要一个目录路径");
86
+ }
87
+ homeSpecified = true;
88
+ commandArguments.push(argument, requestedHome);
89
+ index += 1;
90
+ continue;
91
+ }
92
+ if (argument === "--host") {
93
+ const requestedHost = rawArguments[index + 1];
94
+ if (!requestedHost || requestedHost.startsWith("-")) {
95
+ throw new Error("--host 需要 codex、claude 或 all");
96
+ }
97
+ commandArguments.push(argument, requestedHost);
98
+ index += 1;
99
+ continue;
100
+ }
101
+ if (argument === "--component") {
102
+ const requestedComponent = rawArguments[index + 1];
103
+ if (!requestedComponent || requestedComponent.startsWith("-")) {
104
+ throw new Error("--component 需要 skills、system-agents、agents 或 all");
105
+ }
106
+ component = requestedComponent;
107
+ commandArguments.push(argument, requestedComponent);
108
+ index += 1;
109
+ continue;
110
+ }
111
+ commandArguments.push(argument);
112
+ }
113
+
114
+ if (projectDir) {
115
+ if (homeSpecified) throw new Error("--local/--project 与 --home 不能同时使用");
116
+ if (component && component !== "skills") {
117
+ throw new Error("项目范围只支持 --component skills;Codex 项目 agents 由项目工具管理");
118
+ }
119
+ assertProjectDirectory(projectDir);
120
+ commandArguments.push("--home", projectDir);
121
+ if (!component) commandArguments.push("--component", "skills");
122
+ }
123
+
124
+ if (preview) {
125
+ if (hasOption(commandArguments, "--apply")) {
126
+ throw new Error("preview 不能与 --apply 一起使用");
127
+ }
128
+ if (!hasOption(commandArguments, "--dry-run")) commandArguments.push("--dry-run");
129
+ } else if (
130
+ !hasOption(commandArguments, "--apply") &&
131
+ !hasOption(commandArguments, "--dry-run")
132
+ ) {
133
+ commandArguments.push("--apply");
134
+ }
135
+
136
+ return commandArguments;
137
+ }
138
+
35
139
  function run() {
36
140
  const rawArguments = process.argv.slice(2);
37
141
  const firstArgument = rawArguments[0];
142
+ const knownOrImplicitCommand =
143
+ firstArgument === undefined ||
144
+ firstArgument.startsWith("-") ||
145
+ Object.hasOwn(commands, firstArgument);
38
146
 
39
- if (firstArgument === "--help" || firstArgument === "-h" || firstArgument === "help") {
147
+ if (
148
+ firstArgument === "help" ||
149
+ (knownOrImplicitCommand &&
150
+ rawArguments.some((argument) => argument === "--help" || argument === "-h"))
151
+ ) {
40
152
  printHelp();
41
153
  return;
42
154
  }
@@ -47,7 +159,7 @@ function run() {
47
159
 
48
160
  const implicitInstall = firstArgument === undefined || firstArgument.startsWith("-");
49
161
  const command = implicitInstall ? "install" : firstArgument;
50
- const commandArguments = implicitInstall ? rawArguments : rawArguments.slice(1);
162
+ const rawCommandArguments = implicitInstall ? rawArguments : rawArguments.slice(1);
51
163
  const script = commands[command];
52
164
 
53
165
  if (!script) {
@@ -57,6 +169,18 @@ function run() {
57
169
  return;
58
170
  }
59
171
 
172
+ let commandArguments;
173
+ try {
174
+ commandArguments =
175
+ command === "install" || command === "preview"
176
+ ? prepareInstallArguments(rawCommandArguments, { preview: command === "preview" })
177
+ : [...rawCommandArguments];
178
+ } catch (error) {
179
+ console.error(error.message);
180
+ process.exitCode = 1;
181
+ return;
182
+ }
183
+
60
184
  const result = spawnSync(process.execPath, [path.join(packageRoot, script), ...commandArguments], {
61
185
  stdio: "inherit",
62
186
  windowsHide: true,