Skip to content

Commit c2dae55

Browse files
committed
fix(cli): 兼容轻量 schema 并升级到 0.11.3
1 parent 9bdf9ac commit c2dae55

11 files changed

Lines changed: 127 additions & 27 deletions

File tree

.agents/plugins/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aisee-plugin",
3-
"version": "0.11.2",
3+
"version": "0.11.3",
44
"interface": {
55
"displayName": "Aisee Plugin",
66
"description": "Aisee plugin marketplace for OpenSpec, project memory, team knowledge, and Compound Engineering workflows."

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
本项目遵循 [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) 的结构,并使用 SemVer 管理版本。
44

5+
## [0.11.3] - 2026-06-13
6+
7+
### Changed
8+
9+
- `aisee context pack``aisee:implementation-bridge` 兼容 OpenSpec 官方 `spec-driven` 和其它轻量 schema,不再因为缺少 Aisee 专属 `capabilities`、artifact `requiredness` 或 artifact `capabilities` 字段而误报 blocker。
10+
- `aisee context pack --for ce-work --json` 在无 `source-map.md` 的轻量 schema 下继续从当前 schema artifacts 提取实现路径;仅在真实 schema / artifact / 路径信息缺口上保留阻塞。
11+
- `aisee:implementation-bridge` 与 README 文案同步明确轻量 schema 兼容边界,避免把 Aisee 增强字段误当成 OpenSpec schema 的准入条件。
12+
513
## [0.11.2] - 2026-06-13
614

715
### Changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ Compound Engineering = 可选的执行 / 审查 / 测试消费方
155155
- **Schema-aware change planning**`aisee:change-plan` 将已确认输入映射为可独立交付的 OpenSpec changes。
156156
- **OpenSpec schema pack**:提供 app、device、docsite、infra、security、quick-fix、quick-research、collaboration 等 schema。
157157
- **Context packs**`aisee context pack` 为实现、验证和 review 生成 JSON 上下文。
158+
- **轻量 schema 兼容**`aisee context pack``aisee:implementation-bridge` 可直接消费 OpenSpec 官方 `spec-driven` 及其它轻量 schema;不会因为缺少 Aisee 专属增强字段而拒绝生成 bridge 上下文。
158159
- **项目记忆**`aisee memory` 受控检索和写入当前仓库长期 guidance,不替代 OpenSpec 事实源。
159160
- **团队知识 Guardrails**`aisee knowledge` 基于 pack/card 协议按需检索少量已审查工程经验,不把知识库变成第二份规范事实源。
160161
- **轻量上下文路由**`aisee context pack``source-map.md` 存在时解析来源、编号、候选路径和 evidence 入口。

plugins/aisee-plugin/.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aisee-plugin",
3-
"version": "0.11.2",
3+
"version": "0.11.3",
44
"description": "AI-Enhanced Software Engineering plugin for OpenSpec and Compound Engineering workflows.",
55
"author": {
66
"name": "Fengliang"

plugins/aisee-plugin/.codex-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aisee-plugin",
3-
"version": "0.11.2",
3+
"version": "0.11.3",
44
"description": "AI-Enhanced Software Engineering plugin for OpenSpec and Compound Engineering workflows.",
55
"author": {
66
"name": "Fengliang"

plugins/aisee-plugin/.cursor-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aisee-plugin",
3-
"version": "0.11.2",
3+
"version": "0.11.3",
44
"description": "AI-Enhanced Software Engineering plugin for OpenSpec and Compound Engineering workflows.",
55
"author": {
66
"name": "Fengliang"

plugins/aisee-plugin/skills/aisee-implementation-bridge/SKILL.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ Implementation Brief 是实现阶段的交接输出,不是新的规范事实
6969

7070
- 当前只处理一个 OpenSpec change。
7171
- schema metadata 已声明且项目内已安装该 schema;`SCHEMA_METADATA_MISSING``SCHEMA_MISMATCH``SCHEMA_NOT_INSTALLED``SCHEMA_NOT_FOUND` 都是实现 blocker。
72+
- 不要把 Aisee 增强字段本身当成准入门槛:官方或轻量 schema 缺少顶层 `capabilities`、artifact `requiredness`、artifact `capabilities` 时,不因此阻塞实现交接;只要 OpenSpec schema 本身可解析,仍按该 schema 的实际 artifacts 和 apply tracks 继续 bridge。
7273
- change 已经通过 `aisee:change-author` 补齐当前 schema 的必需 artifacts;只有 schema 生成 `source-map.md` 时才要求 source-map 说明按需 artifacts 的 Required=yes/no 与 N/A 原因。
7374
- 当前 schema 的 apply tracks 存在;通常是 `tasks.md`,但 `quick-research` 等无 apply schema 可以没有 tasks。
7475
- `source-map.md` 只在当前 schema 生成它时必需。
@@ -105,6 +106,7 @@ aisee context pack --change <change> --for ce-work --json
105106
处理规则:
106107

107108
- `context pack` 返回 `SCHEMA_METADATA_MISSING` / `SCHEMA_MISMATCH` / `SCHEMA_NOT_INSTALLED` / `SCHEMA_NOT_FOUND`:停止,不生成可执行 Brief。
109+
- 如果 `context pack` 读取的是官方或轻量 schema,且缺少 Aisee 专属增强字段,不把这类缺口升级成 blocker;继续根据 schema 已声明的 artifacts、`apply.tracks``source-map.md` 是否存在来判断执行入口。
108110
- `context pack.facts.derived.execution.requires_ce_plan=true`:Brief 中推荐先用 `ce-plan`,但结论必须回写当前 schema 的 apply tracks;只有 schema 生成 `source-map.md` 时才回写 source-map。
109111
- `ID_RESERVATION_REQUIRED``ID_UNREGISTERED_REFERENCE``ID_INACTIVE_REFERENCE` 只能作为阻塞或风险进入 Brief;不得在实现阶段由 `ce-work` 临时发明 ID。
110112

@@ -174,6 +176,7 @@ Brief 只做执行索引,不复制 OpenSpec artifact 正文:
174176
- `specs/**/spec.md` 是行为契约。
175177
- 当前 schema 的 apply tracks 是长期执行清单;app/device/quick-fix 通常是 `tasks.md`,无 apply schema 不强制 tasks。
176178
- `source-map.md` 只在当前 schema 生成它时是代码定位入口;不生成 source-map 的 schema 使用 context pack 从 schema artifacts 中提取的 implementation references。
179+
- `spec-driven``quick-fix``quick-research` 或其它轻量 schema 只要 OpenSpec 侧有效,就允许进入 bridge;不要要求它们补 Aisee app/device schema 才有的增强字段。
177180
- app schema 中,按 `source-map.md` 的 Artifact Applicability 判断哪些 supporting artifacts 是 Required=yes;不要要求每个 change 都展开全部 contracts。
178181
- device schema 中,`design.md` 和 hardware/firmware/runtime/verification contracts 是实现 contracts;不要把 app contract 假设套到设备项目。
179182
- `ce-work` 的允许路径应来自 context pack 的 `allowed_paths``code_paths``test_paths`。缺失时标记 `[SOURCE-MAP-GAP]``[IMPLEMENTATION-PATH-GAP]`,不要自行扩大实现范围。

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "aisee-plugin"
7-
version = "0.11.2"
7+
version = "0.11.3"
88
description = "AI-Enhanced Software Engineering plugin for OpenSpec and Compound Engineering workflows."
99
readme = "README.md"
1010
requires-python = ">=3.10"

src/aisee_cli/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
__all__ = ["__version__"]
44

5-
__version__ = "0.11.2"
5+
__version__ = "0.11.3"

src/aisee_cli/context_pack.py

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,17 @@ def parse_schema(schema_path: Path) -> dict[str, Any]:
345345
issues: list[dict[str, str]] = []
346346
raw_capabilities = data.get("capabilities")
347347
capabilities = parse_capabilities(raw_capabilities)
348-
if raw_capabilities is None:
349-
issues.append(schema_issue("SCHEMA_CAPABILITIES_MISSING", "blocker", "schema.yaml must define top-level capabilities"))
350-
elif not isinstance(raw_capabilities, list) or any(not isinstance(item, str) or not item.strip() for item in raw_capabilities):
351-
issues.append(schema_issue("SCHEMA_CAPABILITIES_INVALID", "blocker", "schema capabilities must be a non-empty string list"))
348+
if raw_capabilities is not None and (
349+
not isinstance(raw_capabilities, list)
350+
or any(not isinstance(item, str) or not item.strip() for item in raw_capabilities)
351+
):
352+
issues.append(
353+
schema_issue(
354+
"SCHEMA_CAPABILITIES_INVALID",
355+
"risk",
356+
"schema capabilities should be a non-empty string list when declared",
357+
)
358+
)
352359

353360
artifacts: list[ArtifactSpec] = []
354361
raw_artifacts = data.get("artifacts")
@@ -367,7 +374,7 @@ def parse_schema(schema_path: Path) -> dict[str, Any]:
367374
apply_tracks = normalize_track_value(apply.get("tracks"))
368375
archive_tracks = parse_tracks(archive.get("tracks"))
369376
if apply_tracks is None and "apply_execution" in capabilities:
370-
issues.append(schema_issue("SCHEMA_APPLY_TRACKS_MISSING", "blocker", "schema capability apply_execution requires apply.tracks"))
377+
issues.append(schema_issue("SCHEMA_APPLY_TRACKS_MISSING", "risk", "schema capability apply_execution requires apply.tracks"))
371378
if "archive_authority" in capabilities and not archive_tracks:
372379
issues.append(schema_issue("SCHEMA_ARCHIVE_TRACKS_MISSING", "risk", "schema capability archive_authority should declare archive.tracks"))
373380

@@ -434,40 +441,35 @@ def normalize_track_value(value: Any) -> str | None:
434441
def validate_artifact_schema(data: dict[str, Any]) -> list[dict[str, str]]:
435442
issues: list[dict[str, str]] = []
436443
artifact_id = str(data.get("id") or "")
437-
requiredness = str(data.get("requiredness") or "")
444+
raw_requiredness = data.get("requiredness")
445+
requiredness = str(raw_requiredness or "always")
438446
capabilities = data.get("capabilities")
439447
if not artifact_id:
440448
issues.append(schema_issue("SCHEMA_ARTIFACT_ID_MISSING", "blocker", "schema artifact is missing id"))
441-
if requiredness not in REQUIREDNESS_VALUES:
449+
if raw_requiredness is not None and requiredness not in REQUIREDNESS_VALUES:
442450
issues.append(
443451
schema_issue(
444452
"SCHEMA_ARTIFACT_REQUIREDNESS_INVALID",
445-
"blocker",
453+
"risk",
446454
f"artifact {artifact_id or '<unknown>'} must declare requiredness as one of: always, conditional, never",
447455
)
448456
)
449-
if capabilities is None:
450-
issues.append(
451-
schema_issue(
452-
"SCHEMA_ARTIFACT_CAPABILITIES_MISSING",
453-
"blocker",
454-
f"artifact {artifact_id or '<unknown>'} must declare capabilities",
455-
)
456-
)
457-
elif not isinstance(capabilities, list) or any(not isinstance(item, str) or not item.strip() for item in capabilities):
457+
if capabilities is not None and (
458+
not isinstance(capabilities, list) or any(not isinstance(item, str) or not item.strip() for item in capabilities)
459+
):
458460
issues.append(
459461
schema_issue(
460462
"SCHEMA_ARTIFACT_CAPABILITIES_INVALID",
461-
"blocker",
463+
"risk",
462464
f"artifact {artifact_id or '<unknown>'} capabilities must be a string list",
463465
)
464466
)
465467
na_requires_reason = data.get("na_requires_reason")
466-
if requiredness == "conditional" and not isinstance(na_requires_reason, bool):
468+
if raw_requiredness is not None and requiredness == "conditional" and not isinstance(na_requires_reason, bool):
467469
issues.append(
468470
schema_issue(
469471
"SCHEMA_ARTIFACT_NA_POLICY_MISSING",
470-
"blocker",
472+
"risk",
471473
f"artifact {artifact_id or '<unknown>'} must declare na_requires_reason for conditional requiredness",
472474
)
473475
)
@@ -496,7 +498,16 @@ def artifact_has_capability(artifact: ArtifactSpec | dict[str, Any], capability:
496498

497499

498500
def schema_generates_source_map(schema_info: dict[str, Any]) -> bool:
499-
return schema_has_capability(schema_info, "source_map_routing")
501+
if schema_has_capability(schema_info, "source_map_routing"):
502+
return True
503+
return any(
504+
isinstance(spec, ArtifactSpec)
505+
and (
506+
spec.artifact_id == "source-map"
507+
or spec.generates == "source-map.md"
508+
)
509+
for spec in schema_info.get("artifacts", [])
510+
)
500511

501512

502513
def schema_requires_tasks(schema_info: dict[str, Any]) -> bool:

0 commit comments

Comments
 (0)