Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to @rpamis/comet will be documented in this file.

## What's Changed [0.4.0-beta.4] - 2026-07-11

### Fixed

- **Global artifact language**: Global `comet init` and `comet update` now persist the selected artifact language in `~/.comet/config.yaml`, and Classic workflows resolve project configuration before falling back to that global default, so globally installed Chinese Skills create and validate OpenSpec and Superpowers artifacts in `zh-CN` while still allowing per-project overrides ([#174](https://github.com/rpamis/comet/issues/174)).

## What's Changed [0.4.0-beta.3] - 2026-07-08

### Fixed
Expand Down
3 changes: 3 additions & 0 deletions app/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
copyCometRulesForPlatform,
installCometHooksForPlatform,
createWorkingDirs,
mergeProjectConfig,
} from '../../domains/skill/platform-install.js';
import { LANGUAGES, type LanguageConfig } from '../../domains/skill/languages.js';
import { installOpenSpec, isCommandAvailable } from '../../domains/integrations/openspec.js';
Expand Down Expand Up @@ -568,6 +569,8 @@ export async function initCommand(targetPath: string, options: InitOptions = {})

if (scope === 'project') {
await createWorkingDirs(projectPath, language.artifactLanguage);
} else {
await mergeProjectConfig(baseDir, language.artifactLanguage);
}

if (options.json) {
Expand Down
28 changes: 25 additions & 3 deletions app/commands/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
getManifestSkills,
mergeProjectConfig,
} from '../../domains/skill/platform-install.js';
import { LANGUAGES } from '../../domains/skill/languages.js';
import {
PLATFORMS,
getPlatformSkillsDir,
Expand Down Expand Up @@ -61,6 +62,10 @@ function languageToSkillsDir(languageId: SkillLanguage): string {
return languageId === 'zh' ? 'skills-zh' : 'skills';
}

function languageToArtifactLanguage(languageId: SkillLanguage): 'en' | 'zh-CN' {
return LANGUAGES.find((entry) => entry.id === languageId)!.artifactLanguage;
}

function getScopedBaseDir(
scope: InstallScope,
projectPath: string,
Expand Down Expand Up @@ -416,9 +421,26 @@ export async function updateCommand(
}
}

const hasProjectTargets = targets.some((target) => target.scope === 'project');
if (hasProjectTargets) {
await mergeProjectConfig(projectPath);
for (const scope of ['project', 'global'] as const) {
const scopeTargets = targets.filter((candidate) => candidate.scope === scope);
if (scopeTargets.length === 0) continue;
// An explicit --language always wins. Otherwise only force the persisted language when
// every platform installed at this scope agrees — if two platforms disagree (e.g. one
// installed with English skills, another with Chinese) and the user didn't say which one
// they mean, guessing from array order would silently override whatever language they
// (or a prior install) already configured. Pass null in that case so mergeProjectConfig
// preserves the existing config's language instead of guessing.
const agreedLanguage = scopeTargets.every((t) => t.language === scopeTargets[0].language)
? scopeTargets[0].language
: undefined;
const languageId = options.language
? resolveTargetLanguage(options.language, scopeTargets[0].language)
: agreedLanguage;
const configRoot = getBaseDir(scope, projectPath);
await mergeProjectConfig(
configRoot,
languageId ? languageToArtifactLanguage(languageId) : null,
);
log(` ${t(lang, 'configMerged')}`);
}

Expand Down
2 changes: 1 addition & 1 deletion assets/manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.4.0-beta.3",
"version": "0.4.0-beta.4",
"skills": [
"comet/SKILL.md",
"comet/reference/auto-transition.md",
Expand Down
2 changes: 1 addition & 1 deletion assets/skills-zh/comet-hotfix/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ description: "Use when 用户要修复已有行为 bug,且不新增 capability

### 0. 输出语言约束

精简版 OpenSpec 产物必须使用 Comet 配置产物语言。`.comet.yaml` 尚不存在时读取 `.comet/config.yaml` 的 `language`,初始化后使用 `"$COMET_BASH" "$COMET_STATE" get <name> language` 读取。
精简版 OpenSpec 产物必须使用 Comet 配置产物语言。`.comet.yaml` 尚不存在时依次读取项目 `.comet/config.yaml` 和全局 `~/.comet/config.yaml` 的 `language`,初始化后使用 `"$COMET_BASH" "$COMET_STATE" get <name> language` 读取。

执行链路:open → build → verify → archive。Hotfix 为每个阶段提供默认决策:精简开启、直接构建、按规模验证、验证通过后进入归档前最终确认。

Expand Down
2 changes: 1 addition & 1 deletion assets/skills-zh/comet-open/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ description: "Use when Comet 需要创建新的 OpenSpec change,或 active cha

### 0. 输出语言约束

传递给 OpenSpec 的所有提问和产物要求都必须包含解析后的 Comet 产物语言,并使用 `en`、`zh-CN` 这类规范化 ID。`.comet.yaml` 尚不存在时读取 `.comet/config.yaml` 的 `language`;change 初始化后使用 `"$COMET_BASH" "$COMET_STATE" get <name> language` 读取。没有配置语言时才回退到当前用户请求语言。生成的 `proposal.md`、`design.md`、`tasks.md` 必须以该语言为主语言。
传递给 OpenSpec 的所有提问和产物要求都必须包含解析后的 Comet 产物语言,并使用 `en`、`zh-CN` 这类规范化 ID。`.comet.yaml` 尚不存在时依次读取项目 `.comet/config.yaml` 和全局 `~/.comet/config.yaml` 的 `language`;change 初始化后使用 `"$COMET_BASH" "$COMET_STATE" get <name> language` 读取。没有配置语言时才回退到当前用户请求语言。生成的 `proposal.md`、`design.md`、`tasks.md` 必须以该语言为主语言。

### 1. 探索想法与需求澄清

Expand Down
2 changes: 1 addition & 1 deletion assets/skills-zh/comet-tweak/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Tweak 是 Comet 五阶段能力的预设工作流,不是独立的平行流程

### 0. 输出语言约束

精简版 OpenSpec 产物必须使用 Comet 配置产物语言。`.comet.yaml` 尚不存在时读取 `.comet/config.yaml` 的 `language`,初始化后使用 `"$COMET_BASH" "$COMET_STATE" get <name> language` 读取。
精简版 OpenSpec 产物必须使用 Comet 配置产物语言。`.comet.yaml` 尚不存在时依次读取项目 `.comet/config.yaml` 和全局 `~/.comet/config.yaml` 的 `language`,初始化后使用 `"$COMET_BASH" "$COMET_STATE" get <name> language` 读取。

执行链路:open → OpenSpec apply → verify → archive。Tweak 为每个阶段提供默认决策:精简开启、通过 OpenSpec apply 直接构建、按规模与 delta spec 判定验证轻重、验证通过后进入归档前最终确认。

Expand Down
2 changes: 1 addition & 1 deletion assets/skills-zh/comet/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ agent 做决策只需读本节,参考附录按需查阅。

### 输出语言规则

所有 OpenSpec 和 Superpowers 产物都必须使用 Comet 配置的产物语言。配置值是规范化语言 ID,`en` 或 `zh-CN`。已有 change 优先通过 `"$COMET_BASH" "$COMET_STATE" get <name> language` 读取 `openspec/changes/<name>/.comet.yaml` 中的 `language`;`.comet.yaml` 尚不存在时读取 `.comet/config.yaml` 的 `language`;两者都不存在时才回退到当前用户请求语言。调用外部 OpenSpec/Superpowers skill 时,必须把解析后的语言显式写入 prompt 或 ARGUMENTS。
所有 OpenSpec 和 Superpowers 产物都必须使用 Comet 配置的产物语言。配置值是规范化语言 ID,`en` 或 `zh-CN`。已有 change 优先通过 `"$COMET_BASH" "$COMET_STATE" get <name> language` 读取 `openspec/changes/<name>/.comet.yaml` 中的 `language`;`.comet.yaml` 尚不存在时依次读取项目 `.comet/config.yaml` 和全局 `~/.comet/config.yaml` 的 `language`;都不存在时才回退到当前用户请求语言。调用外部 OpenSpec/Superpowers skill 时,必须把解析后的语言显式写入 prompt 或 ARGUMENTS。

### 阶段自动检测

Expand Down
4 changes: 2 additions & 2 deletions assets/skills-zh/comet/reference/comet-yaml-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

规范路径:`comet/reference/comet-yaml-fields.md`

本文件是 `openspec/changes/<name>/` 下每个 change 级 `.comet.yaml` 状态文件的字段参考。按需查阅,不随 skill 一次性加载。项目级默认配置只放在 `.comet/config.yaml`。
本文件是 `openspec/changes/<name>/` 下每个 change 级 `.comet.yaml` 状态文件的字段参考。按需查阅,不随 skill 一次性加载。项目级默认配置放在 `.comet/config.yaml`,全局默认配置放在 `~/.comet/config.yaml`;项目配置优先于全局配置

## 示例

Expand Down Expand Up @@ -34,7 +34,7 @@ archived: false
| 字段 | 含义 |
|------|------|
| `workflow` | `full`、`hotfix` 或 `tweak` |
| `language` | 产物语言,仅支持 `en` 或 `zh-CN`。由 `comet init` 的初始化语言写入 `.comet/config.yaml`,创建 change 时快照到 `.comet.yaml`,用于约束 OpenSpec / Superpowers 产物主语言 |
| `language` | 产物语言,仅支持 `en` 或 `zh-CN`。由 `comet init` 按安装范围写入项目或全局 `.comet/config.yaml`,创建 change 时按“项目优先、全局回退”快照到 `.comet.yaml`,用于约束 OpenSpec / Superpowers 产物主语言 |
| `phase` | 当前阶段:`open`、`design`、`build`、`verify`、`archive`(init 统一设为 `open`,guard 负责过渡) |
| `design_doc` | 关联的 Superpowers Design Doc 路径,可为空 |
| `plan` | 关联的 Superpowers Plan 路径,可为空 |
Expand Down
2 changes: 1 addition & 1 deletion assets/skills/comet-hotfix/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Quick bug fix workflow: open → build → verify → archive. Skip brainstormin

### 0. Output Language Constraint

Streamlined OpenSpec artifacts must use the configured Comet artifact language. Read `language` from `.comet/config.yaml` before `.comet.yaml` exists, then use `"$COMET_BASH" "$COMET_STATE" get <name> language` after initialization.
Streamlined OpenSpec artifacts must use the configured Comet artifact language. Before `.comet.yaml` exists, read `language` from project `.comet/config.yaml`, then fall back to global `~/.comet/config.yaml`; after initialization, use `"$COMET_BASH" "$COMET_STATE" get <name> language`.

Execution chain: open → build → root cause check → verify → archive. Hotfix provides default decisions for each phase: streamlined open, direct build, root cause confirmation, scale-based verification, and final archive confirmation after verification passes.

Expand Down
2 changes: 1 addition & 1 deletion assets/skills/comet-open/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ description: "Use when Comet needs to create a new OpenSpec change, or an active

### 0. Output Language Constraint

Every prompt and artifact request passed to OpenSpec must include the resolved Comet artifact language, using normalized ids such as `en` or `zh-CN`. Before `.comet.yaml` exists, read `language` from `.comet/config.yaml`; after the change is initialized, use `"$COMET_BASH" "$COMET_STATE" get <name> language`. If no configured language exists, fall back to the current user request language. The generated `proposal.md`, `design.md`, and `tasks.md` must use that language as their main language.
Every prompt and artifact request passed to OpenSpec must include the resolved Comet artifact language, using normalized ids such as `en` or `zh-CN`. Before `.comet.yaml` exists, read `language` from project `.comet/config.yaml`, then fall back to global `~/.comet/config.yaml`; after the change is initialized, use `"$COMET_BASH" "$COMET_STATE" get <name> language`. If no configured language exists, fall back to the current user request language. The generated `proposal.md`, `design.md`, and `tasks.md` must use that language as their main language.

### 1. Explore Ideas and Clarify Requirements

Expand Down
2 changes: 1 addition & 1 deletion assets/skills/comet-tweak/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Applicable for OpenSpec-chained lightweight changes, such as configuration adjus

### 0. Output Language Constraint

Streamlined OpenSpec artifacts must use the configured Comet artifact language. Read `language` from `.comet/config.yaml` before `.comet.yaml` exists, then use `"$COMET_BASH" "$COMET_STATE" get <name> language` after initialization.
Streamlined OpenSpec artifacts must use the configured Comet artifact language. Before `.comet.yaml` exists, read `language` from project `.comet/config.yaml`, then fall back to global `~/.comet/config.yaml`; after initialization, use `"$COMET_BASH" "$COMET_STATE" get <name> language`.

Execution chain: open → OpenSpec apply → verify → archive. Tweak provides default decisions for each phase: streamlined open, direct build through OpenSpec apply, scale- and delta-spec-driven verification weight, and final archive confirmation after verification passes.

Expand Down
2 changes: 1 addition & 1 deletion assets/skills/comet/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Agents need only read this section for decision-making. Refer to the Reference A

### Output Language Rule

Use the configured Comet artifact language as the output language for every OpenSpec and Superpowers artifact. The configured value is a normalized language id, `en` or `zh-CN`. For an existing change, read `language` from `openspec/changes/<name>/.comet.yaml` using `"$COMET_BASH" "$COMET_STATE" get <name> language`. Before `.comet.yaml` exists, read `language` from `.comet/config.yaml`; if neither exists, fall back to the current user request language. Include the resolved language explicitly in every prompt or ARGUMENTS passed to external OpenSpec/Superpowers skills.
Use the configured Comet artifact language as the output language for every OpenSpec and Superpowers artifact. The configured value is a normalized language id, `en` or `zh-CN`. For an existing change, read `language` from `openspec/changes/<name>/.comet.yaml` using `"$COMET_BASH" "$COMET_STATE" get <name> language`. Before `.comet.yaml` exists, read `language` from project `.comet/config.yaml`, then fall back to global `~/.comet/config.yaml`; if neither exists, fall back to the current user request language. Include the resolved language explicitly in every prompt or ARGUMENTS passed to external OpenSpec/Superpowers skills.

### Automatic Phase Detection

Expand Down
4 changes: 2 additions & 2 deletions assets/skills/comet/reference/comet-yaml-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Canonical path: `comet/reference/comet-yaml-fields.md`

This file is the field reference for each change-level `.comet.yaml` state file under `openspec/changes/<name>/`.
Consult on demand; not loaded inline with skills. Project defaults live in `.comet/config.yaml`.
Consult on demand; not loaded inline with skills. Project defaults live in `.comet/config.yaml`, global defaults live in `~/.comet/config.yaml`, and project values take precedence.

## Example

Expand Down Expand Up @@ -35,7 +35,7 @@ archived: false
| Field | Meaning |
|-------|---------|
| `workflow` | `full`, `hotfix`, or `tweak` |
| `language` | Artifact language, `en` or `zh-CN`. Written to `.comet/config.yaml` by `comet init`, snapshotted into `.comet.yaml` when a change is created, and used as the main-language constraint for OpenSpec / Superpowers artifacts |
| `language` | Artifact language, `en` or `zh-CN`. Written to the project or global `.comet/config.yaml` according to install scope, snapshotted into `.comet.yaml` with project-over-global precedence when a change is created, and used as the main-language constraint for OpenSpec / Superpowers artifacts |
| `phase` | Current phase: `open`, `design`, `build`, `verify`, `archive` (init sets `open`; guard handles transitions) |
| `design_doc` | Associated Superpowers Design Doc path; may be empty |
| `plan` | Associated Superpowers Plan path; may be empty |
Expand Down
Loading
Loading