@haaaiawd/anws 2.2.0 → 2.2.2
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 +180 -343
- package/bin/cli.js +112 -112
- package/lib/changelog.js +258 -258
- package/lib/copy.js +116 -109
- package/lib/diff.js +11 -0
- package/lib/manifest.js +4 -1
- package/lib/update.js +319 -319
- package/package.json +4 -3
- package/templates/.agents/skills/anws-system/SKILL.md +9 -7
- package/templates/.agents/skills/code-reviewer/SKILL.md +102 -327
- package/templates/.agents/skills/concept-modeler/SKILL.md +19 -17
- package/templates/.agents/skills/craft-authoring/SKILL.md +123 -0
- package/templates/.agents/skills/e2e-testing-guide/SKILL.md +59 -0
- package/templates/.agents/skills/system-designer/SKILL.md +6 -6
- package/templates/.agents/skills/system-designer/references/system-design-template.md +17 -17
- package/templates/.agents/skills/task-planner/SKILL.md +113 -113
- package/templates/.agents/skills/task-planner/references/TASK_TEMPLATE.md +82 -82
- package/templates/.agents/workflows/blueprint.md +284 -284
- package/templates/.agents/workflows/challenge.md +450 -491
- package/templates/.agents/workflows/change.md +263 -286
- package/templates/.agents/workflows/craft.md +243 -664
- package/templates/.agents/workflows/design-system.md +624 -624
- package/templates/.agents/workflows/explore.md +400 -371
- package/templates/.agents/workflows/forge.md +444 -413
- package/templates/.agents/workflows/genesis.md +342 -395
- package/templates/.agents/workflows/probe.md +21 -16
- package/templates/.agents/workflows/quickstart.md +123 -138
- package/templates/AGENTS.md +149 -134
package/lib/copy.js
CHANGED
|
@@ -1,109 +1,116 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('node:fs/promises');
|
|
4
|
-
const path = require('node:path');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 递归复制目录,返回已写入的文件路径数组(相对于 destDir)。
|
|
8
|
-
*
|
|
9
|
-
* @param {string} srcDir 源目录绝对路径
|
|
10
|
-
* @param {string} destDir 目标目录绝对路径(不存在时自动创建)
|
|
11
|
-
* @returns {Promise<string[]>} 已写入文件的绝对路径列表
|
|
12
|
-
*/
|
|
13
|
-
async function copyDir(srcDir, destDir) {
|
|
14
|
-
const written = [];
|
|
15
|
-
|
|
16
|
-
async function walk(src, dest) {
|
|
17
|
-
await fs.mkdir(dest, { recursive: true });
|
|
18
|
-
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
19
|
-
|
|
20
|
-
for (const entry of entries) {
|
|
21
|
-
const srcPath = path.join(src, entry.name);
|
|
22
|
-
const destPath = path.join(dest, entry.name);
|
|
23
|
-
|
|
24
|
-
if (entry.isDirectory()) {
|
|
25
|
-
await walk(srcPath, destPath);
|
|
26
|
-
} else if (entry.isFile()) {
|
|
27
|
-
await fs.copyFile(srcPath, destPath);
|
|
28
|
-
written.push(destPath);
|
|
29
|
-
}
|
|
30
|
-
// 忽略 symlink 等特殊文件类型
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
await walk(srcDir, destDir);
|
|
35
|
-
return written;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function pathExists(targetPath) {
|
|
39
|
-
return fs.access(targetPath).then(() => true).catch(() => false);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async function writeTargetFiles(cwd, options = {}) {
|
|
43
|
-
const targetPlan = options.targetPlan || {};
|
|
44
|
-
const protectedFiles = options.protectedFiles || targetPlan.userProtectedFiles || [];
|
|
45
|
-
const projectionEntries = targetPlan.projectionEntries || [];
|
|
46
|
-
const shouldWriteRootAgents = options.shouldWriteRootAgents !== false;
|
|
47
|
-
const srcAgents = options.srcAgents;
|
|
48
|
-
const agentsUpdatePlan = options.agentsUpdatePlan;
|
|
49
|
-
const resolveCanonicalSource = options.resolveCanonicalSource;
|
|
50
|
-
const projectionMap = new Map(projectionEntries.map((item) => [item.outputPath, item]));
|
|
51
|
-
const written = [];
|
|
52
|
-
const skipped = [];
|
|
53
|
-
|
|
54
|
-
for (const rel of targetPlan.managedFiles || []) {
|
|
55
|
-
if (rel === 'AGENTS.md' && !shouldWriteRootAgents) {
|
|
56
|
-
skipped.push(rel);
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (rel === 'AGENTS.md') {
|
|
61
|
-
const destPath = path.join(cwd, rel);
|
|
62
|
-
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
|
63
|
-
|
|
64
|
-
if (agentsUpdatePlan && agentsUpdatePlan.mode === 'skip') {
|
|
65
|
-
skipped.push(rel);
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (agentsUpdatePlan && agentsUpdatePlan.content) {
|
|
70
|
-
await fs.writeFile(destPath, agentsUpdatePlan.content, 'utf8');
|
|
71
|
-
written.push(rel);
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (await pathExists(srcAgents)) {
|
|
76
|
-
await fs.copyFile(srcAgents, destPath);
|
|
77
|
-
written.push(rel);
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (protectedFiles.includes(rel)) {
|
|
83
|
-
const destPath = path.join(cwd, rel);
|
|
84
|
-
if (await pathExists(destPath)) {
|
|
85
|
-
skipped.push(rel);
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const entry = projectionMap.get(rel);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs/promises');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 递归复制目录,返回已写入的文件路径数组(相对于 destDir)。
|
|
8
|
+
*
|
|
9
|
+
* @param {string} srcDir 源目录绝对路径
|
|
10
|
+
* @param {string} destDir 目标目录绝对路径(不存在时自动创建)
|
|
11
|
+
* @returns {Promise<string[]>} 已写入文件的绝对路径列表
|
|
12
|
+
*/
|
|
13
|
+
async function copyDir(srcDir, destDir) {
|
|
14
|
+
const written = [];
|
|
15
|
+
|
|
16
|
+
async function walk(src, dest) {
|
|
17
|
+
await fs.mkdir(dest, { recursive: true });
|
|
18
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
19
|
+
|
|
20
|
+
for (const entry of entries) {
|
|
21
|
+
const srcPath = path.join(src, entry.name);
|
|
22
|
+
const destPath = path.join(dest, entry.name);
|
|
23
|
+
|
|
24
|
+
if (entry.isDirectory()) {
|
|
25
|
+
await walk(srcPath, destPath);
|
|
26
|
+
} else if (entry.isFile()) {
|
|
27
|
+
await fs.copyFile(srcPath, destPath);
|
|
28
|
+
written.push(destPath);
|
|
29
|
+
}
|
|
30
|
+
// 忽略 symlink 等特殊文件类型
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
await walk(srcDir, destDir);
|
|
35
|
+
return written;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function pathExists(targetPath) {
|
|
39
|
+
return fs.access(targetPath).then(() => true).catch(() => false);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function writeTargetFiles(cwd, options = {}) {
|
|
43
|
+
const targetPlan = options.targetPlan || {};
|
|
44
|
+
const protectedFiles = options.protectedFiles || targetPlan.userProtectedFiles || [];
|
|
45
|
+
const projectionEntries = targetPlan.projectionEntries || [];
|
|
46
|
+
const shouldWriteRootAgents = options.shouldWriteRootAgents !== false;
|
|
47
|
+
const srcAgents = options.srcAgents;
|
|
48
|
+
const agentsUpdatePlan = options.agentsUpdatePlan;
|
|
49
|
+
const resolveCanonicalSource = options.resolveCanonicalSource;
|
|
50
|
+
const projectionMap = new Map(projectionEntries.map((item) => [item.outputPath, item]));
|
|
51
|
+
const written = [];
|
|
52
|
+
const skipped = [];
|
|
53
|
+
|
|
54
|
+
for (const rel of targetPlan.managedFiles || []) {
|
|
55
|
+
if (rel === 'AGENTS.md' && !shouldWriteRootAgents) {
|
|
56
|
+
skipped.push(rel);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (rel === 'AGENTS.md') {
|
|
61
|
+
const destPath = path.join(cwd, rel);
|
|
62
|
+
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
|
63
|
+
|
|
64
|
+
if (agentsUpdatePlan && agentsUpdatePlan.mode === 'skip') {
|
|
65
|
+
skipped.push(rel);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (agentsUpdatePlan && agentsUpdatePlan.content) {
|
|
70
|
+
await fs.writeFile(destPath, agentsUpdatePlan.content, 'utf8');
|
|
71
|
+
written.push(rel);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (await pathExists(srcAgents)) {
|
|
76
|
+
await fs.copyFile(srcAgents, destPath);
|
|
77
|
+
written.push(rel);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (protectedFiles.includes(rel)) {
|
|
83
|
+
const destPath = path.join(cwd, rel);
|
|
84
|
+
if (await pathExists(destPath)) {
|
|
85
|
+
skipped.push(rel);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const entry = projectionMap.get(rel);
|
|
91
|
+
if (!entry) {
|
|
92
|
+
throw new Error(`anws: managed file "${rel}" has no projection entry — manifest/registry mismatch`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const destPath = path.join(cwd, rel);
|
|
96
|
+
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
|
97
|
+
|
|
98
|
+
const srcPath = resolveCanonicalSource(entry.source);
|
|
99
|
+
if (!(await pathExists(srcPath))) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
`anws: missing canonical template for "${rel}" (${entry.source}). Expected: ${srcPath}`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
await fs.copyFile(srcPath, destPath);
|
|
105
|
+
written.push(rel);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
targetId: targetPlan.targetId,
|
|
110
|
+
targetLabel: targetPlan.targetLabel,
|
|
111
|
+
written,
|
|
112
|
+
skipped
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
module.exports = { copyDir, writeTargetFiles };
|
package/lib/diff.js
CHANGED
|
@@ -145,6 +145,10 @@ async function collectManagedFileDiffs({
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
const entry = projectionMap.get(rel);
|
|
148
|
+
if (!entry && rel !== 'AGENTS.md') {
|
|
149
|
+
throw new Error(`anws: managed file "${rel}" has no projection entry — manifest/registry mismatch`);
|
|
150
|
+
}
|
|
151
|
+
|
|
148
152
|
const metadata = entry
|
|
149
153
|
? {
|
|
150
154
|
source: entry.source,
|
|
@@ -161,6 +165,13 @@ async function collectManagedFileDiffs({
|
|
|
161
165
|
const srcPath = rel === 'AGENTS.md'
|
|
162
166
|
? srcAgents
|
|
163
167
|
: path.join(path.join(__dirname, '..', 'templates'), entry.source);
|
|
168
|
+
|
|
169
|
+
if (rel !== 'AGENTS.md' && !(await pathExists(srcPath))) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
`anws: missing canonical template for "${rel}" (${entry.source}). Expected: ${srcPath}`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
164
175
|
const existing = rel === 'AGENTS.md'
|
|
165
176
|
? { file: rel, absolutePath: path.join(cwd, rel), sourceKind: 'current' }
|
|
166
177
|
: await resolveExistingManagedPath(cwd, rel);
|
package/lib/manifest.js
CHANGED
|
@@ -21,6 +21,7 @@ const RESOURCE_REGISTRY = [
|
|
|
21
21
|
{ id: 'upgrade', type: 'workflow', source: '.agents/workflows/upgrade.md', fileName: 'upgrade.md' },
|
|
22
22
|
{ id: 'anws-system', type: 'skill', source: '.agents/skills/anws-system/SKILL.md', fileName: 'anws-system/SKILL.md', targets: ['codex', 'trae'] },
|
|
23
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' },
|
|
24
25
|
{ id: 'design-reviewer', type: 'skill', source: '.agents/skills/design-reviewer/SKILL.md', fileName: 'design-reviewer/SKILL.md' },
|
|
25
26
|
{ id: 'nexus-mapper', type: 'skill', source: '.agents/skills/nexus-mapper/SKILL.md', fileName: 'nexus-mapper/SKILL.md' },
|
|
26
27
|
{ id: 'nexus-mapper-language-customization', type: 'skill', source: '.agents/skills/nexus-mapper/references/language-customization.md', fileName: 'nexus-mapper/references/language-customization.md' },
|
|
@@ -46,7 +47,9 @@ const RESOURCE_REGISTRY = [
|
|
|
46
47
|
{ id: 'task-planner-template', type: 'skill', source: '.agents/skills/task-planner/references/TASK_TEMPLATE.md', fileName: 'task-planner/references/TASK_TEMPLATE.md' },
|
|
47
48
|
{ id: 'task-reviewer', type: 'skill', source: '.agents/skills/task-reviewer/SKILL.md', fileName: 'task-reviewer/SKILL.md' },
|
|
48
49
|
{ 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
|
+
{ 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' }
|
|
50
53
|
];
|
|
51
54
|
|
|
52
55
|
function toArray(value) {
|