@haaaiawd/anws 2.1.2 → 2.2.1

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/README.md CHANGED
@@ -3,8 +3,8 @@
3
3
  <img src="assets/logo-cli.png" width="260" alt="Anws">
4
4
 
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
- [![Version](https://img.shields.io/badge/version-v2.0.3-7FB5B6)](https://github.com/Haaaiawd/Anws/releases)
7
- [![Targets](https://img.shields.io/badge/Targets-Windsurf%20%7C%20Claude%20Code%20%7C%20Copilot%20%7C%20Cursor%20%7C%20Codex%20Preview%20%7C%20OpenCode%20%7C%20Trae%20%7C%20Qoder%20%7C%20Kilo%20Code-blueviolet)](https://github.com/Haaaiawd/Anws)
6
+ [![Version](https://img.shields.io/badge/version-v2.2.1-7FB5B6)](https://github.com/Haaaiawd/ANWS/releases)
7
+ [![Targets](https://img.shields.io/badge/Targets-Windsurf%20%7C%20Claude%20Code%20%7C%20Copilot%20%7C%20Cursor%20%7C%20Codex%20Preview%20%7C%20OpenCode%20%7C%20Trae%20%7C%20Qoder%20%7C%20Kilo%20Code-blueviolet)](https://github.com/Haaaiawd/ANWS)
8
8
 
9
9
  [English](./README.md) | [中文](./README_CN.md)
10
10
 
@@ -58,6 +58,30 @@ Anws addresses those problems with:
58
58
 
59
59
  ---
60
60
 
61
+ ## What's New in v2.2.0
62
+
63
+ `v2.2.0` closes the loop between design review, task review, implementation, and upgrade safety.
64
+
65
+ - **Closed-loop challenge review**
66
+ - `/challenge` now combines `design-reviewer`, `task-reviewer`, and `code-reviewer`
67
+ - implementation drift is reviewed against PRD, Architecture, ADR, System Design, and `05_TASKS.md`
68
+ - findings are written into `07_CHALLENGE_REPORT.md` with contract-first severity semantics
69
+
70
+ - **Code fidelity evidence layer**
71
+ - new `code-reviewer` skill checks Contract Drift, Task Drift, Test Drift, Missing Change Backflow, and foundational test gaps
72
+ - the review is static and evidence-based, so it does not pretend runtime validation has passed
73
+
74
+ - **Contract closure across workflows**
75
+ - `blueprint`, `task-planner`, `task-reviewer`, `challenge`, `change`, and `forge` now carry public contract coverage explicitly
76
+ - API, CLI, config, file format, error, persistence, and verification responsibilities are tracked as first-class workflow concerns
77
+
78
+ - **Forge verification gate**
79
+ - `/forge` reads the latest `07_CHALLENGE_REPORT.md` before implementation work continues
80
+ - unresolved Critical findings block forge; unresolved High findings require explicit human sign-off
81
+ - high-risk implementation waves can run `code-reviewer` before manual verification
82
+
83
+ ---
84
+
61
85
  ## What's New in v2.0.0
62
86
 
63
87
  `v2.0.0` is a **major release**. It is not just a template refresh; it upgrades the project protocol.
@@ -213,9 +237,9 @@ Use Anws as a lifecycle, not just a folder pack.
213
237
  | `/genesis` | Start from zero with PRD and architecture | Vague idea | PRD, architecture, ADRs |
214
238
  | `/probe` | Analyze a legacy codebase before change | Existing code | Risk report |
215
239
  | `/design-system` | Design one system in depth | Architecture overview | System design doc |
216
- | `/challenge` | Review design or tasks with adversarial pressure | Docs / tasks | Challenge report |
240
+ | `/challenge` | Review design, tasks, and implementation fidelity with adversarial pressure | Docs / tasks / code | Challenge report |
217
241
  | `/blueprint` | Break architecture into executable work | PRD + architecture | `05_TASKS.md` |
218
- | `/forge` | Turn approved tasks into code | Tasks | Working implementation |
242
+ | `/forge` | Turn approved tasks into code with challenge-report and contract gates | Tasks + review state | Working implementation |
219
243
  | `/change` | Modify an existing task only | Small scoped change | Updated task/design docs |
220
244
  | `/explore` | Research ambiguous or strategic topics | Topic | Exploration report |
221
245
  | `/craft` | Create workflows, skills, and prompts | Creation request | Reusable assets |
package/lib/manifest.js CHANGED
@@ -1,209 +1,210 @@
1
- 'use strict';
2
-
3
- const { getTarget } = require('./adapters');
4
-
5
- /**
6
- * MANAGED_FILES — anws 托管文件清单
7
- *
8
- * 此数组列出 anws 包负责管理的所有文件路径(相对于目标项目根目录)。
9
- */
10
- const RESOURCE_REGISTRY = [
11
- { id: 'blueprint', type: 'workflow', source: '.agents/workflows/blueprint.md', fileName: 'blueprint.md' },
12
- { id: 'challenge', type: 'workflow', source: '.agents/workflows/challenge.md', fileName: 'challenge.md' },
13
- { id: 'change', type: 'workflow', source: '.agents/workflows/change.md', fileName: 'change.md' },
14
- { id: 'craft', type: 'workflow', source: '.agents/workflows/craft.md', fileName: 'craft.md' },
15
- { id: 'design-system', type: 'workflow', source: '.agents/workflows/design-system.md', fileName: 'design-system.md' },
16
- { id: 'explore', type: 'workflow', source: '.agents/workflows/explore.md', fileName: 'explore.md' },
17
- { id: 'forge', type: 'workflow', source: '.agents/workflows/forge.md', fileName: 'forge.md' },
18
- { id: 'genesis', type: 'workflow', source: '.agents/workflows/genesis.md', fileName: 'genesis.md' },
19
- { id: 'probe', type: 'workflow', source: '.agents/workflows/probe.md', fileName: 'probe.md' },
20
- { id: 'quickstart', type: 'workflow', source: '.agents/workflows/quickstart.md', fileName: 'quickstart.md' },
21
- { id: 'upgrade', type: 'workflow', source: '.agents/workflows/upgrade.md', fileName: 'upgrade.md' },
22
- { id: 'anws-system', type: 'skill', source: '.agents/skills/anws-system/SKILL.md', fileName: 'anws-system/SKILL.md', targets: ['codex', 'trae'] },
23
- { id: 'concept-modeler', type: 'skill', source: '.agents/skills/concept-modeler/SKILL.md', fileName: 'concept-modeler/SKILL.md' },
24
- { id: 'design-reviewer', type: 'skill', source: '.agents/skills/design-reviewer/SKILL.md', fileName: 'design-reviewer/SKILL.md' },
25
- { id: 'nexus-mapper', type: 'skill', source: '.agents/skills/nexus-mapper/SKILL.md', fileName: 'nexus-mapper/SKILL.md' },
26
- { id: 'nexus-mapper-language-customization', type: 'skill', source: '.agents/skills/nexus-mapper/references/language-customization.md', fileName: 'nexus-mapper/references/language-customization.md' },
27
- { id: 'nexus-mapper-output-schema', type: 'skill', source: '.agents/skills/nexus-mapper/references/output-schema.md', fileName: 'nexus-mapper/references/output-schema.md' },
28
- { id: 'nexus-mapper-probe-protocol', type: 'skill', source: '.agents/skills/nexus-mapper/references/probe-protocol.md', fileName: 'nexus-mapper/references/probe-protocol.md' },
29
- { id: 'nexus-mapper-extract-ast', type: 'skill', source: '.agents/skills/nexus-mapper/scripts/extract_ast.py', fileName: 'nexus-mapper/scripts/extract_ast.py' },
30
- { id: 'nexus-mapper-git-detective', type: 'skill', source: '.agents/skills/nexus-mapper/scripts/git_detective.py', fileName: 'nexus-mapper/scripts/git_detective.py' },
31
- { id: 'nexus-mapper-languages', type: 'skill', source: '.agents/skills/nexus-mapper/scripts/languages.json', fileName: 'nexus-mapper/scripts/languages.json' },
32
- { id: 'nexus-mapper-query-graph', type: 'skill', source: '.agents/skills/nexus-mapper/scripts/query_graph.py', fileName: 'nexus-mapper/scripts/query_graph.py' },
33
- { id: 'nexus-mapper-requirements', type: 'skill', source: '.agents/skills/nexus-mapper/scripts/requirements.txt', fileName: 'nexus-mapper/scripts/requirements.txt' },
34
- { id: 'report-template', type: 'skill', source: '.agents/skills/report-template/SKILL.md', fileName: 'report-template/SKILL.md' },
35
- { id: 'report-template-reference', type: 'skill', source: '.agents/skills/report-template/references/REPORT_TEMPLATE.md', fileName: 'report-template/references/REPORT_TEMPLATE.md' },
36
- { id: 'runtime-inspector', type: 'skill', source: '.agents/skills/runtime-inspector/SKILL.md', fileName: 'runtime-inspector/SKILL.md' },
37
- { id: 'sequential-thinking', type: 'skill', source: '.agents/skills/sequential-thinking/SKILL.md', fileName: 'sequential-thinking/SKILL.md' },
38
- { id: 'spec-writer', type: 'skill', source: '.agents/skills/spec-writer/SKILL.md', fileName: 'spec-writer/SKILL.md' },
39
- { id: 'spec-writer-prd-template', type: 'skill', source: '.agents/skills/spec-writer/references/prd_template.md', fileName: 'spec-writer/references/prd_template.md' },
40
- { id: 'system-architect', type: 'skill', source: '.agents/skills/system-architect/SKILL.md', fileName: 'system-architect/SKILL.md' },
41
- { id: 'system-architect-rfc-template', type: 'skill', source: '.agents/skills/system-architect/references/rfc_template.md', fileName: 'system-architect/references/rfc_template.md' },
42
- { id: 'system-designer', type: 'skill', source: '.agents/skills/system-designer/SKILL.md', fileName: 'system-designer/SKILL.md' },
43
- { id: 'system-designer-detail-template', type: 'skill', source: '.agents/skills/system-designer/references/system-design-detail-template.md', fileName: 'system-designer/references/system-design-detail-template.md' },
44
- { id: 'system-designer-template', type: 'skill', source: '.agents/skills/system-designer/references/system-design-template.md', fileName: 'system-designer/references/system-design-template.md' },
45
- { id: 'task-planner', type: 'skill', source: '.agents/skills/task-planner/SKILL.md', fileName: 'task-planner/SKILL.md' },
46
- { id: 'task-planner-template', type: 'skill', source: '.agents/skills/task-planner/references/TASK_TEMPLATE.md', fileName: 'task-planner/references/TASK_TEMPLATE.md' },
47
- { id: 'task-reviewer', type: 'skill', source: '.agents/skills/task-reviewer/SKILL.md', fileName: 'task-reviewer/SKILL.md' },
48
- { id: 'tech-evaluator', type: 'skill', source: '.agents/skills/tech-evaluator/SKILL.md', fileName: 'tech-evaluator/SKILL.md' },
49
- { id: 'tech-evaluator-adr-template', type: 'skill', source: '.agents/skills/tech-evaluator/references/ADR_TEMPLATE.md', fileName: 'tech-evaluator/references/ADR_TEMPLATE.md' }
50
- ];
51
-
52
- function toArray(value) {
53
- return Array.isArray(value) ? value : [value];
54
- }
55
-
56
- function toProjectionFileName(resource, projectionType, targetId) {
57
- if ((targetId === 'codex' || targetId === 'trae') && projectionType === 'skills' && resource.type === 'workflow') {
58
- return `anws-system/references/${resource.id}.md`;
59
- }
60
- if (projectionType === 'commands') {
61
- return `${resource.id}.md`;
62
- }
63
- if (projectionType === 'prompts') {
64
- return targetId === 'copilot' ? `${resource.id}.prompt.md` : `${resource.id}.md`;
65
- }
66
- if (projectionType === 'agents') {
67
- return `${resource.id}.md`;
68
- }
69
- return resource.fileName;
70
- }
71
-
72
- function buildProjectionEntries(targetId) {
73
- const target = getTarget(targetId);
74
- const typeMap = target.projectionTypes;
75
-
76
- return RESOURCE_REGISTRY.flatMap((resource) => {
77
- if (resource.targets && !resource.targets.includes(target.id)) {
78
- return [];
79
- }
80
- const projectionTypes = typeMap[resource.type];
81
- if (!projectionTypes) {
82
- return [];
83
- }
84
-
85
- return toArray(projectionTypes).map((projectionType) => {
86
- const outputFileName = toProjectionFileName(resource, projectionType, target.id);
87
- return {
88
- ...resource,
89
- projectionType,
90
- outputRoot: target.projections[projectionType],
91
- outputPath: `${target.projections[projectionType]}/${outputFileName}`
92
- };
93
- });
94
- });
95
- }
96
-
97
- function buildManagedManifest(targetIds = ['antigravity']) {
98
- return toArray(targetIds).flatMap((targetId) => {
99
- const target = getTarget(targetId);
100
- const entries = buildProjectionEntries(target.id).map((entry) => ({
101
- ...entry,
102
- targetId: target.id,
103
- targetLabel: target.label,
104
- ownershipKey: `${target.id}:${entry.outputPath}`
105
- }));
106
-
107
- if (!target.rootAgentFile) {
108
- return entries;
109
- }
110
-
111
- return [
112
- {
113
- id: 'root-agents',
114
- type: 'root',
115
- source: 'AGENTS.md',
116
- fileName: 'AGENTS.md',
117
- projectionType: 'rootAgentFile',
118
- outputRoot: '.',
119
- outputPath: 'AGENTS.md',
120
- targetId: target.id,
121
- targetLabel: target.label,
122
- ownershipKey: `${target.id}:AGENTS.md`
123
- },
124
- ...entries
125
- ];
126
- });
127
- }
128
-
129
- function buildProjectionPlan(targetIds = ['antigravity'], resources = RESOURCE_REGISTRY) {
130
- return toArray(targetIds).map((targetId) => {
131
- const target = getTarget(targetId);
132
- const typeMap = target.projectionTypes;
133
- const projectionEntries = resources.flatMap((resource) => {
134
- if (resource.targets && !resource.targets.includes(target.id)) {
135
- return [];
136
- }
137
- const projectionTypes = typeMap[resource.type];
138
- if (!projectionTypes) {
139
- return [];
140
- }
141
-
142
- return toArray(projectionTypes).map((projectionType) => {
143
- const outputFileName = toProjectionFileName(resource, projectionType, target.id);
144
- const outputPath = `${target.projections[projectionType]}/${outputFileName}`;
145
- return {
146
- ...resource,
147
- projectionType,
148
- outputRoot: target.projections[projectionType],
149
- outputPath,
150
- targetId: target.id,
151
- targetLabel: target.label,
152
- ownershipKey: `${target.id}:${outputPath}`
153
- };
154
- });
155
- });
156
-
157
- const managedFiles = target.rootAgentFile
158
- ? ['AGENTS.md', ...projectionEntries.map((item) => item.outputPath)]
159
- : projectionEntries.map((item) => item.outputPath);
160
-
161
- return {
162
- target,
163
- targetId: target.id,
164
- targetLabel: target.label,
165
- managedFiles,
166
- userProtectedFiles: buildUserProtectedFiles(target.id),
167
- projectionEntries,
168
- ownership: projectionEntries.map((item) => item.ownershipKey)
169
- };
170
- });
171
- }
172
-
173
- function buildManagedFiles(targetId = 'antigravity') {
174
- return buildManagedManifest(targetId).map((item) => item.outputPath);
175
- }
176
-
177
- function buildUserProtectedFiles(targetId = 'antigravity') {
178
- const target = getTarget(targetId);
179
- return target.rootAgentFile ? ['AGENTS.md'] : [];
180
- }
181
-
182
- function findByType(type) {
183
- return RESOURCE_REGISTRY.filter((item) => item.type === type);
184
- }
185
-
186
- const MANAGED_FILES = buildManagedFiles('antigravity');
187
-
188
- /**
189
- * USER_PROTECTED_FILES — 用户保护文件
190
- *
191
- * 这些文件在项目初始化后通常会包含特定于项目的配置。
192
- * anws update 默认会跳过这些文件。
193
- */
194
- const USER_PROTECTED_FILES = buildUserProtectedFiles('antigravity');
195
-
196
- module.exports = {
197
- RESOURCE_REGISTRY,
198
- buildManagedManifest,
199
- buildProjectionPlan,
200
- buildManagedFiles,
201
- buildProjectionEntries,
202
- buildUserProtectedFiles,
203
- findByType,
204
- MANAGED_FILES,
205
- USER_PROTECTED_FILES
206
- };
207
-
208
-
209
-
1
+ 'use strict';
2
+
3
+ const { getTarget } = require('./adapters');
4
+
5
+ /**
6
+ * MANAGED_FILES — anws 托管文件清单
7
+ *
8
+ * 此数组列出 anws 包负责管理的所有文件路径(相对于目标项目根目录)。
9
+ */
10
+ const RESOURCE_REGISTRY = [
11
+ { id: 'blueprint', type: 'workflow', source: '.agents/workflows/blueprint.md', fileName: 'blueprint.md' },
12
+ { id: 'challenge', type: 'workflow', source: '.agents/workflows/challenge.md', fileName: 'challenge.md' },
13
+ { id: 'change', type: 'workflow', source: '.agents/workflows/change.md', fileName: 'change.md' },
14
+ { id: 'craft', type: 'workflow', source: '.agents/workflows/craft.md', fileName: 'craft.md' },
15
+ { id: 'design-system', type: 'workflow', source: '.agents/workflows/design-system.md', fileName: 'design-system.md' },
16
+ { id: 'explore', type: 'workflow', source: '.agents/workflows/explore.md', fileName: 'explore.md' },
17
+ { id: 'forge', type: 'workflow', source: '.agents/workflows/forge.md', fileName: 'forge.md' },
18
+ { id: 'genesis', type: 'workflow', source: '.agents/workflows/genesis.md', fileName: 'genesis.md' },
19
+ { id: 'probe', type: 'workflow', source: '.agents/workflows/probe.md', fileName: 'probe.md' },
20
+ { id: 'quickstart', type: 'workflow', source: '.agents/workflows/quickstart.md', fileName: 'quickstart.md' },
21
+ { id: 'upgrade', type: 'workflow', source: '.agents/workflows/upgrade.md', fileName: 'upgrade.md' },
22
+ { id: 'anws-system', type: 'skill', source: '.agents/skills/anws-system/SKILL.md', fileName: 'anws-system/SKILL.md', targets: ['codex', 'trae'] },
23
+ { id: 'concept-modeler', type: 'skill', source: '.agents/skills/concept-modeler/SKILL.md', fileName: 'concept-modeler/SKILL.md' },
24
+ { id: 'code-reviewer', type: 'skill', source: '.agents/skills/code-reviewer/SKILL.md', fileName: 'code-reviewer/SKILL.md' },
25
+ { id: 'design-reviewer', type: 'skill', source: '.agents/skills/design-reviewer/SKILL.md', fileName: 'design-reviewer/SKILL.md' },
26
+ { id: 'nexus-mapper', type: 'skill', source: '.agents/skills/nexus-mapper/SKILL.md', fileName: 'nexus-mapper/SKILL.md' },
27
+ { id: 'nexus-mapper-language-customization', type: 'skill', source: '.agents/skills/nexus-mapper/references/language-customization.md', fileName: 'nexus-mapper/references/language-customization.md' },
28
+ { id: 'nexus-mapper-output-schema', type: 'skill', source: '.agents/skills/nexus-mapper/references/output-schema.md', fileName: 'nexus-mapper/references/output-schema.md' },
29
+ { id: 'nexus-mapper-probe-protocol', type: 'skill', source: '.agents/skills/nexus-mapper/references/probe-protocol.md', fileName: 'nexus-mapper/references/probe-protocol.md' },
30
+ { id: 'nexus-mapper-extract-ast', type: 'skill', source: '.agents/skills/nexus-mapper/scripts/extract_ast.py', fileName: 'nexus-mapper/scripts/extract_ast.py' },
31
+ { id: 'nexus-mapper-git-detective', type: 'skill', source: '.agents/skills/nexus-mapper/scripts/git_detective.py', fileName: 'nexus-mapper/scripts/git_detective.py' },
32
+ { id: 'nexus-mapper-languages', type: 'skill', source: '.agents/skills/nexus-mapper/scripts/languages.json', fileName: 'nexus-mapper/scripts/languages.json' },
33
+ { id: 'nexus-mapper-query-graph', type: 'skill', source: '.agents/skills/nexus-mapper/scripts/query_graph.py', fileName: 'nexus-mapper/scripts/query_graph.py' },
34
+ { id: 'nexus-mapper-requirements', type: 'skill', source: '.agents/skills/nexus-mapper/scripts/requirements.txt', fileName: 'nexus-mapper/scripts/requirements.txt' },
35
+ { id: 'report-template', type: 'skill', source: '.agents/skills/report-template/SKILL.md', fileName: 'report-template/SKILL.md' },
36
+ { id: 'report-template-reference', type: 'skill', source: '.agents/skills/report-template/references/REPORT_TEMPLATE.md', fileName: 'report-template/references/REPORT_TEMPLATE.md' },
37
+ { id: 'runtime-inspector', type: 'skill', source: '.agents/skills/runtime-inspector/SKILL.md', fileName: 'runtime-inspector/SKILL.md' },
38
+ { id: 'sequential-thinking', type: 'skill', source: '.agents/skills/sequential-thinking/SKILL.md', fileName: 'sequential-thinking/SKILL.md' },
39
+ { id: 'spec-writer', type: 'skill', source: '.agents/skills/spec-writer/SKILL.md', fileName: 'spec-writer/SKILL.md' },
40
+ { id: 'spec-writer-prd-template', type: 'skill', source: '.agents/skills/spec-writer/references/prd_template.md', fileName: 'spec-writer/references/prd_template.md' },
41
+ { id: 'system-architect', type: 'skill', source: '.agents/skills/system-architect/SKILL.md', fileName: 'system-architect/SKILL.md' },
42
+ { id: 'system-architect-rfc-template', type: 'skill', source: '.agents/skills/system-architect/references/rfc_template.md', fileName: 'system-architect/references/rfc_template.md' },
43
+ { id: 'system-designer', type: 'skill', source: '.agents/skills/system-designer/SKILL.md', fileName: 'system-designer/SKILL.md' },
44
+ { id: 'system-designer-detail-template', type: 'skill', source: '.agents/skills/system-designer/references/system-design-detail-template.md', fileName: 'system-designer/references/system-design-detail-template.md' },
45
+ { id: 'system-designer-template', type: 'skill', source: '.agents/skills/system-designer/references/system-design-template.md', fileName: 'system-designer/references/system-design-template.md' },
46
+ { id: 'task-planner', type: 'skill', source: '.agents/skills/task-planner/SKILL.md', fileName: 'task-planner/SKILL.md' },
47
+ { id: 'task-planner-template', type: 'skill', source: '.agents/skills/task-planner/references/TASK_TEMPLATE.md', fileName: 'task-planner/references/TASK_TEMPLATE.md' },
48
+ { id: 'task-reviewer', type: 'skill', source: '.agents/skills/task-reviewer/SKILL.md', fileName: 'task-reviewer/SKILL.md' },
49
+ { id: 'tech-evaluator', type: 'skill', source: '.agents/skills/tech-evaluator/SKILL.md', fileName: 'tech-evaluator/SKILL.md' },
50
+ { id: 'tech-evaluator-adr-template', type: 'skill', source: '.agents/skills/tech-evaluator/references/ADR_TEMPLATE.md', fileName: 'tech-evaluator/references/ADR_TEMPLATE.md' }
51
+ ];
52
+
53
+ function toArray(value) {
54
+ return Array.isArray(value) ? value : [value];
55
+ }
56
+
57
+ function toProjectionFileName(resource, projectionType, targetId) {
58
+ if ((targetId === 'codex' || targetId === 'trae') && projectionType === 'skills' && resource.type === 'workflow') {
59
+ return `anws-system/references/${resource.id}.md`;
60
+ }
61
+ if (projectionType === 'commands') {
62
+ return `${resource.id}.md`;
63
+ }
64
+ if (projectionType === 'prompts') {
65
+ return targetId === 'copilot' ? `${resource.id}.prompt.md` : `${resource.id}.md`;
66
+ }
67
+ if (projectionType === 'agents') {
68
+ return `${resource.id}.md`;
69
+ }
70
+ return resource.fileName;
71
+ }
72
+
73
+ function buildProjectionEntries(targetId) {
74
+ const target = getTarget(targetId);
75
+ const typeMap = target.projectionTypes;
76
+
77
+ return RESOURCE_REGISTRY.flatMap((resource) => {
78
+ if (resource.targets && !resource.targets.includes(target.id)) {
79
+ return [];
80
+ }
81
+ const projectionTypes = typeMap[resource.type];
82
+ if (!projectionTypes) {
83
+ return [];
84
+ }
85
+
86
+ return toArray(projectionTypes).map((projectionType) => {
87
+ const outputFileName = toProjectionFileName(resource, projectionType, target.id);
88
+ return {
89
+ ...resource,
90
+ projectionType,
91
+ outputRoot: target.projections[projectionType],
92
+ outputPath: `${target.projections[projectionType]}/${outputFileName}`
93
+ };
94
+ });
95
+ });
96
+ }
97
+
98
+ function buildManagedManifest(targetIds = ['antigravity']) {
99
+ return toArray(targetIds).flatMap((targetId) => {
100
+ const target = getTarget(targetId);
101
+ const entries = buildProjectionEntries(target.id).map((entry) => ({
102
+ ...entry,
103
+ targetId: target.id,
104
+ targetLabel: target.label,
105
+ ownershipKey: `${target.id}:${entry.outputPath}`
106
+ }));
107
+
108
+ if (!target.rootAgentFile) {
109
+ return entries;
110
+ }
111
+
112
+ return [
113
+ {
114
+ id: 'root-agents',
115
+ type: 'root',
116
+ source: 'AGENTS.md',
117
+ fileName: 'AGENTS.md',
118
+ projectionType: 'rootAgentFile',
119
+ outputRoot: '.',
120
+ outputPath: 'AGENTS.md',
121
+ targetId: target.id,
122
+ targetLabel: target.label,
123
+ ownershipKey: `${target.id}:AGENTS.md`
124
+ },
125
+ ...entries
126
+ ];
127
+ });
128
+ }
129
+
130
+ function buildProjectionPlan(targetIds = ['antigravity'], resources = RESOURCE_REGISTRY) {
131
+ return toArray(targetIds).map((targetId) => {
132
+ const target = getTarget(targetId);
133
+ const typeMap = target.projectionTypes;
134
+ const projectionEntries = resources.flatMap((resource) => {
135
+ if (resource.targets && !resource.targets.includes(target.id)) {
136
+ return [];
137
+ }
138
+ const projectionTypes = typeMap[resource.type];
139
+ if (!projectionTypes) {
140
+ return [];
141
+ }
142
+
143
+ return toArray(projectionTypes).map((projectionType) => {
144
+ const outputFileName = toProjectionFileName(resource, projectionType, target.id);
145
+ const outputPath = `${target.projections[projectionType]}/${outputFileName}`;
146
+ return {
147
+ ...resource,
148
+ projectionType,
149
+ outputRoot: target.projections[projectionType],
150
+ outputPath,
151
+ targetId: target.id,
152
+ targetLabel: target.label,
153
+ ownershipKey: `${target.id}:${outputPath}`
154
+ };
155
+ });
156
+ });
157
+
158
+ const managedFiles = target.rootAgentFile
159
+ ? ['AGENTS.md', ...projectionEntries.map((item) => item.outputPath)]
160
+ : projectionEntries.map((item) => item.outputPath);
161
+
162
+ return {
163
+ target,
164
+ targetId: target.id,
165
+ targetLabel: target.label,
166
+ managedFiles,
167
+ userProtectedFiles: buildUserProtectedFiles(target.id),
168
+ projectionEntries,
169
+ ownership: projectionEntries.map((item) => item.ownershipKey)
170
+ };
171
+ });
172
+ }
173
+
174
+ function buildManagedFiles(targetId = 'antigravity') {
175
+ return buildManagedManifest(targetId).map((item) => item.outputPath);
176
+ }
177
+
178
+ function buildUserProtectedFiles(targetId = 'antigravity') {
179
+ const target = getTarget(targetId);
180
+ return target.rootAgentFile ? ['AGENTS.md'] : [];
181
+ }
182
+
183
+ function findByType(type) {
184
+ return RESOURCE_REGISTRY.filter((item) => item.type === type);
185
+ }
186
+
187
+ const MANAGED_FILES = buildManagedFiles('antigravity');
188
+
189
+ /**
190
+ * USER_PROTECTED_FILES — 用户保护文件
191
+ *
192
+ * 这些文件在项目初始化后通常会包含特定于项目的配置。
193
+ * anws update 默认会跳过这些文件。
194
+ */
195
+ const USER_PROTECTED_FILES = buildUserProtectedFiles('antigravity');
196
+
197
+ module.exports = {
198
+ RESOURCE_REGISTRY,
199
+ buildManagedManifest,
200
+ buildProjectionPlan,
201
+ buildManagedFiles,
202
+ buildProjectionEntries,
203
+ buildUserProtectedFiles,
204
+ findByType,
205
+ MANAGED_FILES,
206
+ USER_PROTECTED_FILES
207
+ };
208
+
209
+
210
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haaaiawd/anws",
3
- "version": "2.1.2",
3
+ "version": "2.2.1",
4
4
  "description": "Anws — A spec-driven workflow framework for AI-assisted development. Empowers prompt engineers to build production-ready software through structured PRD → Architecture → Task decomposition. Works with Claude Code, GitHub Copilot, Cursor, Windsurf, and any tool that reads AGENTS.md.",
5
5
  "keywords": [
6
6
  "anws",
@@ -17,10 +17,10 @@
17
17
  "cursor",
18
18
  "windsurf"
19
19
  ],
20
- "homepage": "https://github.com/Haaaiawd/Anws",
20
+ "homepage": "https://github.com/Haaaiawd/ANWS",
21
21
  "repository": {
22
22
  "type": "git",
23
- "url": "git+https://github.com/Haaaiawd/Anws.git"
23
+ "url": "git+https://github.com/Haaaiawd/ANWS.git"
24
24
  },
25
25
  "author": "haaaiawd <1134180104@qq.com>",
26
26
  "license": "MIT",