@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.
Files changed (28) hide show
  1. package/README.md +180 -343
  2. package/bin/cli.js +112 -112
  3. package/lib/changelog.js +258 -258
  4. package/lib/copy.js +116 -109
  5. package/lib/diff.js +11 -0
  6. package/lib/manifest.js +4 -1
  7. package/lib/update.js +319 -319
  8. package/package.json +4 -3
  9. package/templates/.agents/skills/anws-system/SKILL.md +9 -7
  10. package/templates/.agents/skills/code-reviewer/SKILL.md +102 -327
  11. package/templates/.agents/skills/concept-modeler/SKILL.md +19 -17
  12. package/templates/.agents/skills/craft-authoring/SKILL.md +123 -0
  13. package/templates/.agents/skills/e2e-testing-guide/SKILL.md +59 -0
  14. package/templates/.agents/skills/system-designer/SKILL.md +6 -6
  15. package/templates/.agents/skills/system-designer/references/system-design-template.md +17 -17
  16. package/templates/.agents/skills/task-planner/SKILL.md +113 -113
  17. package/templates/.agents/skills/task-planner/references/TASK_TEMPLATE.md +82 -82
  18. package/templates/.agents/workflows/blueprint.md +284 -284
  19. package/templates/.agents/workflows/challenge.md +450 -491
  20. package/templates/.agents/workflows/change.md +263 -286
  21. package/templates/.agents/workflows/craft.md +243 -664
  22. package/templates/.agents/workflows/design-system.md +624 -624
  23. package/templates/.agents/workflows/explore.md +400 -371
  24. package/templates/.agents/workflows/forge.md +444 -413
  25. package/templates/.agents/workflows/genesis.md +342 -395
  26. package/templates/.agents/workflows/probe.md +21 -16
  27. package/templates/.agents/workflows/quickstart.md +123 -138
  28. package/templates/AGENTS.md +149 -134
package/lib/update.js CHANGED
@@ -1,319 +1,319 @@
1
- 'use strict';
2
-
3
- const fs = require('node:fs/promises');
4
- const path = require('node:path');
5
- const { buildProjectionPlan } = require('./manifest');
6
- const { getTarget } = require('./adapters');
7
- const { planAgentsUpdate, resolveAgentsInstall, printLegacyMigrationWarning, pathExists } = require('./agents');
8
- const { collectManagedFileDiffs } = require('./diff');
9
- const { detectUpgrade, generateChangelog } = require('./changelog');
10
- const { writeTargetFiles } = require('./copy');
11
- const { createInstallLock, dedupeTargets, detectInstallState, summarizeTargetState, writeInstallLock } = require('./install-state');
12
- const { confirm } = require('./prompt');
13
- const { ROOT_AGENTS_FILE, resolveCanonicalSource } = require('./resources');
14
- const { warn, error, info, fileLine, skippedLine, blank, logo, section } = require('./output');
15
-
16
- async function update() {
17
- const cwd = process.cwd();
18
- const legacyAgentDir = path.join(cwd, '.agent');
19
- const { version } = require(path.join(__dirname, '..', 'package.json'));
20
- const installState = await detectInstallState(cwd);
21
- const legacyAgentExists = await pathExists(legacyAgentDir);
22
- const isLegacyMigration = installState.selectedTargets.length === 0 && legacyAgentExists;
23
- const detectedTargetIds = isLegacyMigration ? ['antigravity'] : installState.selectedTargets;
24
-
25
- if (detectedTargetIds.length === 0 && !legacyAgentExists) {
26
- logo();
27
- error('No supported Anws target layout found in current directory.');
28
- info('Run `anws init` first to set up the workflow system.');
29
- process.exit(1);
30
- }
31
-
32
- const targetPlans = buildProjectionPlan(detectedTargetIds);
33
- const detectedTargetPlans = buildProjectionPlan(detectedTargetIds);
34
-
35
- const srcAgents = ROOT_AGENTS_FILE;
36
-
37
- if (isLegacyMigration) {
38
- logo();
39
- blank();
40
- printLegacyMigrationNotice();
41
- blank();
42
- }
43
-
44
- const versionState = await detectUpgrade({ cwd, version });
45
- const targetContexts = [];
46
-
47
- for (const targetPlan of targetPlans) {
48
- const target = getTarget(targetPlan.targetId);
49
- const agentsDecision = target.id === 'antigravity'
50
- ? await resolveAgentsInstall({
51
- cwd,
52
- askMigrate,
53
- forceYes: !!global.__ANWS_FORCE_YES
54
- })
55
- : {
56
- shouldWriteRootAgents: false,
57
- shouldWarnMigration: false,
58
- rootExists: false,
59
- legacyExists: false
60
- };
61
-
62
- if (!agentsDecision.shouldWriteRootAgents && agentsDecision.legacyExists) {
63
- info('Keeping legacy .agent/rules/agents.md. Will not pull root AGENTS.md.');
64
- }
65
- if (agentsDecision.shouldWarnMigration) {
66
- printLegacyMigrationWarning();
67
- }
68
-
69
- let agentsUpdatePlan = null;
70
- if (agentsDecision.shouldWriteRootAgents && agentsDecision.rootExists) {
71
- const templateContent = await fs.readFile(srcAgents, 'utf8');
72
- const existingContent = await fs.readFile(path.join(cwd, 'AGENTS.md'), 'utf8');
73
- agentsUpdatePlan = planAgentsUpdate({ templateContent, existingContent });
74
-
75
- if (agentsUpdatePlan.warning) {
76
- warn(agentsUpdatePlan.warning);
77
- }
78
- }
79
-
80
- const rawChanges = await collectManagedFileDiffs({
81
- cwd,
82
- projectionPlan: [targetPlan],
83
- srcAgents,
84
- shouldWriteRootAgents: agentsDecision.shouldWriteRootAgents,
85
- agentsUpdatePlan
86
- });
87
- const changes = rawChanges.filter((item) => {
88
- if (item.file !== 'AGENTS.md') return true;
89
- if (agentsUpdatePlan && agentsUpdatePlan.mode === 'skip') return false;
90
- return agentsDecision.shouldWriteRootAgents;
91
- });
92
-
93
- targetContexts.push({
94
- target,
95
- targetPlan,
96
- agentsDecision,
97
- agentsUpdatePlan,
98
- changes
99
- });
100
- }
101
-
102
- const changes = targetContexts.flatMap((context) => context.changes);
103
-
104
- if (!versionState.needUpgrade) {
105
- if (!isLegacyMigration) {
106
- logo();
107
- blank();
108
- }
109
- printTargetSelection(installState, targetContexts.map((context) => context.target));
110
- if (installState.canRebuildLock && detectedTargetIds.length > 0) {
111
- const generatedAt = new Date().toISOString();
112
- await writeInstallLock(cwd, createInstallLock({
113
- cliVersion: version,
114
- generatedAt,
115
- targets: dedupeTargets(detectedTargetPlans.map((targetPlan) => summarizeTargetState(targetPlan, version))),
116
- lastUpdateSummary: {
117
- successfulTargets: [],
118
- failedTargets: [],
119
- updatedAt: generatedAt
120
- }
121
- }));
122
- info('Rebuilt .anws/install-lock.json from the detected target layout.');
123
- }
124
- info(`Already up to date. Latest recorded version is v${versionState.latestVersion || version}.`);
125
- return;
126
- }
127
-
128
- if (!isLegacyMigration) {
129
- logo();
130
- blank();
131
- }
132
-
133
- printTargetSelection(installState, targetContexts.map((context) => context.target));
134
-
135
- const updated = [];
136
- const skipped = [];
137
- const successfulTargets = [];
138
- const failedTargets = [];
139
-
140
- for (const context of targetContexts) {
141
- try {
142
- const result = await writeTargetFiles(cwd, {
143
- targetPlan: context.targetPlan,
144
- protectedFiles: context.targetPlan.userProtectedFiles,
145
- srcAgents,
146
- shouldWriteRootAgents: context.agentsDecision.shouldWriteRootAgents,
147
- agentsUpdatePlan: context.agentsUpdatePlan,
148
- resolveCanonicalSource
149
- });
150
-
151
- updated.push(...result.written);
152
- skipped.push(...result.skipped);
153
- successfulTargets.push(summarizeTargetState(context.targetPlan, version));
154
- } catch (error) {
155
- failedTargets.push({
156
- targetId: context.target.id,
157
- targetLabel: context.target.label,
158
- reason: error.message
159
- });
160
- }
161
- }
162
-
163
- blank();
164
- info('Updated files:');
165
- blank();
166
- for (const rel of updated) {
167
- fileLine(rel.replace(/\\/g, '/'));
168
- }
169
-
170
- if (skipped.length > 0) {
171
- blank();
172
- info('Skipped (project-specific, preserved):');
173
- for (const rel of skipped) {
174
- skippedLine(rel.replace(/\\/g, '/'));
175
- }
176
- }
177
-
178
- printTargetUpdateSummary(successfulTargets, failedTargets);
179
-
180
- const changelogPath = await generateChangelog({
181
- cwd,
182
- version,
183
- changes,
184
- targetSummary: {
185
- successfulTargets: successfulTargets.map((item) => `${item.targetLabel} (${item.targetId})`),
186
- failedTargets: failedTargets.map((item) => `${item.targetLabel} (${item.targetId})`)
187
- }
188
- });
189
- const generatedAt = new Date().toISOString();
190
- const successfulTargetIdSet = new Set(successfulTargets.map((item) => item.targetId));
191
- const retainedDetectedTargets = installState.canRebuildLock
192
- ? detectedTargetPlans
193
- .filter((targetPlan) => !successfulTargetIdSet.has(targetPlan.targetId))
194
- .map((targetPlan) => summarizeTargetState(targetPlan, version))
195
- : [];
196
- const existingLockTargets = installState.canRebuildLock
197
- ? []
198
- : (installState.lockResult.lock?.targets || []);
199
- await writeInstallLock(cwd, createInstallLock({
200
- cliVersion: version,
201
- generatedAt,
202
- targets: dedupeTargets([
203
- ...existingLockTargets,
204
- ...retainedDetectedTargets,
205
- ...successfulTargets
206
- ]),
207
- lastUpdateSummary: {
208
- successfulTargets: successfulTargets.map((item) => item.targetId),
209
- failedTargets: failedTargets.map((item) => item.targetId),
210
- updatedAt: generatedAt
211
- }
212
- }));
213
-
214
- let legacyCleanupLine = '';
215
- if (isLegacyMigration) {
216
- legacyCleanupLine = 'Legacy .agent/ was preserved. You can review and delete it manually after migration.';
217
- const deleted = await maybeDeleteLegacyDir(legacyAgentDir);
218
- if (deleted) {
219
- legacyCleanupLine = 'Legacy .agent/ directory was deleted after confirmation.';
220
- }
221
- }
222
-
223
- printUpdateCompletionSummary({
224
- updatedCount: updated.length,
225
- skippedCount: skipped.length,
226
- changelogPath: path.relative(cwd, changelogPath).replace(/\\/g, '/'),
227
- legacyCleanupLine
228
- });
229
- }
230
-
231
- async function askMigrate() {
232
- if (global.__ANWS_FORCE_YES) return true;
233
-
234
- if (!process.stdin.isTTY) {
235
- return false;
236
- }
237
-
238
- return confirm({
239
- message: 'Legacy .agent/ directory detected. Migrate to .agents/?',
240
- confirmLabel: 'Migrate',
241
- cancelLabel: 'Keep legacy',
242
- defaultValue: false
243
- });
244
- }
245
-
246
- async function maybeDeleteLegacyDir(legacyAgentDir) {
247
- const exists = await pathExists(legacyAgentDir);
248
- if (!exists) return false;
249
-
250
- if (global.__ANWS_FORCE_YES) {
251
- return false;
252
- }
253
-
254
- if (!process.stdin.isTTY) {
255
- return false;
256
- }
257
-
258
- const shouldDelete = await confirm({
259
- message: 'Legacy .agent/ directory has been preserved. Delete it now?',
260
- confirmLabel: 'Delete',
261
- cancelLabel: 'Keep',
262
- defaultValue: false
263
- });
264
-
265
- if (!shouldDelete) return false;
266
-
267
- await fs.rm(legacyAgentDir, { recursive: true, force: true });
268
- return true;
269
- }
270
-
271
- function buildSelectionModeLine() {
272
- return 'Selection mode: detected target layout';
273
- }
274
-
275
- function printLegacyMigrationNotice() {
276
- section('Legacy migration', [
277
- 'Legacy .agent/ directory detected.',
278
- 'anws update will migrate managed files into the Antigravity target structure.',
279
- 'Your old .agent/ directory will be preserved for manual review.'
280
- ], { minWidth: 60 });
281
- }
282
-
283
- function printTargetSelection(installState, targets) {
284
- blank();
285
- section('Target selection', [
286
- buildSelectionModeLine(),
287
- `Matched targets: ${targets.map((target) => `${target.label} (${target.id})`).join(', ') || 'none'}`,
288
- installState.needsFallback ? 'State source: directory scan fallback' : 'State source: install-lock + directory scan',
289
- ...(installState.drift.hasDrift
290
- ? [`State drift detected. Missing on disk: ${installState.drift.missingOnDisk.join(', ') || 'none'}; untracked on disk: ${installState.drift.untrackedOnDisk.join(', ') || 'none'}.`]
291
- : [])
292
- ]);
293
- }
294
-
295
- function printTargetUpdateSummary(successfulTargets, failedTargets) {
296
- blank();
297
- section('Update summary by target', [
298
- ...successfulTargets.map((target) => `✔ ${target.targetLabel} (${target.targetId})`),
299
- ...failedTargets.map((target) => `✖ ${target.targetLabel} (${target.targetId}) — ${target.reason}`)
300
- ]);
301
- }
302
-
303
- function printUpdateCompletionSummary({ updatedCount, skippedCount, changelogPath, legacyCleanupLine }) {
304
- blank();
305
- section('Update completed', [
306
- `✔ Done! ${updatedCount} file(s) updated${skippedCount > 0 ? `, ${skippedCount} skipped` : ''}.`,
307
- 'Managed files have been updated to the latest version.',
308
- 'Your custom files outside the selected target projections were not touched.',
309
- ...(legacyCleanupLine ? [legacyCleanupLine] : []),
310
- `Generated upgrade record: ${changelogPath}`,
311
- 'Run `/upgrade` in your AI IDE to update your architecture docs.'
312
- ], { minWidth: 60 });
313
- }
314
-
315
- module.exports = update;
316
-
317
-
318
-
319
-
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const { buildProjectionPlan } = require('./manifest');
6
+ const { getTarget } = require('./adapters');
7
+ const { planAgentsUpdate, resolveAgentsInstall, printLegacyMigrationWarning, pathExists } = require('./agents');
8
+ const { collectManagedFileDiffs } = require('./diff');
9
+ const { detectUpgrade, generateChangelog } = require('./changelog');
10
+ const { writeTargetFiles } = require('./copy');
11
+ const { createInstallLock, dedupeTargets, detectInstallState, summarizeTargetState, writeInstallLock } = require('./install-state');
12
+ const { confirm } = require('./prompt');
13
+ const { ROOT_AGENTS_FILE, resolveCanonicalSource } = require('./resources');
14
+ const { warn, error, info, fileLine, skippedLine, blank, logo, section } = require('./output');
15
+
16
+ async function update() {
17
+ const cwd = process.cwd();
18
+ const legacyAgentDir = path.join(cwd, '.agent');
19
+ const { version } = require(path.join(__dirname, '..', 'package.json'));
20
+ const installState = await detectInstallState(cwd);
21
+ const legacyAgentExists = await pathExists(legacyAgentDir);
22
+ const isLegacyMigration = installState.selectedTargets.length === 0 && legacyAgentExists;
23
+ const detectedTargetIds = isLegacyMigration ? ['antigravity'] : installState.selectedTargets;
24
+
25
+ if (detectedTargetIds.length === 0 && !legacyAgentExists) {
26
+ logo();
27
+ error('No supported Anws target layout found in current directory.');
28
+ info('Run `anws init` first to set up the workflow system.');
29
+ process.exit(1);
30
+ }
31
+
32
+ const targetPlans = buildProjectionPlan(detectedTargetIds);
33
+ const detectedTargetPlans = buildProjectionPlan(detectedTargetIds);
34
+
35
+ const srcAgents = ROOT_AGENTS_FILE;
36
+
37
+ if (isLegacyMigration) {
38
+ logo();
39
+ blank();
40
+ printLegacyMigrationNotice();
41
+ blank();
42
+ }
43
+
44
+ const versionState = await detectUpgrade({ cwd, version });
45
+ const targetContexts = [];
46
+
47
+ for (const targetPlan of targetPlans) {
48
+ const target = getTarget(targetPlan.targetId);
49
+ const agentsDecision = target.id === 'antigravity'
50
+ ? await resolveAgentsInstall({
51
+ cwd,
52
+ askMigrate,
53
+ forceYes: !!global.__ANWS_FORCE_YES
54
+ })
55
+ : {
56
+ shouldWriteRootAgents: false,
57
+ shouldWarnMigration: false,
58
+ rootExists: false,
59
+ legacyExists: false
60
+ };
61
+
62
+ if (!agentsDecision.shouldWriteRootAgents && agentsDecision.legacyExists) {
63
+ info('Keeping legacy .agent/rules/agents.md. Will not pull root AGENTS.md.');
64
+ }
65
+ if (agentsDecision.shouldWarnMigration) {
66
+ printLegacyMigrationWarning();
67
+ }
68
+
69
+ let agentsUpdatePlan = null;
70
+ if (agentsDecision.shouldWriteRootAgents && agentsDecision.rootExists) {
71
+ const templateContent = await fs.readFile(srcAgents, 'utf8');
72
+ const existingContent = await fs.readFile(path.join(cwd, 'AGENTS.md'), 'utf8');
73
+ agentsUpdatePlan = planAgentsUpdate({ templateContent, existingContent });
74
+
75
+ if (agentsUpdatePlan.warning) {
76
+ warn(agentsUpdatePlan.warning);
77
+ }
78
+ }
79
+
80
+ const rawChanges = await collectManagedFileDiffs({
81
+ cwd,
82
+ projectionPlan: [targetPlan],
83
+ srcAgents,
84
+ shouldWriteRootAgents: agentsDecision.shouldWriteRootAgents,
85
+ agentsUpdatePlan
86
+ });
87
+ const changes = rawChanges.filter((item) => {
88
+ if (item.file !== 'AGENTS.md') return true;
89
+ if (agentsUpdatePlan && agentsUpdatePlan.mode === 'skip') return false;
90
+ return agentsDecision.shouldWriteRootAgents;
91
+ });
92
+
93
+ targetContexts.push({
94
+ target,
95
+ targetPlan,
96
+ agentsDecision,
97
+ agentsUpdatePlan,
98
+ changes
99
+ });
100
+ }
101
+
102
+ const changes = targetContexts.flatMap((context) => context.changes);
103
+
104
+ if (!versionState.needUpgrade) {
105
+ if (!isLegacyMigration) {
106
+ logo();
107
+ blank();
108
+ }
109
+ printTargetSelection(installState, targetContexts.map((context) => context.target));
110
+ if (installState.canRebuildLock && detectedTargetIds.length > 0) {
111
+ const generatedAt = new Date().toISOString();
112
+ await writeInstallLock(cwd, createInstallLock({
113
+ cliVersion: version,
114
+ generatedAt,
115
+ targets: dedupeTargets(detectedTargetPlans.map((targetPlan) => summarizeTargetState(targetPlan, version))),
116
+ lastUpdateSummary: {
117
+ successfulTargets: [],
118
+ failedTargets: [],
119
+ updatedAt: generatedAt
120
+ }
121
+ }));
122
+ info('Rebuilt .anws/install-lock.json from the detected target layout.');
123
+ }
124
+ info(`Already up to date. Latest recorded version is v${versionState.latestVersion || version}.`);
125
+ return;
126
+ }
127
+
128
+ if (!isLegacyMigration) {
129
+ logo();
130
+ blank();
131
+ }
132
+
133
+ printTargetSelection(installState, targetContexts.map((context) => context.target));
134
+
135
+ const updated = [];
136
+ const skipped = [];
137
+ const successfulTargets = [];
138
+ const failedTargets = [];
139
+
140
+ for (const context of targetContexts) {
141
+ try {
142
+ const result = await writeTargetFiles(cwd, {
143
+ targetPlan: context.targetPlan,
144
+ protectedFiles: context.targetPlan.userProtectedFiles,
145
+ srcAgents,
146
+ shouldWriteRootAgents: context.agentsDecision.shouldWriteRootAgents,
147
+ agentsUpdatePlan: context.agentsUpdatePlan,
148
+ resolveCanonicalSource
149
+ });
150
+
151
+ updated.push(...result.written);
152
+ skipped.push(...result.skipped);
153
+ successfulTargets.push(summarizeTargetState(context.targetPlan, version));
154
+ } catch (error) {
155
+ failedTargets.push({
156
+ targetId: context.target.id,
157
+ targetLabel: context.target.label,
158
+ reason: error.message
159
+ });
160
+ }
161
+ }
162
+
163
+ blank();
164
+ info('Updated files:');
165
+ blank();
166
+ for (const rel of updated) {
167
+ fileLine(rel.replace(/\\/g, '/'));
168
+ }
169
+
170
+ if (skipped.length > 0) {
171
+ blank();
172
+ info('Skipped (project-specific, preserved):');
173
+ for (const rel of skipped) {
174
+ skippedLine(rel.replace(/\\/g, '/'));
175
+ }
176
+ }
177
+
178
+ printTargetUpdateSummary(successfulTargets, failedTargets);
179
+
180
+ const changelogPath = await generateChangelog({
181
+ cwd,
182
+ version,
183
+ changes,
184
+ targetSummary: {
185
+ successfulTargets: successfulTargets.map((item) => `${item.targetLabel} (${item.targetId})`),
186
+ failedTargets: failedTargets.map((item) => `${item.targetLabel} (${item.targetId})`)
187
+ }
188
+ });
189
+ const generatedAt = new Date().toISOString();
190
+ const successfulTargetIdSet = new Set(successfulTargets.map((item) => item.targetId));
191
+ const retainedDetectedTargets = installState.canRebuildLock
192
+ ? detectedTargetPlans
193
+ .filter((targetPlan) => !successfulTargetIdSet.has(targetPlan.targetId))
194
+ .map((targetPlan) => summarizeTargetState(targetPlan, version))
195
+ : [];
196
+ const existingLockTargets = installState.canRebuildLock
197
+ ? []
198
+ : (installState.lockResult.lock?.targets || []);
199
+ await writeInstallLock(cwd, createInstallLock({
200
+ cliVersion: version,
201
+ generatedAt,
202
+ targets: dedupeTargets([
203
+ ...existingLockTargets,
204
+ ...retainedDetectedTargets,
205
+ ...successfulTargets
206
+ ]),
207
+ lastUpdateSummary: {
208
+ successfulTargets: successfulTargets.map((item) => item.targetId),
209
+ failedTargets: failedTargets.map((item) => item.targetId),
210
+ updatedAt: generatedAt
211
+ }
212
+ }));
213
+
214
+ let legacyCleanupLine = '';
215
+ if (isLegacyMigration) {
216
+ legacyCleanupLine = 'Legacy .agent/ was preserved. You can review and delete it manually after migration.';
217
+ const deleted = await maybeDeleteLegacyDir(legacyAgentDir);
218
+ if (deleted) {
219
+ legacyCleanupLine = 'Legacy .agent/ directory was deleted after confirmation.';
220
+ }
221
+ }
222
+
223
+ printUpdateCompletionSummary({
224
+ updatedCount: updated.length,
225
+ skippedCount: skipped.length,
226
+ changelogPath: path.relative(cwd, changelogPath).replace(/\\/g, '/'),
227
+ legacyCleanupLine
228
+ });
229
+ }
230
+
231
+ async function askMigrate() {
232
+ if (global.__ANWS_FORCE_YES) return true;
233
+
234
+ if (!process.stdin.isTTY) {
235
+ return false;
236
+ }
237
+
238
+ return confirm({
239
+ message: 'Legacy .agent/ directory detected. Migrate to .agents/?',
240
+ confirmLabel: 'Migrate',
241
+ cancelLabel: 'Keep legacy',
242
+ defaultValue: false
243
+ });
244
+ }
245
+
246
+ async function maybeDeleteLegacyDir(legacyAgentDir) {
247
+ const exists = await pathExists(legacyAgentDir);
248
+ if (!exists) return false;
249
+
250
+ if (global.__ANWS_FORCE_YES) {
251
+ return false;
252
+ }
253
+
254
+ if (!process.stdin.isTTY) {
255
+ return false;
256
+ }
257
+
258
+ const shouldDelete = await confirm({
259
+ message: 'Legacy .agent/ directory has been preserved. Delete it now?',
260
+ confirmLabel: 'Delete',
261
+ cancelLabel: 'Keep',
262
+ defaultValue: false
263
+ });
264
+
265
+ if (!shouldDelete) return false;
266
+
267
+ await fs.rm(legacyAgentDir, { recursive: true, force: true });
268
+ return true;
269
+ }
270
+
271
+ function buildSelectionModeLine() {
272
+ return 'Selection mode: detected target layout';
273
+ }
274
+
275
+ function printLegacyMigrationNotice() {
276
+ section('Legacy migration', [
277
+ 'Legacy .agent/ directory detected.',
278
+ 'anws update will migrate managed files into the Antigravity target structure.',
279
+ 'Your old .agent/ directory will be preserved for manual review.'
280
+ ], { minWidth: 60 });
281
+ }
282
+
283
+ function printTargetSelection(installState, targets) {
284
+ blank();
285
+ section('Target selection', [
286
+ buildSelectionModeLine(),
287
+ `Matched targets: ${targets.map((target) => `${target.label} (${target.id})`).join(', ') || 'none'}`,
288
+ installState.needsFallback ? 'State source: directory scan fallback' : 'State source: install-lock + directory scan',
289
+ ...(installState.drift.hasDrift
290
+ ? [`State drift detected. Missing on disk: ${installState.drift.missingOnDisk.join(', ') || 'none'}; untracked on disk: ${installState.drift.untrackedOnDisk.join(', ') || 'none'}.`]
291
+ : [])
292
+ ]);
293
+ }
294
+
295
+ function printTargetUpdateSummary(successfulTargets, failedTargets) {
296
+ blank();
297
+ section('Update summary by target', [
298
+ ...successfulTargets.map((target) => `✔ ${target.targetLabel} (${target.targetId})`),
299
+ ...failedTargets.map((target) => `✖ ${target.targetLabel} (${target.targetId}) — ${target.reason}`)
300
+ ]);
301
+ }
302
+
303
+ function printUpdateCompletionSummary({ updatedCount, skippedCount, changelogPath, legacyCleanupLine }) {
304
+ blank();
305
+ section('Update completed', [
306
+ `✔ Done! ${updatedCount} file(s) updated${skippedCount > 0 ? `, ${skippedCount} skipped` : ''}.`,
307
+ 'Managed files have been updated to the latest version.',
308
+ 'Your custom files outside the selected target projections were not touched.',
309
+ ...(legacyCleanupLine ? [legacyCleanupLine] : []),
310
+ `Generated upgrade record: ${changelogPath}`,
311
+ 'Run `/upgrade` in your AI IDE to update your architecture docs.'
312
+ ], { minWidth: 60 });
313
+ }
314
+
315
+ module.exports = update;
316
+
317
+
318
+
319
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haaaiawd/anws",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
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",
@@ -12,15 +12,16 @@
12
12
  "prompt-engineering",
13
13
  "devops-for-ai",
14
14
  "skills-framework",
15
+ "craft-authoring",
15
16
  "claude-code",
16
17
  "github-copilot",
17
18
  "cursor",
18
19
  "windsurf"
19
20
  ],
20
- "homepage": "https://github.com/Haaaiawd/Anws",
21
+ "homepage": "https://github.com/Haaaiawd/ANWS",
21
22
  "repository": {
22
23
  "type": "git",
23
- "url": "git+https://github.com/Haaaiawd/Anws.git"
24
+ "url": "git+https://github.com/Haaaiawd/ANWS.git"
24
25
  },
25
26
  "author": "haaaiawd <1134180104@qq.com>",
26
27
  "license": "MIT",