@haaaiawd/anws 1.2.5 → 2.0.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 +230 -174
- package/bin/cli.js +22 -9
- package/lib/adapters/index.js +157 -0
- package/lib/agents.js +136 -1
- package/lib/changelog.js +187 -0
- package/lib/copy.js +72 -1
- package/lib/diff.js +270 -0
- package/lib/init.js +150 -125
- package/lib/install-state.js +195 -0
- package/lib/manifest.js +184 -42
- package/lib/output.js +185 -13
- package/lib/prompt.js +284 -0
- package/lib/resources/index.js +27 -0
- package/lib/update.js +291 -83
- package/package.json +10 -6
- package/templates/.agents/skills/concept-modeler/SKILL.md +176 -0
- package/templates/{.agent → .agents}/skills/design-reviewer/SKILL.md +6 -6
- package/templates/.agents/skills/nexus-mapper/SKILL.md +306 -0
- package/templates/.agents/skills/nexus-mapper/references/language-customization.md +164 -0
- package/templates/.agents/skills/nexus-mapper/references/output-schema.md +298 -0
- package/templates/.agents/skills/nexus-mapper/references/probe-protocol.md +246 -0
- package/templates/.agents/skills/nexus-mapper/scripts/extract_ast.py +706 -0
- package/templates/.agents/skills/nexus-mapper/scripts/git_detective.py +194 -0
- package/templates/.agents/skills/nexus-mapper/scripts/languages.json +127 -0
- package/templates/.agents/skills/nexus-mapper/scripts/query_graph.py +556 -0
- package/templates/.agents/skills/nexus-mapper/scripts/requirements.txt +6 -0
- package/templates/{.agent → .agents}/skills/report-template/SKILL.md +11 -14
- package/templates/.agents/skills/report-template/references/REPORT_TEMPLATE.md +100 -0
- package/templates/{.agent → .agents}/skills/runtime-inspector/SKILL.md +1 -1
- package/templates/.agents/skills/sequential-thinking/SKILL.md +179 -0
- package/templates/.agents/skills/spec-writer/SKILL.md +108 -0
- package/templates/{.agent → .agents}/skills/spec-writer/references/prd_template.md +1 -1
- package/templates/{.agent → .agents}/skills/system-architect/SKILL.md +3 -3
- package/templates/.agents/skills/system-architect/references/rfc_template.md +59 -0
- package/templates/{.agent → .agents}/skills/system-designer/SKILL.md +6 -6
- package/templates/{.agent → .agents}/skills/system-designer/references/system-design-template.md +75 -25
- package/templates/{.agent → .agents}/skills/task-planner/SKILL.md +1 -1
- package/templates/.agents/skills/task-planner/references/TASK_TEMPLATE.md +144 -0
- package/templates/{.agent → .agents}/skills/task-reviewer/SKILL.md +4 -3
- package/templates/{.agent → .agents}/skills/tech-evaluator/SKILL.md +2 -2
- package/templates/{.agent → .agents}/skills/tech-evaluator/references/ADR_TEMPLATE.md +10 -0
- package/templates/{.agent → .agents}/workflows/blueprint.md +32 -27
- package/templates/{.agent → .agents}/workflows/challenge.md +21 -15
- package/templates/{.agent → .agents}/workflows/change.md +23 -14
- package/templates/{.agent → .agents}/workflows/craft.md +8 -19
- package/templates/{.agent → .agents}/workflows/design-system.md +81 -54
- package/templates/{.agent → .agents}/workflows/explore.md +6 -19
- package/templates/{.agent → .agents}/workflows/forge.md +30 -32
- package/templates/{.agent → .agents}/workflows/genesis.md +68 -56
- package/templates/.agents/workflows/probe.md +168 -0
- package/templates/{.agent → .agents}/workflows/quickstart.md +7 -12
- package/templates/.agents/workflows/upgrade.md +192 -0
- package/templates/AGENTS.md +66 -45
- package/templates/.agent/skills/build-inspector/SKILL.md +0 -83
- package/templates/.agent/skills/complexity-guard/SKILL.md +0 -71
- package/templates/.agent/skills/complexity-guard/references/anti_patterns.md +0 -21
- package/templates/.agent/skills/concept-modeler/SKILL.md +0 -112
- package/templates/.agent/skills/concept-modeler/prompts/GLOSSARY_PROMPT.md +0 -40
- package/templates/.agent/skills/concept-modeler/references/ENTITY_EXTRACTION_PROMPT.md +0 -299
- package/templates/.agent/skills/concept-modeler/scripts/glossary_gen.py +0 -66
- package/templates/.agent/skills/git-forensics/SKILL.md +0 -74
- package/templates/.agent/skills/git-forensics/references/ANALYSIS_METHODOLOGY.md +0 -193
- package/templates/.agent/skills/git-forensics/scripts/__pycache__/git_forensics.cpython-313.pyc +0 -0
- package/templates/.agent/skills/git-forensics/scripts/git_forensics.py +0 -615
- package/templates/.agent/skills/git-forensics/scripts/git_hotspots.py +0 -118
- package/templates/.agent/skills/report-template/references/REPORT_TEMPLATE.md +0 -100
- package/templates/.agent/skills/spec-writer/SKILL.md +0 -108
- package/templates/.agent/skills/system-architect/references/rfc_template.md +0 -59
- package/templates/.agent/skills/task-planner/references/TASK_TEMPLATE.md +0 -144
- package/templates/.agent/workflows/scout.md +0 -139
- /package/templates/{.agent → .agents}/skills/system-designer/references/system-design-detail-template.md +0 -0
package/lib/prompt.js
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { blank, PALETTE, c, colorize, drawBox, visibleLength } = require('./output');
|
|
4
|
+
|
|
5
|
+
const KEY = {
|
|
6
|
+
CTRL_C: '\u0003',
|
|
7
|
+
ENTER: '\r',
|
|
8
|
+
NEWLINE: '\n',
|
|
9
|
+
SPACE: ' ',
|
|
10
|
+
ESCAPE: '\u001b',
|
|
11
|
+
ARROW_UP: '\u001b[A',
|
|
12
|
+
ARROW_DOWN: '\u001b[B',
|
|
13
|
+
ARROW_RIGHT: '\u001b[C',
|
|
14
|
+
ARROW_LEFT: '\u001b[D'
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
async function selectMultiple({ message, options, initialSelectedIndexes = [] }) {
|
|
18
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
19
|
+
return initialSelectedIndexes.map((index) => options[index]).filter(Boolean);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const selected = new Set(initialSelectedIndexes.filter((index) => index >= 0 && index < options.length));
|
|
23
|
+
const state = {
|
|
24
|
+
cursorIndex: 0,
|
|
25
|
+
errorMessage: ''
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
blank();
|
|
29
|
+
|
|
30
|
+
return runPrompt({
|
|
31
|
+
render() {
|
|
32
|
+
return renderMultiSelect({ message, options, selected, cursorIndex: state.cursorIndex, errorMessage: state.errorMessage });
|
|
33
|
+
},
|
|
34
|
+
onKey(key) {
|
|
35
|
+
if (key === KEY.CTRL_C) {
|
|
36
|
+
return 'abort';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (key === KEY.ARROW_UP) {
|
|
40
|
+
state.cursorIndex = (state.cursorIndex - 1 + options.length) % options.length;
|
|
41
|
+
state.errorMessage = '';
|
|
42
|
+
return 'render';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (key === KEY.ARROW_DOWN) {
|
|
46
|
+
state.cursorIndex = (state.cursorIndex + 1) % options.length;
|
|
47
|
+
state.errorMessage = '';
|
|
48
|
+
return 'render';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (key === KEY.SPACE) {
|
|
52
|
+
if (selected.has(state.cursorIndex)) {
|
|
53
|
+
selected.delete(state.cursorIndex);
|
|
54
|
+
} else {
|
|
55
|
+
selected.add(state.cursorIndex);
|
|
56
|
+
}
|
|
57
|
+
state.errorMessage = '';
|
|
58
|
+
return 'render';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (key === KEY.ENTER || key === KEY.NEWLINE) {
|
|
62
|
+
if (selected.size === 0) {
|
|
63
|
+
state.errorMessage = 'Select at least one target before continuing.';
|
|
64
|
+
return 'render';
|
|
65
|
+
}
|
|
66
|
+
return Array.from(selected).sort((left, right) => left - right).map((index) => options[index]);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function confirm({ message, messageLines = [], contextLines = [], confirmLabel = 'Continue', cancelLabel = 'Cancel', defaultValue = false }) {
|
|
75
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
76
|
+
return defaultValue;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const state = { value: defaultValue ? 'confirm' : 'cancel' };
|
|
80
|
+
blank();
|
|
81
|
+
|
|
82
|
+
return runPrompt({
|
|
83
|
+
render() {
|
|
84
|
+
return renderConfirm({ message, messageLines, contextLines, confirmLabel, cancelLabel, value: state.value });
|
|
85
|
+
},
|
|
86
|
+
onKey(key) {
|
|
87
|
+
if (key === KEY.CTRL_C) {
|
|
88
|
+
return 'abort';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (key === KEY.ARROW_LEFT || key === KEY.ARROW_UP) {
|
|
92
|
+
state.value = 'confirm';
|
|
93
|
+
return 'render';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (key === KEY.ARROW_RIGHT || key === KEY.ARROW_DOWN) {
|
|
97
|
+
state.value = 'cancel';
|
|
98
|
+
return 'render';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (key === 'y' || key === 'Y') {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (key === 'n' || key === 'N') {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (key === KEY.ENTER || key === KEY.NEWLINE) {
|
|
110
|
+
return state.value === 'confirm';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function renderMultiSelect({ message, options, selected, cursorIndex, errorMessage = '' }) {
|
|
119
|
+
const optionLines = options.map((option, index) => {
|
|
120
|
+
const isActive = index === cursorIndex;
|
|
121
|
+
const isSelected = selected.has(index);
|
|
122
|
+
const cursor = isActive ? colorize('❯', PALETTE.brand) : ' ';
|
|
123
|
+
const mark = isSelected ? colorize('◉', PALETTE.brand) : colorize('◌', PALETTE.muted);
|
|
124
|
+
const label = isActive ? colorize(option.label, PALETTE.ink) : option.label;
|
|
125
|
+
return `${cursor} ${mark} ${label}`;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
return centerFrame([
|
|
129
|
+
drawBox({
|
|
130
|
+
title: 'Select Targets',
|
|
131
|
+
lines: [
|
|
132
|
+
message,
|
|
133
|
+
'',
|
|
134
|
+
...optionLines,
|
|
135
|
+
'',
|
|
136
|
+
errorMessage ? colorize(errorMessage, c.yellow) : colorize('Choose any set of targets, then press Enter.', PALETTE.muted)
|
|
137
|
+
],
|
|
138
|
+
accent: PALETTE.brand,
|
|
139
|
+
borderTone: PALETTE.muted,
|
|
140
|
+
minWidth: 60
|
|
141
|
+
}),
|
|
142
|
+
colorize(' ↑/↓ Move Space Toggle Enter Confirm', PALETTE.muted)
|
|
143
|
+
].join('\n'));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function renderConfirm({ message, messageLines = [], contextLines = [], confirmLabel, cancelLabel, value }) {
|
|
147
|
+
const confirmOption = renderChoiceChip(confirmLabel, value === 'confirm');
|
|
148
|
+
const cancelOption = renderChoiceChip(cancelLabel, value === 'cancel');
|
|
149
|
+
const contentLines = messageLines.length > 0 ? messageLines : [message];
|
|
150
|
+
|
|
151
|
+
// 构建框内行:如果有 contextLines,则在上半部分显示,用分隔线隔开
|
|
152
|
+
const boxLines = contextLines.length > 0
|
|
153
|
+
? [...contextLines, '---', ...contentLines, '', `${confirmOption} ${cancelOption}`]
|
|
154
|
+
: [...contentLines, '', `${confirmOption} ${cancelOption}`];
|
|
155
|
+
|
|
156
|
+
return centerFrame([
|
|
157
|
+
drawBox({
|
|
158
|
+
title: 'Confirm',
|
|
159
|
+
lines: boxLines,
|
|
160
|
+
accent: PALETTE.brand,
|
|
161
|
+
borderTone: PALETTE.muted,
|
|
162
|
+
minWidth: 60
|
|
163
|
+
}),
|
|
164
|
+
colorize(' ←/→ Choose Enter Confirm', PALETTE.muted)
|
|
165
|
+
].join('\n'));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function runPrompt({ render, onKey }) {
|
|
169
|
+
const stdin = process.stdin;
|
|
170
|
+
const stdout = process.stdout;
|
|
171
|
+
let previousLineCount = 0;
|
|
172
|
+
|
|
173
|
+
return new Promise((resolve, reject) => {
|
|
174
|
+
const cleanup = () => {
|
|
175
|
+
stdin.setRawMode(false);
|
|
176
|
+
stdin.pause();
|
|
177
|
+
stdin.removeListener('data', handleData);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const finish = (value) => {
|
|
181
|
+
clearFrame(previousLineCount);
|
|
182
|
+
cleanup();
|
|
183
|
+
resolve(value);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const fail = (error) => {
|
|
187
|
+
clearFrame(previousLineCount);
|
|
188
|
+
cleanup();
|
|
189
|
+
reject(error);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const rerender = () => {
|
|
193
|
+
const frame = render();
|
|
194
|
+
const lineCount = frame.split('\n').length;
|
|
195
|
+
|
|
196
|
+
if (previousLineCount > 0) {
|
|
197
|
+
stdout.write(`\x1b[${previousLineCount}F`);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
stdout.write(`${frame}\n`);
|
|
201
|
+
|
|
202
|
+
if (previousLineCount > lineCount) {
|
|
203
|
+
for (let index = 0; index < previousLineCount - lineCount; index += 1) {
|
|
204
|
+
stdout.write('\x1b[2K\n');
|
|
205
|
+
}
|
|
206
|
+
stdout.write(`\x1b[${previousLineCount - lineCount}F`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
previousLineCount = lineCount;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const handleData = (buffer) => {
|
|
213
|
+
const key = buffer.toString('utf8');
|
|
214
|
+
const result = onKey(key);
|
|
215
|
+
|
|
216
|
+
if (result === 'abort') {
|
|
217
|
+
fail(new Error('Prompt aborted by user'));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (result === 'render') {
|
|
222
|
+
rerender();
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (result !== null && result !== undefined) {
|
|
227
|
+
finish(result);
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
stdin.setRawMode(true);
|
|
232
|
+
stdin.resume();
|
|
233
|
+
stdin.setEncoding('utf8');
|
|
234
|
+
stdin.on('data', handleData);
|
|
235
|
+
rerender();
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function clearFrame(lineCount) {
|
|
240
|
+
if (!process.stdout.isTTY || lineCount <= 0) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
process.stdout.write(`\x1b[${lineCount}F`);
|
|
245
|
+
for (let index = 0; index < lineCount; index += 1) {
|
|
246
|
+
process.stdout.write('\x1b[2K');
|
|
247
|
+
if (index < lineCount - 1) {
|
|
248
|
+
process.stdout.write('\n');
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
process.stdout.write('\r');
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function renderChoiceChip(label, isActive) {
|
|
255
|
+
const prefix = isActive ? '■' : '□';
|
|
256
|
+
const text = `${prefix} ${label}`;
|
|
257
|
+
const width = Math.max(12, visibleLength(label) + 4);
|
|
258
|
+
const padded = `${text}${' '.repeat(Math.max(0, width - visibleLength(text)))}`;
|
|
259
|
+
return isActive ? colorize(padded, PALETTE.brand) : colorize(padded, PALETTE.muted);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function centerFrame(frame) {
|
|
263
|
+
const terminalWidth = Number.isInteger(process.stdout.columns) ? process.stdout.columns : 0;
|
|
264
|
+
if (!terminalWidth) {
|
|
265
|
+
return frame;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
return frame
|
|
269
|
+
.split('\n')
|
|
270
|
+
.map((line) => {
|
|
271
|
+
const padding = Math.max(0, Math.floor((terminalWidth - visibleLength(line)) / 2));
|
|
272
|
+
return `${' '.repeat(padding)}${line}`;
|
|
273
|
+
})
|
|
274
|
+
.join('\n');
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
module.exports = {
|
|
278
|
+
selectMultiple,
|
|
279
|
+
confirm,
|
|
280
|
+
renderMultiSelect,
|
|
281
|
+
renderConfirm
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { findByType } = require('../manifest');
|
|
5
|
+
|
|
6
|
+
const TEMPLATE_ROOT = path.join(__dirname, '..', '..', 'templates');
|
|
7
|
+
const AGENTS_ROOT = path.join(TEMPLATE_ROOT, '.agents');
|
|
8
|
+
const ROOT_AGENTS_FILE = path.join(TEMPLATE_ROOT, 'AGENTS.md');
|
|
9
|
+
|
|
10
|
+
function listCanonicalResources() {
|
|
11
|
+
return [
|
|
12
|
+
...findByType('workflow').map((item) => ({ ...item })),
|
|
13
|
+
...findByType('skill').map((item) => ({ ...item }))
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function resolveCanonicalSource(relPath) {
|
|
18
|
+
return path.join(TEMPLATE_ROOT, relPath);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
TEMPLATE_ROOT,
|
|
23
|
+
AGENTS_ROOT,
|
|
24
|
+
ROOT_AGENTS_FILE,
|
|
25
|
+
listCanonicalResources,
|
|
26
|
+
resolveCanonicalSource
|
|
27
|
+
};
|