roadmapsmith 0.9.15 → 0.9.22
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/.claude-plugin/plugin.json +34 -0
- package/.codex-plugin/plugin.json +55 -0
- package/README.md +76 -20
- package/assets/palette.png +0 -0
- package/assets/roadmapsmith-logo.png +0 -0
- package/bin/cli.js +75 -17
- package/package.json +20 -4
- package/skills/roadmap/SKILL.md +33 -0
- package/skills/roadmap-audit/SKILL.md +16 -0
- package/skills/roadmap-generate/SKILL.md +18 -0
- package/skills/roadmap-init/SKILL.md +16 -0
- package/skills/roadmap-maintain/SKILL.md +18 -0
- package/skills/roadmap-setup/SKILL.md +17 -0
- package/skills/roadmap-status/SKILL.md +17 -0
- package/skills/roadmap-sync/SKILL.md +20 -0
- package/skills/roadmap-sync/agents/openai.yaml +7 -0
- package/skills/roadmap-update/SKILL.md +17 -0
- package/skills/roadmap-validate/SKILL.md +16 -0
- package/skills/roadmap-zero/SKILL.md +17 -0
- package/skills.json +95 -0
- package/src/classifier/index.js +35 -0
- package/src/generator/index.js +219 -19
- package/src/host.js +446 -58
- package/src/io.js +45 -4
- package/src/match.js +18 -2
- package/src/parser/index.js +13 -0
- package/src/slash.js +148 -69
- package/src/utils.js +1 -0
package/src/io.js
CHANGED
|
@@ -126,14 +126,55 @@ function detectLanguages(files) {
|
|
|
126
126
|
'.sh': 'Shell'
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
-
const
|
|
129
|
+
const languageScores = new Map();
|
|
130
|
+
|
|
131
|
+
function scoreLanguageFile(file) {
|
|
132
|
+
if (/^(scripts|tools|fixtures|examples)\//.test(file)) {
|
|
133
|
+
return 0.4;
|
|
134
|
+
}
|
|
135
|
+
if (/(^|\/)(__tests__|tests)\//.test(file) || /\.test\.|\.spec\.|_test\./.test(file)) {
|
|
136
|
+
return 0.8;
|
|
137
|
+
}
|
|
138
|
+
if (/^(src|app|electron|pages|components|lib|cmd|internal)\//.test(file)) {
|
|
139
|
+
return 4;
|
|
140
|
+
}
|
|
141
|
+
if (/^(packages|apps)\/[^/]+\/(src|app|electron|lib)\//.test(file)) {
|
|
142
|
+
return 4;
|
|
143
|
+
}
|
|
144
|
+
if (/^(packages|apps)\/[^/]+\//.test(file)) {
|
|
145
|
+
return 2.5;
|
|
146
|
+
}
|
|
147
|
+
return 1.5;
|
|
148
|
+
}
|
|
149
|
+
|
|
130
150
|
for (const file of files) {
|
|
131
151
|
const ext = path.extname(file).toLowerCase();
|
|
132
|
-
|
|
133
|
-
|
|
152
|
+
const language = languageByExtension[ext];
|
|
153
|
+
if (!language) {
|
|
154
|
+
continue;
|
|
134
155
|
}
|
|
156
|
+
|
|
157
|
+
const nextScore = (languageScores.get(language) || 0) + scoreLanguageFile(file);
|
|
158
|
+
languageScores.set(language, nextScore);
|
|
135
159
|
}
|
|
136
|
-
|
|
160
|
+
|
|
161
|
+
const ranked = Array.from(languageScores.entries()).sort((left, right) => {
|
|
162
|
+
if (right[1] !== left[1]) {
|
|
163
|
+
return right[1] - left[1];
|
|
164
|
+
}
|
|
165
|
+
return left[0].localeCompare(right[0]);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
if (ranked.length === 0) {
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const maxScore = ranked[0][1];
|
|
173
|
+
const inclusionThreshold = Math.max(1, maxScore * 0.35);
|
|
174
|
+
|
|
175
|
+
return ranked
|
|
176
|
+
.filter(([, score]) => score >= inclusionThreshold)
|
|
177
|
+
.map(([language]) => language);
|
|
137
178
|
}
|
|
138
179
|
|
|
139
180
|
function detectTestFrameworks(projectRoot, files) {
|
package/src/match.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { similarityScore, slugify, tokenize, uniqueBy } = require('./utils');
|
|
3
|
+
const { normalizeText, similarityScore, slugify, tokenize, uniqueBy } = require('./utils');
|
|
4
4
|
const { PHASE_ORDER } = require('./model');
|
|
5
5
|
|
|
6
6
|
function canonicalSignature(text) {
|
|
@@ -17,12 +17,28 @@ function inferPriorityWeight(priority) {
|
|
|
17
17
|
return 4;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
function
|
|
20
|
+
function normalizeTaskText(text) {
|
|
21
|
+
return normalizeText(String(text || '').replace(/`?\[P[0-3]\]`?\s*/gi, ' '));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function findBestTaskMatch(candidate, existingTasks, options = {}) {
|
|
25
|
+
const minScore = typeof options.minScore === 'number' ? options.minScore : 0.55;
|
|
26
|
+
const allowFuzzy = options.allowFuzzy !== false;
|
|
21
27
|
const direct = existingTasks.find((task) => task.id === candidate.id);
|
|
22
28
|
if (direct) {
|
|
23
29
|
return { task: direct, score: 1 };
|
|
24
30
|
}
|
|
25
31
|
|
|
32
|
+
const normalizedCandidateText = normalizeTaskText(candidate.text);
|
|
33
|
+
const exactText = existingTasks.find((task) => normalizeTaskText(task.text) === normalizedCandidateText);
|
|
34
|
+
if (exactText) {
|
|
35
|
+
return { task: exactText, score: 0.95 };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!allowFuzzy) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
26
42
|
let best = null;
|
|
27
43
|
for (const task of existingTasks) {
|
|
28
44
|
const score = similarityScore(candidate.text, task.text);
|
package/src/parser/index.js
CHANGED
|
@@ -27,6 +27,9 @@ function parseHeadingLine(line) {
|
|
|
27
27
|
if (content.startsWith('### ')) {
|
|
28
28
|
return content.slice(4).trim();
|
|
29
29
|
}
|
|
30
|
+
if (content.startsWith('#### ')) {
|
|
31
|
+
return content.slice(5).trim();
|
|
32
|
+
}
|
|
30
33
|
return null;
|
|
31
34
|
}
|
|
32
35
|
|
|
@@ -206,6 +209,15 @@ function findManagedRange(lines) {
|
|
|
206
209
|
return null;
|
|
207
210
|
}
|
|
208
211
|
|
|
212
|
+
function tasksInManagedBlock(parsedRoadmap) {
|
|
213
|
+
if (!parsedRoadmap || !parsedRoadmap.managedRange) {
|
|
214
|
+
return parsedRoadmap && Array.isArray(parsedRoadmap.tasks) ? parsedRoadmap.tasks : [];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const { start, end } = parsedRoadmap.managedRange;
|
|
218
|
+
return parsedRoadmap.tasks.filter((task) => task.lineIndex > start && task.lineIndex < end);
|
|
219
|
+
}
|
|
220
|
+
|
|
209
221
|
function upsertManagedBlock(existingContent, managedBody) {
|
|
210
222
|
const existing = String(existingContent || '');
|
|
211
223
|
const lines = existing.split(/\r?\n/);
|
|
@@ -227,5 +239,6 @@ function upsertManagedBlock(existingContent, managedBody) {
|
|
|
227
239
|
module.exports = {
|
|
228
240
|
findManagedRange,
|
|
229
241
|
parseRoadmap,
|
|
242
|
+
tasksInManagedBlock,
|
|
230
243
|
upsertManagedBlock
|
|
231
244
|
};
|
package/src/slash.js
CHANGED
|
@@ -5,83 +5,102 @@ const SLASH_ACTIONS = [
|
|
|
5
5
|
id: 'zero',
|
|
6
6
|
description: 'Interview the developer in terminal and generate the first roadmap for an empty or low-context repo.',
|
|
7
7
|
classicCliExample: 'roadmapsmith zero',
|
|
8
|
-
slashExamples: ['/zero', '/road zero', '/roadmap-sync zero'],
|
|
9
8
|
taskLabel: 'RoadmapSmith: Zero Mode'
|
|
10
9
|
},
|
|
11
10
|
{
|
|
12
11
|
id: 'maintain',
|
|
13
|
-
description: '
|
|
12
|
+
description: 'Preserve-first existing-repo flow: update, sync, and audit the roadmap without rebuilding substantive domain content.',
|
|
14
13
|
classicCliExample: 'roadmapsmith maintain',
|
|
15
|
-
slashExamples: ['/maintain', '/road maintain', '/roadmap-sync maintain'],
|
|
16
14
|
taskLabel: 'RoadmapSmith: Maintain'
|
|
17
15
|
},
|
|
18
16
|
{
|
|
19
17
|
id: 'status',
|
|
20
|
-
description: 'Inspect CLI, roadmap, VS Code task, and Claude
|
|
18
|
+
description: 'Inspect CLI, roadmap, VS Code task, Codex, and Claude readiness.',
|
|
21
19
|
classicCliExample: 'roadmapsmith doctor --json',
|
|
22
|
-
slashExamples: ['/status', '/road status', '/roadmap-sync status'],
|
|
23
20
|
taskLabel: 'RoadmapSmith: Status'
|
|
24
21
|
},
|
|
25
22
|
{
|
|
26
23
|
id: 'init',
|
|
27
24
|
description: 'Create ROADMAP.md and AGENTS.md when they are missing.',
|
|
28
25
|
classicCliExample: 'roadmapsmith init',
|
|
29
|
-
slashExamples: ['/init', '/road init', '/roadmap-sync init'],
|
|
30
26
|
taskLabel: 'RoadmapSmith: Init'
|
|
31
27
|
},
|
|
32
28
|
{
|
|
33
29
|
id: 'generate',
|
|
34
|
-
description: '
|
|
30
|
+
description: 'Generate or update ROADMAP.md, refusing destructive replacement unless rerun with --full-regen.',
|
|
35
31
|
classicCliExample: 'roadmapsmith generate --project-root .',
|
|
36
|
-
slashExamples: ['/generate', '/road generate', '/roadmap-sync generate'],
|
|
37
32
|
taskLabel: 'RoadmapSmith: Generate'
|
|
38
33
|
},
|
|
39
34
|
{
|
|
40
35
|
id: 'validate',
|
|
41
36
|
description: 'Inspect per-task evidence status as JSON.',
|
|
42
37
|
classicCliExample: 'roadmapsmith validate --json --project-root .',
|
|
43
|
-
slashExamples: ['/validate', '/road validate', '/roadmap-sync validate'],
|
|
44
38
|
taskLabel: 'RoadmapSmith: Validate'
|
|
45
39
|
},
|
|
46
40
|
{
|
|
47
41
|
id: 'sync',
|
|
48
42
|
description: 'Apply evidence-backed checklist sync to ROADMAP.md.',
|
|
49
43
|
classicCliExample: 'roadmapsmith sync --project-root .',
|
|
50
|
-
slashExamples: ['/sync', '/road sync', '/roadmap-sync sync'],
|
|
51
44
|
taskLabel: 'RoadmapSmith: Sync'
|
|
52
45
|
},
|
|
53
46
|
{
|
|
54
47
|
id: 'audit',
|
|
55
48
|
description: 'Run sync and print the post-sync mismatch summary.',
|
|
56
49
|
classicCliExample: 'roadmapsmith sync --audit --project-root .',
|
|
57
|
-
slashExamples: ['/audit', '/road audit', '/roadmap-sync audit'],
|
|
58
50
|
taskLabel: 'RoadmapSmith: Sync Audit'
|
|
59
51
|
},
|
|
60
52
|
{
|
|
61
53
|
id: 'setup',
|
|
62
54
|
description: 'Generate visible VS Code tasks and optional Claude hook wiring.',
|
|
63
55
|
classicCliExample: 'roadmapsmith setup',
|
|
64
|
-
slashExamples: ['/setup', '/road setup', '/roadmap-sync setup'],
|
|
65
56
|
taskLabel: 'RoadmapSmith: Refresh Setup'
|
|
66
57
|
}
|
|
67
58
|
];
|
|
68
59
|
|
|
69
|
-
const SLASH_ROOT_ALIASES = new Set(['/
|
|
60
|
+
const SLASH_ROOT_ALIASES = new Set(['/roadmap', '/road']);
|
|
61
|
+
const LEGACY_ROUTER_ALIAS = '/roadmap-sync';
|
|
70
62
|
|
|
71
|
-
|
|
72
|
-
'/
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
63
|
+
function getNamespacedDirectSlash(actionId) {
|
|
64
|
+
return actionId === 'sync' ? '/roadmap-update' : `/roadmap-${actionId}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const DIRECT_HOST_NATIVE_ALIAS_TO_ACTION = Object.freeze(
|
|
68
|
+
Object.fromEntries(SLASH_ACTIONS.map((action) => [getNamespacedDirectSlash(action.id), action.id]))
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const DIRECT_DEPRECATED_CLI_ALIAS_TO_ACTION = Object.freeze(
|
|
72
|
+
Object.fromEntries(SLASH_ACTIONS.map((action) => [`/${action.id}`, action.id]))
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
function getHostNativeSkillNames() {
|
|
76
|
+
return [
|
|
77
|
+
'roadmap',
|
|
78
|
+
'roadmap-zero',
|
|
79
|
+
'roadmap-maintain',
|
|
80
|
+
'roadmap-status',
|
|
81
|
+
'roadmap-init',
|
|
82
|
+
'roadmap-generate',
|
|
83
|
+
'roadmap-validate',
|
|
84
|
+
'roadmap-update',
|
|
85
|
+
'roadmap-sync',
|
|
86
|
+
'roadmap-audit',
|
|
87
|
+
'roadmap-setup'
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function getHostNativeSlashCommands() {
|
|
92
|
+
return getHostNativeSkillNames().map((name) => `/${name}`);
|
|
93
|
+
}
|
|
82
94
|
|
|
83
95
|
function normalizeActionId(value) {
|
|
84
|
-
|
|
96
|
+
let normalized = String(value || '').trim().toLowerCase().replace(/^\/+/, '');
|
|
97
|
+
if (normalized.startsWith('roadmap-')) {
|
|
98
|
+
normalized = normalized.slice('roadmap-'.length);
|
|
99
|
+
}
|
|
100
|
+
if (normalized === 'update') {
|
|
101
|
+
normalized = 'sync';
|
|
102
|
+
}
|
|
103
|
+
return normalized;
|
|
85
104
|
}
|
|
86
105
|
|
|
87
106
|
function isSlashToken(value) {
|
|
@@ -93,8 +112,17 @@ function getSlashAction(actionId) {
|
|
|
93
112
|
return SLASH_ACTIONS.find((action) => action.id === normalized) || null;
|
|
94
113
|
}
|
|
95
114
|
|
|
115
|
+
function getLegacyRouterSlash(action) {
|
|
116
|
+
return `/roadmap-sync ${action.id === 'sync' ? 'update' : action.id}`;
|
|
117
|
+
}
|
|
118
|
+
|
|
96
119
|
function getSlashActionSpecs() {
|
|
97
|
-
return SLASH_ACTIONS.map((action) => ({
|
|
120
|
+
return SLASH_ACTIONS.map((action) => ({
|
|
121
|
+
...action,
|
|
122
|
+
directSlash: getNamespacedDirectSlash(action.id),
|
|
123
|
+
routerSlash: `/roadmap ${action.id}`,
|
|
124
|
+
legacyRouterSlash: getLegacyRouterSlash(action)
|
|
125
|
+
}));
|
|
98
126
|
}
|
|
99
127
|
|
|
100
128
|
function getSlashSuggestions(query) {
|
|
@@ -108,7 +136,35 @@ function getSlashSuggestions(query) {
|
|
|
108
136
|
return !action.id.startsWith(normalized) && action.id.includes(normalized);
|
|
109
137
|
});
|
|
110
138
|
|
|
111
|
-
return [...startsWithMatches, ...containsMatches].map((action) => ({
|
|
139
|
+
return [...startsWithMatches, ...containsMatches].map((action) => ({
|
|
140
|
+
...action,
|
|
141
|
+
directSlash: getNamespacedDirectSlash(action.id),
|
|
142
|
+
routerSlash: `/roadmap ${action.id}`,
|
|
143
|
+
legacyRouterSlash: getLegacyRouterSlash(action)
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function paletteResponse(source, query, deprecated = false, deprecationMessage = '') {
|
|
148
|
+
return {
|
|
149
|
+
kind: 'palette',
|
|
150
|
+
query,
|
|
151
|
+
source,
|
|
152
|
+
suggestions: getSlashSuggestions(query),
|
|
153
|
+
deprecated,
|
|
154
|
+
deprecationMessage
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function executeResponse(source, actionId, query, deprecated = false, deprecationMessage = '') {
|
|
159
|
+
return {
|
|
160
|
+
kind: 'execute',
|
|
161
|
+
actionId,
|
|
162
|
+
query,
|
|
163
|
+
source,
|
|
164
|
+
suggestions: getSlashSuggestions(query),
|
|
165
|
+
deprecated,
|
|
166
|
+
deprecationMessage
|
|
167
|
+
};
|
|
112
168
|
}
|
|
113
169
|
|
|
114
170
|
function resolveSlashInvocation(command, args = []) {
|
|
@@ -118,56 +174,68 @@ function resolveSlashInvocation(command, args = []) {
|
|
|
118
174
|
|
|
119
175
|
const normalizedCommand = String(command).trim().toLowerCase();
|
|
120
176
|
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
177
|
+
if (normalizedCommand === LEGACY_ROUTER_ALIAS) {
|
|
178
|
+
if (args.length === 0) {
|
|
179
|
+
return paletteResponse(normalizedCommand, '');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const queryToken = normalizeActionId(args[0]);
|
|
183
|
+
const deprecationMessage = 'Legacy CLI compatibility root /roadmap-sync <action> is deprecated. Use /roadmap <action> or the direct /roadmap-* commands.';
|
|
184
|
+
const exactAction = getSlashAction(queryToken);
|
|
185
|
+
if (exactAction) {
|
|
186
|
+
return executeResponse(normalizedCommand, exactAction.id, queryToken, true, deprecationMessage);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return paletteResponse(normalizedCommand, queryToken, true, deprecationMessage);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (Object.prototype.hasOwnProperty.call(DIRECT_HOST_NATIVE_ALIAS_TO_ACTION, normalizedCommand)) {
|
|
193
|
+
return executeResponse(
|
|
194
|
+
normalizedCommand,
|
|
195
|
+
DIRECT_HOST_NATIVE_ALIAS_TO_ACTION[normalizedCommand],
|
|
196
|
+
normalizeActionId(normalizedCommand)
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (Object.prototype.hasOwnProperty.call(DIRECT_DEPRECATED_CLI_ALIAS_TO_ACTION, normalizedCommand)) {
|
|
201
|
+
const actionId = DIRECT_DEPRECATED_CLI_ALIAS_TO_ACTION[normalizedCommand];
|
|
202
|
+
return executeResponse(
|
|
203
|
+
normalizedCommand,
|
|
204
|
+
actionId,
|
|
205
|
+
normalizeActionId(normalizedCommand),
|
|
206
|
+
true,
|
|
207
|
+
`CLI compatibility alias ${normalizedCommand} is deprecated. Use ${getNamespacedDirectSlash(actionId)} or /roadmap ${actionId}.`
|
|
208
|
+
);
|
|
129
209
|
}
|
|
130
210
|
|
|
131
211
|
if (SLASH_ROOT_ALIASES.has(normalizedCommand)) {
|
|
132
212
|
const queryToken = args.length > 0 ? normalizeActionId(args[0]) : '';
|
|
213
|
+
const deprecated = normalizedCommand === '/road';
|
|
214
|
+
const deprecationMessage = deprecated
|
|
215
|
+
? 'CLI compatibility alias /road is deprecated. Use /roadmap.'
|
|
216
|
+
: '';
|
|
217
|
+
|
|
133
218
|
if (!queryToken) {
|
|
134
|
-
return
|
|
135
|
-
kind: 'palette',
|
|
136
|
-
query: '',
|
|
137
|
-
source: normalizedCommand,
|
|
138
|
-
suggestions: getSlashSuggestions('')
|
|
139
|
-
};
|
|
219
|
+
return paletteResponse(normalizedCommand, '', deprecated, deprecationMessage);
|
|
140
220
|
}
|
|
141
221
|
|
|
142
222
|
const exactAction = getSlashAction(queryToken);
|
|
143
223
|
if (exactAction) {
|
|
144
|
-
return
|
|
145
|
-
kind: 'execute',
|
|
146
|
-
actionId: exactAction.id,
|
|
147
|
-
query: queryToken,
|
|
148
|
-
source: normalizedCommand,
|
|
149
|
-
suggestions: getSlashSuggestions(queryToken)
|
|
150
|
-
};
|
|
224
|
+
return executeResponse(normalizedCommand, exactAction.id, queryToken, deprecated, deprecationMessage);
|
|
151
225
|
}
|
|
152
226
|
|
|
153
|
-
return
|
|
154
|
-
kind: 'palette',
|
|
155
|
-
query: queryToken,
|
|
156
|
-
source: normalizedCommand,
|
|
157
|
-
suggestions: getSlashSuggestions(queryToken)
|
|
158
|
-
};
|
|
227
|
+
return paletteResponse(normalizedCommand, queryToken, deprecated, deprecationMessage);
|
|
159
228
|
}
|
|
160
229
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
};
|
|
230
|
+
if (normalizedCommand.startsWith('/roadmap-')) {
|
|
231
|
+
return paletteResponse(normalizedCommand, normalizeActionId(normalizedCommand));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return paletteResponse(normalizedCommand, normalizeActionId(normalizedCommand));
|
|
167
235
|
}
|
|
168
236
|
|
|
169
237
|
function renderSlashPalette(options = {}) {
|
|
170
|
-
const source = options.source || '/
|
|
238
|
+
const source = options.source || '/roadmap';
|
|
171
239
|
const query = normalizeActionId(options.query);
|
|
172
240
|
const suggestions = Array.isArray(options.suggestions) ? options.suggestions : getSlashSuggestions(query);
|
|
173
241
|
const lines = [];
|
|
@@ -175,6 +243,11 @@ function renderSlashPalette(options = {}) {
|
|
|
175
243
|
lines.push('RoadmapSmith slash palette');
|
|
176
244
|
lines.push('');
|
|
177
245
|
|
|
246
|
+
if (options.deprecated && options.deprecationMessage) {
|
|
247
|
+
lines.push(`Deprecated alias: ${options.deprecationMessage}`);
|
|
248
|
+
lines.push('');
|
|
249
|
+
}
|
|
250
|
+
|
|
178
251
|
if (query) {
|
|
179
252
|
lines.push(`Input: ${source} ${query}`);
|
|
180
253
|
if (suggestions.length > 0) {
|
|
@@ -193,20 +266,21 @@ function renderSlashPalette(options = {}) {
|
|
|
193
266
|
lines.push('No related slash actions found.');
|
|
194
267
|
} else {
|
|
195
268
|
suggestions.forEach((action) => {
|
|
196
|
-
lines.push(`-
|
|
269
|
+
lines.push(`- ${action.directSlash}: ${action.description}`);
|
|
270
|
+
lines.push(` Router form: ${action.routerSlash}`);
|
|
271
|
+
lines.push(` Legacy router: ${action.legacyRouterSlash}`);
|
|
197
272
|
lines.push(` Classic CLI: ${action.classicCliExample}`);
|
|
198
|
-
lines.push(` Skill form: /roadmap-sync ${action.id}`);
|
|
199
273
|
lines.push(` VS Code task: ${action.taskLabel}`);
|
|
200
274
|
});
|
|
201
275
|
}
|
|
202
276
|
|
|
203
277
|
lines.push('');
|
|
204
278
|
lines.push('Examples:');
|
|
205
|
-
lines.push('- roadmapsmith
|
|
206
|
-
lines.push('- roadmapsmith maintain');
|
|
207
|
-
lines.push('- roadmapsmith /
|
|
208
|
-
lines.push('- roadmapsmith /
|
|
209
|
-
lines.push('- roadmapsmith /roadmap-sync
|
|
279
|
+
lines.push('- roadmapsmith /roadmap');
|
|
280
|
+
lines.push('- roadmapsmith /roadmap maintain');
|
|
281
|
+
lines.push('- roadmapsmith /roadmap-maintain');
|
|
282
|
+
lines.push('- roadmapsmith /roadmap-update');
|
|
283
|
+
lines.push('- roadmapsmith /roadmap-sync validate');
|
|
210
284
|
lines.push('');
|
|
211
285
|
lines.push('Installing the skill alone does not expose CLI behavior in VS Code. Use roadmapsmith setup for the visible task/launcher layer.');
|
|
212
286
|
|
|
@@ -214,8 +288,13 @@ function renderSlashPalette(options = {}) {
|
|
|
214
288
|
}
|
|
215
289
|
|
|
216
290
|
module.exports = {
|
|
217
|
-
|
|
291
|
+
DIRECT_DEPRECATED_CLI_ALIAS_TO_ACTION,
|
|
292
|
+
DIRECT_HOST_NATIVE_ALIAS_TO_ACTION,
|
|
293
|
+
LEGACY_ROUTER_ALIAS,
|
|
218
294
|
SLASH_ROOT_ALIASES,
|
|
295
|
+
getHostNativeSkillNames,
|
|
296
|
+
getHostNativeSlashCommands,
|
|
297
|
+
getNamespacedDirectSlash,
|
|
219
298
|
getSlashAction,
|
|
220
299
|
getSlashActionSpecs,
|
|
221
300
|
getSlashSuggestions,
|