@haaaiawd/anws 2.2.5 → 2.3.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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  <img src="assets/logo-cli.png" width="260" alt="Anws">
5
5
 
6
6
  [![License: MIT](https://opensource.org/licenses/MIT)](https://opensource.org/licenses/MIT)
7
- [![Version](https://img.shields.io/badge/version-v2.2.5-7FB5B6)](https://github.com/Haaaiawd/ANWS/releases)
7
+ [![Version](https://img.shields.io/badge/version-v2.3.0--WIP-7FB5B6)](https://github.com/Haaaiawd/ANWS/releases)
8
8
  [![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)
9
9
 
10
10
  [English](./README.md) | [中文](./README_CN.md)
package/lib/manifest.js CHANGED
@@ -1,212 +1,213 @@
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
- { id: 'e2e-testing-guide', type: 'skill', source: '.agents/skills/e2e-testing-guide/SKILL.md', fileName: 'e2e-testing-guide/SKILL.md' },
52
- { id: 'craft-authoring', type: 'skill', source: '.agents/skills/craft-authoring/SKILL.md', fileName: 'craft-authoring/SKILL.md' }
53
- ];
54
-
55
- function toArray(value) {
56
- return Array.isArray(value) ? value : [value];
57
- }
58
-
59
- function toProjectionFileName(resource, projectionType, targetId) {
60
- if ((targetId === 'codex' || targetId === 'trae') && projectionType === 'skills' && resource.type === 'workflow') {
61
- return `anws-system/references/${resource.id}.md`;
62
- }
63
- if (projectionType === 'commands') {
64
- return `${resource.id}.md`;
65
- }
66
- if (projectionType === 'prompts') {
67
- return targetId === 'copilot' ? `${resource.id}.prompt.md` : `${resource.id}.md`;
68
- }
69
- if (projectionType === 'agents') {
70
- return `${resource.id}.md`;
71
- }
72
- return resource.fileName;
73
- }
74
-
75
- function buildProjectionEntries(targetId) {
76
- const target = getTarget(targetId);
77
- const typeMap = target.projectionTypes;
78
-
79
- return RESOURCE_REGISTRY.flatMap((resource) => {
80
- if (resource.targets && !resource.targets.includes(target.id)) {
81
- return [];
82
- }
83
- const projectionTypes = typeMap[resource.type];
84
- if (!projectionTypes) {
85
- return [];
86
- }
87
-
88
- return toArray(projectionTypes).map((projectionType) => {
89
- const outputFileName = toProjectionFileName(resource, projectionType, target.id);
90
- return {
91
- ...resource,
92
- projectionType,
93
- outputRoot: target.projections[projectionType],
94
- outputPath: `${target.projections[projectionType]}/${outputFileName}`
95
- };
96
- });
97
- });
98
- }
99
-
100
- function buildManagedManifest(targetIds = ['antigravity']) {
101
- return toArray(targetIds).flatMap((targetId) => {
102
- const target = getTarget(targetId);
103
- const entries = buildProjectionEntries(target.id).map((entry) => ({
104
- ...entry,
105
- targetId: target.id,
106
- targetLabel: target.label,
107
- ownershipKey: `${target.id}:${entry.outputPath}`
108
- }));
109
-
110
- if (!target.rootAgentFile) {
111
- return entries;
112
- }
113
-
114
- return [
115
- {
116
- id: 'root-agents',
117
- type: 'root',
118
- source: 'AGENTS.md',
119
- fileName: 'AGENTS.md',
120
- projectionType: 'rootAgentFile',
121
- outputRoot: '.',
122
- outputPath: 'AGENTS.md',
123
- targetId: target.id,
124
- targetLabel: target.label,
125
- ownershipKey: `${target.id}:AGENTS.md`
126
- },
127
- ...entries
128
- ];
129
- });
130
- }
131
-
132
- function buildProjectionPlan(targetIds = ['antigravity'], resources = RESOURCE_REGISTRY) {
133
- return toArray(targetIds).map((targetId) => {
134
- const target = getTarget(targetId);
135
- const typeMap = target.projectionTypes;
136
- const projectionEntries = resources.flatMap((resource) => {
137
- if (resource.targets && !resource.targets.includes(target.id)) {
138
- return [];
139
- }
140
- const projectionTypes = typeMap[resource.type];
141
- if (!projectionTypes) {
142
- return [];
143
- }
144
-
145
- return toArray(projectionTypes).map((projectionType) => {
146
- const outputFileName = toProjectionFileName(resource, projectionType, target.id);
147
- const outputPath = `${target.projections[projectionType]}/${outputFileName}`;
148
- return {
149
- ...resource,
150
- projectionType,
151
- outputRoot: target.projections[projectionType],
152
- outputPath,
153
- targetId: target.id,
154
- targetLabel: target.label,
155
- ownershipKey: `${target.id}:${outputPath}`
156
- };
157
- });
158
- });
159
-
160
- const managedFiles = target.rootAgentFile
161
- ? ['AGENTS.md', ...projectionEntries.map((item) => item.outputPath)]
162
- : projectionEntries.map((item) => item.outputPath);
163
-
164
- return {
165
- target,
166
- targetId: target.id,
167
- targetLabel: target.label,
168
- managedFiles,
169
- userProtectedFiles: buildUserProtectedFiles(target.id),
170
- projectionEntries,
171
- ownership: projectionEntries.map((item) => item.ownershipKey)
172
- };
173
- });
174
- }
175
-
176
- function buildManagedFiles(targetId = 'antigravity') {
177
- return buildManagedManifest(targetId).map((item) => item.outputPath);
178
- }
179
-
180
- function buildUserProtectedFiles(targetId = 'antigravity') {
181
- const target = getTarget(targetId);
182
- return target.rootAgentFile ? ['AGENTS.md'] : [];
183
- }
184
-
185
- function findByType(type) {
186
- return RESOURCE_REGISTRY.filter((item) => item.type === type);
187
- }
188
-
189
- const MANAGED_FILES = buildManagedFiles('antigravity');
190
-
191
- /**
192
- * USER_PROTECTED_FILES — 用户保护文件
193
- *
194
- * 这些文件在项目初始化后通常会包含特定于项目的配置。
195
- * anws update 默认会跳过这些文件。
196
- */
197
- const USER_PROTECTED_FILES = buildUserProtectedFiles('antigravity');
198
-
199
- module.exports = {
200
- RESOURCE_REGISTRY,
201
- buildManagedManifest,
202
- buildProjectionPlan,
203
- buildManagedFiles,
204
- buildProjectionEntries,
205
- buildUserProtectedFiles,
206
- findByType,
207
- MANAGED_FILES,
208
- USER_PROTECTED_FILES
209
- };
210
-
211
-
212
-
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-05a', type: 'skill', source: '.agents/skills/task-planner/references/TASK_TEMPLATE_05A.md', fileName: 'task-planner/references/TASK_TEMPLATE_05A.md' },
48
+ { id: 'task-planner-template-05b', type: 'skill', source: '.agents/skills/task-planner/references/TASK_TEMPLATE_05B.md', fileName: 'task-planner/references/TASK_TEMPLATE_05B.md' },
49
+ { id: 'task-reviewer', type: 'skill', source: '.agents/skills/task-reviewer/SKILL.md', fileName: 'task-reviewer/SKILL.md' },
50
+ { id: 'tech-evaluator', type: 'skill', source: '.agents/skills/tech-evaluator/SKILL.md', fileName: 'tech-evaluator/SKILL.md' },
51
+ { id: 'tech-evaluator-adr-template', type: 'skill', source: '.agents/skills/tech-evaluator/references/ADR_TEMPLATE.md', fileName: 'tech-evaluator/references/ADR_TEMPLATE.md' },
52
+ { id: 'e2e-testing-guide', type: 'skill', source: '.agents/skills/e2e-testing-guide/SKILL.md', fileName: 'e2e-testing-guide/SKILL.md' },
53
+ { id: 'craft-authoring', type: 'skill', source: '.agents/skills/craft-authoring/SKILL.md', fileName: 'craft-authoring/SKILL.md' }
54
+ ];
55
+
56
+ function toArray(value) {
57
+ return Array.isArray(value) ? value : [value];
58
+ }
59
+
60
+ function toProjectionFileName(resource, projectionType, targetId) {
61
+ if ((targetId === 'codex' || targetId === 'trae') && projectionType === 'skills' && resource.type === 'workflow') {
62
+ return `anws-system/references/${resource.id}.md`;
63
+ }
64
+ if (projectionType === 'commands') {
65
+ return `${resource.id}.md`;
66
+ }
67
+ if (projectionType === 'prompts') {
68
+ return targetId === 'copilot' ? `${resource.id}.prompt.md` : `${resource.id}.md`;
69
+ }
70
+ if (projectionType === 'agents') {
71
+ return `${resource.id}.md`;
72
+ }
73
+ return resource.fileName;
74
+ }
75
+
76
+ function buildProjectionEntries(targetId) {
77
+ const target = getTarget(targetId);
78
+ const typeMap = target.projectionTypes;
79
+
80
+ return RESOURCE_REGISTRY.flatMap((resource) => {
81
+ if (resource.targets && !resource.targets.includes(target.id)) {
82
+ return [];
83
+ }
84
+ const projectionTypes = typeMap[resource.type];
85
+ if (!projectionTypes) {
86
+ return [];
87
+ }
88
+
89
+ return toArray(projectionTypes).map((projectionType) => {
90
+ const outputFileName = toProjectionFileName(resource, projectionType, target.id);
91
+ return {
92
+ ...resource,
93
+ projectionType,
94
+ outputRoot: target.projections[projectionType],
95
+ outputPath: `${target.projections[projectionType]}/${outputFileName}`
96
+ };
97
+ });
98
+ });
99
+ }
100
+
101
+ function buildManagedManifest(targetIds = ['antigravity']) {
102
+ return toArray(targetIds).flatMap((targetId) => {
103
+ const target = getTarget(targetId);
104
+ const entries = buildProjectionEntries(target.id).map((entry) => ({
105
+ ...entry,
106
+ targetId: target.id,
107
+ targetLabel: target.label,
108
+ ownershipKey: `${target.id}:${entry.outputPath}`
109
+ }));
110
+
111
+ if (!target.rootAgentFile) {
112
+ return entries;
113
+ }
114
+
115
+ return [
116
+ {
117
+ id: 'root-agents',
118
+ type: 'root',
119
+ source: 'AGENTS.md',
120
+ fileName: 'AGENTS.md',
121
+ projectionType: 'rootAgentFile',
122
+ outputRoot: '.',
123
+ outputPath: 'AGENTS.md',
124
+ targetId: target.id,
125
+ targetLabel: target.label,
126
+ ownershipKey: `${target.id}:AGENTS.md`
127
+ },
128
+ ...entries
129
+ ];
130
+ });
131
+ }
132
+
133
+ function buildProjectionPlan(targetIds = ['antigravity'], resources = RESOURCE_REGISTRY) {
134
+ return toArray(targetIds).map((targetId) => {
135
+ const target = getTarget(targetId);
136
+ const typeMap = target.projectionTypes;
137
+ const projectionEntries = resources.flatMap((resource) => {
138
+ if (resource.targets && !resource.targets.includes(target.id)) {
139
+ return [];
140
+ }
141
+ const projectionTypes = typeMap[resource.type];
142
+ if (!projectionTypes) {
143
+ return [];
144
+ }
145
+
146
+ return toArray(projectionTypes).map((projectionType) => {
147
+ const outputFileName = toProjectionFileName(resource, projectionType, target.id);
148
+ const outputPath = `${target.projections[projectionType]}/${outputFileName}`;
149
+ return {
150
+ ...resource,
151
+ projectionType,
152
+ outputRoot: target.projections[projectionType],
153
+ outputPath,
154
+ targetId: target.id,
155
+ targetLabel: target.label,
156
+ ownershipKey: `${target.id}:${outputPath}`
157
+ };
158
+ });
159
+ });
160
+
161
+ const managedFiles = target.rootAgentFile
162
+ ? ['AGENTS.md', ...projectionEntries.map((item) => item.outputPath)]
163
+ : projectionEntries.map((item) => item.outputPath);
164
+
165
+ return {
166
+ target,
167
+ targetId: target.id,
168
+ targetLabel: target.label,
169
+ managedFiles,
170
+ userProtectedFiles: buildUserProtectedFiles(target.id),
171
+ projectionEntries,
172
+ ownership: projectionEntries.map((item) => item.ownershipKey)
173
+ };
174
+ });
175
+ }
176
+
177
+ function buildManagedFiles(targetId = 'antigravity') {
178
+ return buildManagedManifest(targetId).map((item) => item.outputPath);
179
+ }
180
+
181
+ function buildUserProtectedFiles(targetId = 'antigravity') {
182
+ const target = getTarget(targetId);
183
+ return target.rootAgentFile ? ['AGENTS.md'] : [];
184
+ }
185
+
186
+ function findByType(type) {
187
+ return RESOURCE_REGISTRY.filter((item) => item.type === type);
188
+ }
189
+
190
+ const MANAGED_FILES = buildManagedFiles('antigravity');
191
+
192
+ /**
193
+ * USER_PROTECTED_FILES — 用户保护文件
194
+ *
195
+ * 这些文件在项目初始化后通常会包含特定于项目的配置。
196
+ * anws update 默认会跳过这些文件。
197
+ */
198
+ const USER_PROTECTED_FILES = buildUserProtectedFiles('antigravity');
199
+
200
+ module.exports = {
201
+ RESOURCE_REGISTRY,
202
+ buildManagedManifest,
203
+ buildProjectionPlan,
204
+ buildManagedFiles,
205
+ buildProjectionEntries,
206
+ buildUserProtectedFiles,
207
+ findByType,
208
+ MANAGED_FILES,
209
+ USER_PROTECTED_FILES
210
+ };
211
+
212
+
213
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haaaiawd/anws",
3
- "version": "2.2.5",
3
+ "version": "2.3.0",
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",
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## name: code-reviewer
4
4
 
5
- description: 纯静态「契约忠实度 / 实现侧证据」审查:对照 PRD、ADR、系统设计、05A_TASKS 与 05B_VERIFICATION_PLAN,围绕契约闭合、任务兑现、架构健康、安全边界、验证证据与回流一致性产出可追溯结论;供 /challenge(CODE/FULL)与 /forge(Step 3 §3.4.5 波末)共用。
5
+ description: 纯静态「契约忠实度 / 实现侧证据」审查:对照 PRD、ADR、系统设计、05A_TASKS 与 05B_VERIFICATION_PLAN,围绕契约闭合、任务兑现、架构健康、安全边界、验证证据与回流一致性产出可追溯结论;供 /challenge(CODE/FULL)与 /forge(Step 3 §3.6 波末)共用。
6
6
 
7
7
  # Code Reviewer — 实现侧证据层
8
8
 
@@ -24,12 +24,24 @@ description: 纯静态「契约忠实度 / 实现侧证据」审查:对照 PRD
24
24
  ## 激活时机
25
25
 
26
26
  - `**/challenge`**:`REVIEW_MODE` = `CODE` / `FULL`,或从 design/task 审查**自适应升级**到实现侧。
27
- - `**/forge`**:Step 3 §3.4.5 波末门禁(本波最后一项任务、§3.4 自动侧通过后,§3.4.6 之前;默认**每波一次**)。`/forge` 在 §3.4.5 之后另有 **§3.4.5.1 极简交付索引表**(workflow 规定,**非**本 skill 的报告体,不得用该表替代正文)。
27
+ - `**/forge`**:Step 3 **§3.6 波末门禁**(本波最后一项任务的 §3.5 提交完成后,强制执行;默认**每波一次**)。`/forge` 在 §3.6 之后另有 **§3.8 交付索引表**(workflow 规定,**非**本 skill 的报告体,**不得**用该表替代审查正文)。
28
28
 
29
- ## 执行形态(宿主能力)
29
+ ## 执行形态(默认:当前会话完整执行)
30
30
 
31
- - **有子代理**:若环境提供子代理 / Task / 并行会话等能力,**优先**启动**子代理**专职跑本 skill(与编码/导航会话隔离上下文,减少串话);**产出格式、Lens、证据规则仍以本文件为准**,子代理不得自行删减。
32
- - **无子代理**:由**当前会话**按本 skill **完整**执行;**不得**以「没有子代理」为理由降低证据或跳过 Lens
31
+ - **默认路径**:由**当前会话**按本 skill **完整**执行 Lens 1–6,按「输出结构(精简)」六段输出审查全文。这是 baseline,没有任何前置条件。
32
+ - **可选优化**:若宿主明确提供子代理 / Task / 并行会话能力,**可**委派子代理跑本 skill 以隔离上下文。但子代理只是执行容器,**产出格式、Lens、证据规则仍以本文件为准**,子代理不得自行删减。
33
+ - **禁止借口**:**不得**以「没有子代理」「上下文不够」「改动不大」「时间紧」等理由降低证据要求、跳过 Lens 或跳过执行。`/forge` 中的豁免**只能**由用户在波次签名时明示。
34
+
35
+ ## 落盘要求(`/forge` 路径强制)
36
+
37
+ 由 `/forge` §3.6 触发时,审查全文**必须**写入物理文件:
38
+
39
+ - **路径**:`{TARGET_DIR}/wave-reviews/wave-{N}-review.md`(`{N}` 为当前 Wave 序号)
40
+ - **首行**:以 `# Wave {N} Code Review — {YYYY-MM-DD}` 开头
41
+ - **不落盘 = §4.0 硬阻塞**,无任何例外(含 AUTO 模式)。表格自填、口头声称"已审查"一律视为未执行。
42
+ - 用户豁免时**不写**审查文件,改为创建 `{TARGET_DIR}/wave-reviews/wave-{N}-WAIVED.md`(详见 `/forge` §3.6 豁免协议)。
43
+
44
+ 由 `/challenge` 触发时,按 `/challenge` 工作流的报告路径写入(默认进入 `07_CHALLENGE_REPORT.md` 的对应章节),不强制独立落盘到 `wave-reviews/`。
33
45
 
34
46
  ## 必读输入
35
47