@ryuenn3123/agentic-senior-core 2.0.5 → 2.0.8
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/.agent-context/blueprints/mobile-app.md +91 -21
- package/.agent-context/profiles/platform.md +13 -13
- package/.agent-context/profiles/regulated.md +13 -13
- package/.agent-context/profiles/startup.md +13 -13
- package/.agent-context/prompts/review-code.md +3 -3
- package/.agent-context/review-checklists/frontend-skill-parity.md +28 -28
- package/.agent-context/review-checklists/frontend-usability.md +33 -33
- package/.agent-context/review-checklists/pr-checklist.md +11 -6
- package/.agent-context/review-checklists/release-operations.md +29 -29
- package/.agent-context/rules/api-docs.md +34 -0
- package/.agent-context/skills/README.md +62 -62
- package/.agent-context/skills/backend/README.md +67 -67
- package/.agent-context/skills/backend/architecture.md +360 -360
- package/.agent-context/skills/backend/compatibility-manifest.json +8 -8
- package/.agent-context/skills/backend/data-access.md +230 -230
- package/.agent-context/skills/backend/errors.md +137 -137
- package/.agent-context/skills/backend/validation.md +116 -116
- package/.agent-context/skills/backend.md +28 -28
- package/.agent-context/skills/cli/README.md +55 -49
- package/.agent-context/skills/cli/compatibility-manifest.json +8 -8
- package/.agent-context/skills/cli/init.md +37 -37
- package/.agent-context/skills/cli/output.md +35 -35
- package/.agent-context/skills/cli/safety-telemetry.md +39 -0
- package/.agent-context/skills/cli/upgrade.md +37 -37
- package/.agent-context/skills/cli.md +31 -28
- package/.agent-context/skills/distribution/.evidence/compatibility-manifest.json +9 -0
- package/.agent-context/skills/distribution/.evidence/sbom-excerpt.json +6 -0
- package/.agent-context/skills/distribution/.evidence/test-report.json +8 -0
- package/.agent-context/skills/distribution/CHANGELOG.md +7 -0
- package/.agent-context/skills/distribution/README.md +27 -19
- package/.agent-context/skills/distribution/compatibility-manifest.json +8 -8
- package/.agent-context/skills/distribution/compatibility.md +31 -31
- package/.agent-context/skills/distribution/package.json +5 -0
- package/.agent-context/skills/distribution/provenance-attestation.md +47 -0
- package/.agent-context/skills/distribution/publish.md +36 -36
- package/.agent-context/skills/distribution/rollback.md +31 -31
- package/.agent-context/skills/distribution/tests/.gitkeep +1 -0
- package/.agent-context/skills/distribution.md +31 -28
- package/.agent-context/skills/frontend/.evidence/compatibility-manifest.json +9 -0
- package/.agent-context/skills/frontend/.evidence/sbom-excerpt.json +6 -0
- package/.agent-context/skills/frontend/.evidence/test-report.json +8 -0
- package/.agent-context/skills/frontend/CHANGELOG.md +7 -0
- package/.agent-context/skills/frontend/README.md +49 -36
- package/.agent-context/skills/frontend/accessibility.md +107 -107
- package/.agent-context/skills/frontend/compatibility-manifest.json +8 -8
- package/.agent-context/skills/frontend/conversion-clarity.md +51 -0
- package/.agent-context/skills/frontend/motion.md +66 -66
- package/.agent-context/skills/frontend/package.json +5 -0
- package/.agent-context/skills/frontend/performance.md +62 -62
- package/.agent-context/skills/frontend/responsive-delivery.md +41 -0
- package/.agent-context/skills/frontend/tests/.gitkeep +1 -0
- package/.agent-context/skills/frontend/ui-architecture.md +128 -128
- package/.agent-context/skills/frontend.md +35 -29
- package/.agent-context/skills/fullstack/.evidence/compatibility-manifest.json +9 -0
- package/.agent-context/skills/fullstack/.evidence/sbom-excerpt.json +6 -0
- package/.agent-context/skills/fullstack/.evidence/test-report.json +8 -0
- package/.agent-context/skills/fullstack/CHANGELOG.md +7 -0
- package/.agent-context/skills/fullstack/README.md +27 -19
- package/.agent-context/skills/fullstack/compatibility-manifest.json +8 -8
- package/.agent-context/skills/fullstack/contracts.md +52 -52
- package/.agent-context/skills/fullstack/end-to-end.md +41 -41
- package/.agent-context/skills/fullstack/feature-slicing.md +64 -64
- package/.agent-context/skills/fullstack/package.json +5 -0
- package/.agent-context/skills/fullstack/release-coordination.md +51 -0
- package/.agent-context/skills/fullstack/tests/.gitkeep +1 -0
- package/.agent-context/skills/fullstack.md +29 -26
- package/.agent-context/skills/index.json +107 -107
- package/.agent-context/skills/review-quality/.evidence/compatibility-manifest.json +9 -0
- package/.agent-context/skills/review-quality/.evidence/sbom-excerpt.json +6 -0
- package/.agent-context/skills/review-quality/.evidence/test-report.json +8 -0
- package/.agent-context/skills/review-quality/CHANGELOG.md +7 -0
- package/.agent-context/skills/review-quality/README.md +27 -19
- package/.agent-context/skills/review-quality/benchmark.md +29 -29
- package/.agent-context/skills/review-quality/compatibility-manifest.json +8 -8
- package/.agent-context/skills/review-quality/package.json +5 -0
- package/.agent-context/skills/review-quality/planning.md +37 -37
- package/.agent-context/skills/review-quality/release-decision.md +49 -0
- package/.agent-context/skills/review-quality/security.md +33 -33
- package/.agent-context/skills/review-quality/tests/.gitkeep +1 -0
- package/.agent-context/skills/review-quality.md +33 -27
- package/.agent-context/stacks/flutter.md +16 -16
- package/.agent-context/stacks/react-native.md +16 -16
- package/.agent-context/state/architecture-map.md +25 -25
- package/.agent-context/state/benchmark-analysis.json +431 -431
- package/.agent-context/state/benchmark-thresholds.json +10 -10
- package/.agent-context/state/benchmark-watchlist.json +19 -19
- package/.agent-context/state/dependency-map.md +32 -32
- package/.agent-context/state/quality-trend-report.json +16 -6
- package/.agent-context/state/skill-platform.json +38 -38
- package/.agent-context/state/weekly-governance-report.json +126 -0
- package/.agent-override.md +36 -36
- package/.cursorrules +1 -1
- package/.gemini/instructions.md +20 -20
- package/.github/ISSUE_TEMPLATE/v1.7-frontend-work-item.yml +54 -54
- package/.github/copilot-instructions.md +21 -21
- package/.github/workflows/benchmark-detection.yml +38 -38
- package/.github/workflows/benchmark-intelligence.yml +50 -50
- package/.github/workflows/frontend-usability-gate.yml +36 -36
- package/.github/workflows/governance-weekly-report.yml +43 -0
- package/.github/workflows/release-gate.yml +32 -32
- package/.github/workflows/sbom-compliance.yml +32 -32
- package/.windsurfrules +1 -1
- package/AGENTS.md +27 -27
- package/README.md +389 -368
- package/lib/cli/commands/init.mjs +13 -1
- package/lib/cli/commands/optimize.mjs +171 -171
- package/lib/cli/commands/upgrade.mjs +9 -1
- package/lib/cli/compatibility.mjs +124 -124
- package/lib/cli/constants.mjs +37 -2
- package/lib/cli/token-optimization.mjs +275 -275
- package/lib/cli/utils.mjs +24 -3
- package/mcp.json +92 -92
- package/package.json +2 -1
- package/scripts/benchmark-gate.mjs +121 -121
- package/scripts/benchmark-intelligence.mjs +140 -140
- package/scripts/detection-benchmark.mjs +138 -138
- package/scripts/frontend-usability-audit.mjs +87 -87
- package/scripts/generate-sbom.mjs +61 -61
- package/scripts/governance-weekly-report.mjs +293 -0
- package/scripts/init-project.ps1 +104 -104
- package/scripts/llm-judge.mjs +664 -664
- package/scripts/quality-trend-report.mjs +288 -288
- package/scripts/release-gate.mjs +261 -259
- package/scripts/skill-tier-policy.mjs +75 -75
- package/scripts/token-optimization-benchmark.mjs +252 -252
- package/scripts/validate.mjs +942 -865
|
@@ -1,275 +1,275 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { spawnSync } from 'node:child_process';
|
|
4
|
-
import { platform } from 'node:process';
|
|
5
|
-
|
|
6
|
-
import { pathExists } from './utils.mjs';
|
|
7
|
-
|
|
8
|
-
export const TOKEN_OPTIMIZATION_STATE_FILE_NAME = 'token-optimization.json';
|
|
9
|
-
export const TOKEN_OPTIMIZATION_REPORT_FILE_NAME = 'token-optimization-report.json';
|
|
10
|
-
|
|
11
|
-
const TOKEN_OPTIMIZATION_SCHEMA_VERSION = 'token-optimization-v1';
|
|
12
|
-
const FALLBACK_AGENT_NAME = 'copilot';
|
|
13
|
-
|
|
14
|
-
const SUPPORTED_AGENT_NAMES = new Set([
|
|
15
|
-
'copilot',
|
|
16
|
-
'claude',
|
|
17
|
-
'cursor',
|
|
18
|
-
'windsurf',
|
|
19
|
-
'gemini',
|
|
20
|
-
'codex',
|
|
21
|
-
'cline',
|
|
22
|
-
]);
|
|
23
|
-
|
|
24
|
-
const COMMAND_REWRITE_MAPPINGS = [
|
|
25
|
-
{
|
|
26
|
-
rawCommand: 'ls -la',
|
|
27
|
-
optimizedCommand: 'rtk ls .',
|
|
28
|
-
reason: 'Directory listings are grouped and compacted before entering the model context.',
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
rawCommand: 'tree',
|
|
32
|
-
optimizedCommand: 'rtk ls .',
|
|
33
|
-
reason: 'Large trees are summarized without losing high-signal structure.',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
rawCommand: 'cat file.ext',
|
|
37
|
-
optimizedCommand: 'rtk read file.ext',
|
|
38
|
-
reason: 'File reads keep signatures and relevant lines while trimming boilerplate.',
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
rawCommand: 'rg pattern .',
|
|
42
|
-
optimizedCommand: 'rtk grep "pattern" .',
|
|
43
|
-
reason: 'Search hits are grouped and deduplicated for faster reasoning.',
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
rawCommand: 'git status',
|
|
47
|
-
optimizedCommand: 'rtk git status',
|
|
48
|
-
reason: 'Status output is condensed to actionable file changes.',
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
rawCommand: 'git diff',
|
|
52
|
-
optimizedCommand: 'rtk git diff',
|
|
53
|
-
reason: 'Diff noise is trimmed while preserving code-review context.',
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
rawCommand: 'git log -n 10',
|
|
57
|
-
optimizedCommand: 'rtk git log -n 10',
|
|
58
|
-
reason: 'History is converted to compact one-line summaries.',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
rawCommand: 'npm test',
|
|
62
|
-
optimizedCommand: 'rtk test npm test',
|
|
63
|
-
reason: 'Test results emphasize failures and suppress repetitive pass logs.',
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
rawCommand: 'npm run build',
|
|
67
|
-
optimizedCommand: 'rtk err npm run build',
|
|
68
|
-
reason: 'Build runs return errors and warnings only for quicker remediation.',
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
rawCommand: 'tsc --noEmit',
|
|
72
|
-
optimizedCommand: 'rtk tsc',
|
|
73
|
-
reason: 'TypeScript diagnostics are grouped by file with less repetition.',
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
rawCommand: 'eslint .',
|
|
77
|
-
optimizedCommand: 'rtk lint',
|
|
78
|
-
reason: 'Lint output is grouped by rule and location to reduce token churn.',
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
rawCommand: 'docker ps',
|
|
82
|
-
optimizedCommand: 'rtk docker ps',
|
|
83
|
-
reason: 'Container state is summarized into compact rows.',
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
rawCommand: 'kubectl get pods',
|
|
87
|
-
optimizedCommand: 'rtk kubectl pods',
|
|
88
|
-
reason: 'Kubernetes output is condensed and stable for agent consumption.',
|
|
89
|
-
},
|
|
90
|
-
];
|
|
91
|
-
|
|
92
|
-
function parseRtkVersion(versionOutput) {
|
|
93
|
-
const versionMatch = versionOutput.match(/\d+\.\d+\.\d+/);
|
|
94
|
-
return versionMatch ? versionMatch[0] : null;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function normalizeAgentName(rawAgentName = FALLBACK_AGENT_NAME) {
|
|
98
|
-
const normalizedAgentName = String(rawAgentName || '')
|
|
99
|
-
.trim()
|
|
100
|
-
.toLowerCase();
|
|
101
|
-
|
|
102
|
-
if (!normalizedAgentName) {
|
|
103
|
-
return FALLBACK_AGENT_NAME;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (!SUPPORTED_AGENT_NAMES.has(normalizedAgentName)) {
|
|
107
|
-
throw new Error(
|
|
108
|
-
`Unsupported agent "${rawAgentName}". Supported values: ${Array.from(SUPPORTED_AGENT_NAMES).join(', ')}`
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return normalizedAgentName;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export function detectRtkBinary() {
|
|
116
|
-
try {
|
|
117
|
-
const versionResult = spawnSync('rtk', ['--version'], {
|
|
118
|
-
encoding: 'utf8',
|
|
119
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
if (versionResult.status !== 0) {
|
|
123
|
-
return {
|
|
124
|
-
isAvailable: false,
|
|
125
|
-
version: null,
|
|
126
|
-
detectionError: (versionResult.stderr || versionResult.stdout || 'Unknown external proxy detection error').trim(),
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
const detectedVersion = parseRtkVersion(versionResult.stdout || '');
|
|
131
|
-
return {
|
|
132
|
-
isAvailable: true,
|
|
133
|
-
version: detectedVersion,
|
|
134
|
-
detectionError: null,
|
|
135
|
-
};
|
|
136
|
-
} catch (detectionError) {
|
|
137
|
-
return {
|
|
138
|
-
isAvailable: false,
|
|
139
|
-
version: null,
|
|
140
|
-
detectionError: detectionError instanceof Error ? detectionError.message : String(detectionError),
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export function buildRtkInstallHint() {
|
|
146
|
-
if (platform === 'win32') {
|
|
147
|
-
return 'Install the external token optimizer binary for Windows, extract it, and ensure the executable is on PATH.';
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (platform === 'darwin') {
|
|
151
|
-
return 'Install the external token optimizer with Homebrew, then verify the executable is available in your shell.';
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return 'Install the external token optimizer with the vendor installer, then verify it is available in your shell PATH.';
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export function buildRtkHookCommand(selectedAgentName) {
|
|
158
|
-
const normalizedAgentName = normalizeAgentName(selectedAgentName);
|
|
159
|
-
|
|
160
|
-
if (normalizedAgentName === 'copilot') {
|
|
161
|
-
return 'rtk init -g --copilot';
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (normalizedAgentName === 'claude') {
|
|
165
|
-
return 'rtk init -g';
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (normalizedAgentName === 'cursor') {
|
|
169
|
-
return 'rtk init -g --agent cursor';
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (normalizedAgentName === 'windsurf') {
|
|
173
|
-
return 'rtk init --agent windsurf';
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (normalizedAgentName === 'gemini') {
|
|
177
|
-
return 'rtk init -g --gemini';
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (normalizedAgentName === 'codex') {
|
|
181
|
-
return 'rtk init -g --codex';
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (normalizedAgentName === 'cline') {
|
|
185
|
-
return 'rtk init --agent cline';
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return 'rtk init -g --copilot';
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
export function createTokenOptimizationState({
|
|
192
|
-
isEnabled,
|
|
193
|
-
selectedAgentName,
|
|
194
|
-
rtkDetection,
|
|
195
|
-
}) {
|
|
196
|
-
return {
|
|
197
|
-
schemaVersion: TOKEN_OPTIMIZATION_SCHEMA_VERSION,
|
|
198
|
-
enabled: Boolean(isEnabled),
|
|
199
|
-
selectedAgent: normalizeAgentName(selectedAgentName),
|
|
200
|
-
preferredShellProxy: rtkDetection.isAvailable ? 'external-proxy' : 'native-fallback',
|
|
201
|
-
externalProxy: {
|
|
202
|
-
detected: Boolean(rtkDetection.isAvailable),
|
|
203
|
-
version: rtkDetection.version,
|
|
204
|
-
detectionError: rtkDetection.detectionError,
|
|
205
|
-
},
|
|
206
|
-
commandRewriteMappings: COMMAND_REWRITE_MAPPINGS.map((mapping) => ({ ...mapping })),
|
|
207
|
-
generatedAt: new Date().toISOString(),
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
export async function readTokenOptimizationState(targetDirectoryPath) {
|
|
212
|
-
const stateFilePath = path.join(
|
|
213
|
-
targetDirectoryPath,
|
|
214
|
-
'.agent-context',
|
|
215
|
-
'state',
|
|
216
|
-
TOKEN_OPTIMIZATION_STATE_FILE_NAME
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
if (!(await pathExists(stateFilePath))) {
|
|
220
|
-
return null;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
try {
|
|
224
|
-
const stateContent = await fs.readFile(stateFilePath, 'utf8');
|
|
225
|
-
const parsedState = JSON.parse(stateContent);
|
|
226
|
-
if (typeof parsedState.enabled !== 'boolean') {
|
|
227
|
-
return null;
|
|
228
|
-
}
|
|
229
|
-
return parsedState;
|
|
230
|
-
} catch {
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
export async function writeTokenOptimizationState(targetDirectoryPath, tokenOptimizationState) {
|
|
236
|
-
const stateDirectoryPath = path.join(targetDirectoryPath, '.agent-context', 'state');
|
|
237
|
-
const stateFilePath = path.join(stateDirectoryPath, TOKEN_OPTIMIZATION_STATE_FILE_NAME);
|
|
238
|
-
|
|
239
|
-
await fs.mkdir(stateDirectoryPath, { recursive: true });
|
|
240
|
-
await fs.writeFile(stateFilePath, JSON.stringify(tokenOptimizationState, null, 2) + '\n', 'utf8');
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
export function buildTokenOptimizationGuidanceBlock(tokenOptimizationState) {
|
|
244
|
-
if (!tokenOptimizationState?.enabled) {
|
|
245
|
-
return [
|
|
246
|
-
'Token optimization mode is disabled for this repository.',
|
|
247
|
-
'Use native shell commands with manual output limiting when needed.',
|
|
248
|
-
].join('\n');
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const rewriteLines = (tokenOptimizationState.commandRewriteMappings || []).map(
|
|
252
|
-
(mapping) => `- ${mapping.rawCommand} => ${mapping.optimizedCommand} (${mapping.reason})`
|
|
253
|
-
);
|
|
254
|
-
|
|
255
|
-
const fallbackGuidance = [
|
|
256
|
-
'- Prefer command variants with bounded output (for example: git diff --stat, rg --max-count, and npm test -- --reporter=dot).',
|
|
257
|
-
'- Request only the lines or sections required for the current decision.',
|
|
258
|
-
'- If shell output is still large, summarize and continue iteratively instead of dumping full logs.',
|
|
259
|
-
];
|
|
260
|
-
|
|
261
|
-
return [
|
|
262
|
-
`Token optimization mode is enabled for agent: ${tokenOptimizationState.selectedAgent}.`,
|
|
263
|
-
`Preferred shell proxy: ${tokenOptimizationState.preferredShellProxy}.`,
|
|
264
|
-
'',
|
|
265
|
-
'Apply command rewrites before running verbose shell commands:',
|
|
266
|
-
...rewriteLines,
|
|
267
|
-
'',
|
|
268
|
-
'Important scope note:',
|
|
269
|
-
'- Shell rewrite hooks affect shell tool calls only.',
|
|
270
|
-
'- Built-in read/grep/glob style tools may bypass shell rewrites, so explicit compact shell commands should be preferred in high-volume sessions.',
|
|
271
|
-
'',
|
|
272
|
-
'Fallback behavior when external proxy is unavailable:',
|
|
273
|
-
...fallbackGuidance,
|
|
274
|
-
].join('\n');
|
|
275
|
-
}
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { platform } from 'node:process';
|
|
5
|
+
|
|
6
|
+
import { pathExists } from './utils.mjs';
|
|
7
|
+
|
|
8
|
+
export const TOKEN_OPTIMIZATION_STATE_FILE_NAME = 'token-optimization.json';
|
|
9
|
+
export const TOKEN_OPTIMIZATION_REPORT_FILE_NAME = 'token-optimization-report.json';
|
|
10
|
+
|
|
11
|
+
const TOKEN_OPTIMIZATION_SCHEMA_VERSION = 'token-optimization-v1';
|
|
12
|
+
const FALLBACK_AGENT_NAME = 'copilot';
|
|
13
|
+
|
|
14
|
+
const SUPPORTED_AGENT_NAMES = new Set([
|
|
15
|
+
'copilot',
|
|
16
|
+
'claude',
|
|
17
|
+
'cursor',
|
|
18
|
+
'windsurf',
|
|
19
|
+
'gemini',
|
|
20
|
+
'codex',
|
|
21
|
+
'cline',
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
const COMMAND_REWRITE_MAPPINGS = [
|
|
25
|
+
{
|
|
26
|
+
rawCommand: 'ls -la',
|
|
27
|
+
optimizedCommand: 'rtk ls .',
|
|
28
|
+
reason: 'Directory listings are grouped and compacted before entering the model context.',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
rawCommand: 'tree',
|
|
32
|
+
optimizedCommand: 'rtk ls .',
|
|
33
|
+
reason: 'Large trees are summarized without losing high-signal structure.',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
rawCommand: 'cat file.ext',
|
|
37
|
+
optimizedCommand: 'rtk read file.ext',
|
|
38
|
+
reason: 'File reads keep signatures and relevant lines while trimming boilerplate.',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
rawCommand: 'rg pattern .',
|
|
42
|
+
optimizedCommand: 'rtk grep "pattern" .',
|
|
43
|
+
reason: 'Search hits are grouped and deduplicated for faster reasoning.',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
rawCommand: 'git status',
|
|
47
|
+
optimizedCommand: 'rtk git status',
|
|
48
|
+
reason: 'Status output is condensed to actionable file changes.',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
rawCommand: 'git diff',
|
|
52
|
+
optimizedCommand: 'rtk git diff',
|
|
53
|
+
reason: 'Diff noise is trimmed while preserving code-review context.',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
rawCommand: 'git log -n 10',
|
|
57
|
+
optimizedCommand: 'rtk git log -n 10',
|
|
58
|
+
reason: 'History is converted to compact one-line summaries.',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
rawCommand: 'npm test',
|
|
62
|
+
optimizedCommand: 'rtk test npm test',
|
|
63
|
+
reason: 'Test results emphasize failures and suppress repetitive pass logs.',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
rawCommand: 'npm run build',
|
|
67
|
+
optimizedCommand: 'rtk err npm run build',
|
|
68
|
+
reason: 'Build runs return errors and warnings only for quicker remediation.',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
rawCommand: 'tsc --noEmit',
|
|
72
|
+
optimizedCommand: 'rtk tsc',
|
|
73
|
+
reason: 'TypeScript diagnostics are grouped by file with less repetition.',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
rawCommand: 'eslint .',
|
|
77
|
+
optimizedCommand: 'rtk lint',
|
|
78
|
+
reason: 'Lint output is grouped by rule and location to reduce token churn.',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
rawCommand: 'docker ps',
|
|
82
|
+
optimizedCommand: 'rtk docker ps',
|
|
83
|
+
reason: 'Container state is summarized into compact rows.',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
rawCommand: 'kubectl get pods',
|
|
87
|
+
optimizedCommand: 'rtk kubectl pods',
|
|
88
|
+
reason: 'Kubernetes output is condensed and stable for agent consumption.',
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
function parseRtkVersion(versionOutput) {
|
|
93
|
+
const versionMatch = versionOutput.match(/\d+\.\d+\.\d+/);
|
|
94
|
+
return versionMatch ? versionMatch[0] : null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function normalizeAgentName(rawAgentName = FALLBACK_AGENT_NAME) {
|
|
98
|
+
const normalizedAgentName = String(rawAgentName || '')
|
|
99
|
+
.trim()
|
|
100
|
+
.toLowerCase();
|
|
101
|
+
|
|
102
|
+
if (!normalizedAgentName) {
|
|
103
|
+
return FALLBACK_AGENT_NAME;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!SUPPORTED_AGENT_NAMES.has(normalizedAgentName)) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Unsupported agent "${rawAgentName}". Supported values: ${Array.from(SUPPORTED_AGENT_NAMES).join(', ')}`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return normalizedAgentName;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function detectRtkBinary() {
|
|
116
|
+
try {
|
|
117
|
+
const versionResult = spawnSync('rtk', ['--version'], {
|
|
118
|
+
encoding: 'utf8',
|
|
119
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
if (versionResult.status !== 0) {
|
|
123
|
+
return {
|
|
124
|
+
isAvailable: false,
|
|
125
|
+
version: null,
|
|
126
|
+
detectionError: (versionResult.stderr || versionResult.stdout || 'Unknown external proxy detection error').trim(),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const detectedVersion = parseRtkVersion(versionResult.stdout || '');
|
|
131
|
+
return {
|
|
132
|
+
isAvailable: true,
|
|
133
|
+
version: detectedVersion,
|
|
134
|
+
detectionError: null,
|
|
135
|
+
};
|
|
136
|
+
} catch (detectionError) {
|
|
137
|
+
return {
|
|
138
|
+
isAvailable: false,
|
|
139
|
+
version: null,
|
|
140
|
+
detectionError: detectionError instanceof Error ? detectionError.message : String(detectionError),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function buildRtkInstallHint() {
|
|
146
|
+
if (platform === 'win32') {
|
|
147
|
+
return 'Install the external token optimizer binary for Windows, extract it, and ensure the executable is on PATH.';
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (platform === 'darwin') {
|
|
151
|
+
return 'Install the external token optimizer with Homebrew, then verify the executable is available in your shell.';
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return 'Install the external token optimizer with the vendor installer, then verify it is available in your shell PATH.';
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function buildRtkHookCommand(selectedAgentName) {
|
|
158
|
+
const normalizedAgentName = normalizeAgentName(selectedAgentName);
|
|
159
|
+
|
|
160
|
+
if (normalizedAgentName === 'copilot') {
|
|
161
|
+
return 'rtk init -g --copilot';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (normalizedAgentName === 'claude') {
|
|
165
|
+
return 'rtk init -g';
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (normalizedAgentName === 'cursor') {
|
|
169
|
+
return 'rtk init -g --agent cursor';
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (normalizedAgentName === 'windsurf') {
|
|
173
|
+
return 'rtk init --agent windsurf';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (normalizedAgentName === 'gemini') {
|
|
177
|
+
return 'rtk init -g --gemini';
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (normalizedAgentName === 'codex') {
|
|
181
|
+
return 'rtk init -g --codex';
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (normalizedAgentName === 'cline') {
|
|
185
|
+
return 'rtk init --agent cline';
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return 'rtk init -g --copilot';
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export function createTokenOptimizationState({
|
|
192
|
+
isEnabled,
|
|
193
|
+
selectedAgentName,
|
|
194
|
+
rtkDetection,
|
|
195
|
+
}) {
|
|
196
|
+
return {
|
|
197
|
+
schemaVersion: TOKEN_OPTIMIZATION_SCHEMA_VERSION,
|
|
198
|
+
enabled: Boolean(isEnabled),
|
|
199
|
+
selectedAgent: normalizeAgentName(selectedAgentName),
|
|
200
|
+
preferredShellProxy: rtkDetection.isAvailable ? 'external-proxy' : 'native-fallback',
|
|
201
|
+
externalProxy: {
|
|
202
|
+
detected: Boolean(rtkDetection.isAvailable),
|
|
203
|
+
version: rtkDetection.version,
|
|
204
|
+
detectionError: rtkDetection.detectionError,
|
|
205
|
+
},
|
|
206
|
+
commandRewriteMappings: COMMAND_REWRITE_MAPPINGS.map((mapping) => ({ ...mapping })),
|
|
207
|
+
generatedAt: new Date().toISOString(),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export async function readTokenOptimizationState(targetDirectoryPath) {
|
|
212
|
+
const stateFilePath = path.join(
|
|
213
|
+
targetDirectoryPath,
|
|
214
|
+
'.agent-context',
|
|
215
|
+
'state',
|
|
216
|
+
TOKEN_OPTIMIZATION_STATE_FILE_NAME
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
if (!(await pathExists(stateFilePath))) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
const stateContent = await fs.readFile(stateFilePath, 'utf8');
|
|
225
|
+
const parsedState = JSON.parse(stateContent);
|
|
226
|
+
if (typeof parsedState.enabled !== 'boolean') {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
return parsedState;
|
|
230
|
+
} catch {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export async function writeTokenOptimizationState(targetDirectoryPath, tokenOptimizationState) {
|
|
236
|
+
const stateDirectoryPath = path.join(targetDirectoryPath, '.agent-context', 'state');
|
|
237
|
+
const stateFilePath = path.join(stateDirectoryPath, TOKEN_OPTIMIZATION_STATE_FILE_NAME);
|
|
238
|
+
|
|
239
|
+
await fs.mkdir(stateDirectoryPath, { recursive: true });
|
|
240
|
+
await fs.writeFile(stateFilePath, JSON.stringify(tokenOptimizationState, null, 2) + '\n', 'utf8');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export function buildTokenOptimizationGuidanceBlock(tokenOptimizationState) {
|
|
244
|
+
if (!tokenOptimizationState?.enabled) {
|
|
245
|
+
return [
|
|
246
|
+
'Token optimization mode is disabled for this repository.',
|
|
247
|
+
'Use native shell commands with manual output limiting when needed.',
|
|
248
|
+
].join('\n');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const rewriteLines = (tokenOptimizationState.commandRewriteMappings || []).map(
|
|
252
|
+
(mapping) => `- ${mapping.rawCommand} => ${mapping.optimizedCommand} (${mapping.reason})`
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
const fallbackGuidance = [
|
|
256
|
+
'- Prefer command variants with bounded output (for example: git diff --stat, rg --max-count, and npm test -- --reporter=dot).',
|
|
257
|
+
'- Request only the lines or sections required for the current decision.',
|
|
258
|
+
'- If shell output is still large, summarize and continue iteratively instead of dumping full logs.',
|
|
259
|
+
];
|
|
260
|
+
|
|
261
|
+
return [
|
|
262
|
+
`Token optimization mode is enabled for agent: ${tokenOptimizationState.selectedAgent}.`,
|
|
263
|
+
`Preferred shell proxy: ${tokenOptimizationState.preferredShellProxy}.`,
|
|
264
|
+
'',
|
|
265
|
+
'Apply command rewrites before running verbose shell commands:',
|
|
266
|
+
...rewriteLines,
|
|
267
|
+
'',
|
|
268
|
+
'Important scope note:',
|
|
269
|
+
'- Shell rewrite hooks affect shell tool calls only.',
|
|
270
|
+
'- Built-in read/grep/glob style tools may bypass shell rewrites, so explicit compact shell commands should be preferred in high-volume sessions.',
|
|
271
|
+
'',
|
|
272
|
+
'Fallback behavior when external proxy is unavailable:',
|
|
273
|
+
...fallbackGuidance,
|
|
274
|
+
].join('\n');
|
|
275
|
+
}
|
package/lib/cli/utils.mjs
CHANGED
|
@@ -9,11 +9,14 @@ import {
|
|
|
9
9
|
REPO_ROOT,
|
|
10
10
|
ALLOWED_SEVERITY_LEVELS,
|
|
11
11
|
PROFILE_PRESETS,
|
|
12
|
+
INIT_PRESETS,
|
|
12
13
|
entryPointFiles,
|
|
13
14
|
directoryCopies,
|
|
14
15
|
} from './constants.mjs';
|
|
15
16
|
|
|
16
17
|
export function printUsage() {
|
|
18
|
+
const presetNames = Object.keys(INIT_PRESETS).join(', ');
|
|
19
|
+
|
|
17
20
|
console.log('Agentic-Senior-Core CLI');
|
|
18
21
|
console.log('');
|
|
19
22
|
console.log('Local runtime:');
|
|
@@ -26,7 +29,7 @@ export function printUsage() {
|
|
|
26
29
|
console.log('Usage:');
|
|
27
30
|
console.log(' agentic-senior-core launch');
|
|
28
31
|
console.log(' agentic-senior-core init [target-directory] [--preset <name>] [--profile <beginner|balanced|strict>] [--profile-pack <name>] [--stack <name>] [--blueprint <name>] [--ci <true|false>] [--newbie] [--token-optimize] [--no-token-optimize] [--token-agent <name>]');
|
|
29
|
-
console.log(' agentic-senior-core upgrade [target-directory] [--dry-run] [--yes]');
|
|
32
|
+
console.log(' agentic-senior-core upgrade [target-directory] [--dry-run] [--yes] [--mcp-template]');
|
|
30
33
|
console.log(' agentic-senior-core optimize [target-directory] [--agent <copilot|claude|cursor|windsurf|gemini|codex|cline>] [--enable|--disable] [--show]');
|
|
31
34
|
console.log(' agentic-senior-core rollback [target-directory]');
|
|
32
35
|
console.log(' agentic-senior-core skill [domain] [--tier <standard|advance|expert|above>] [--json]');
|
|
@@ -36,7 +39,7 @@ export function printUsage() {
|
|
|
36
39
|
console.log(' --help Show help');
|
|
37
40
|
console.log(' --version Show CLI version');
|
|
38
41
|
console.log(' --profile Choose beginner, balanced, or strict');
|
|
39
|
-
console.log(
|
|
42
|
+
console.log(` --preset Use a plug-and-play starter preset (${presetNames})`);
|
|
40
43
|
console.log(' --profile-pack Apply a team profile pack (startup, regulated, platform)');
|
|
41
44
|
console.log(' --newbie Alias for --profile beginner');
|
|
42
45
|
console.log(' --stack Override stack selection');
|
|
@@ -45,6 +48,7 @@ export function printUsage() {
|
|
|
45
48
|
console.log(' --token-optimize Explicitly enable token optimization policy during init (default behavior)');
|
|
46
49
|
console.log(' --token-agent Set token optimization agent target (copilot, claude, cursor, windsurf, gemini, codex, cline)');
|
|
47
50
|
console.log(' --no-token-optimize Disable token optimization policy during init');
|
|
51
|
+
console.log(' --mcp-template Also copy mcp.json template (MCP server registration in IDE is still manual)');
|
|
48
52
|
console.log(' --dry-run Preview upgrade without writing files');
|
|
49
53
|
console.log(' --yes Skip confirmation prompts for upgrade');
|
|
50
54
|
console.log(' --agent Target agent integration for token optimization mode');
|
|
@@ -93,7 +97,12 @@ export async function copyDirectory(sourceDirectoryPath, targetDirectoryPath) {
|
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
99
|
|
|
96
|
-
export async function copyGovernanceAssetsToTarget(
|
|
100
|
+
export async function copyGovernanceAssetsToTarget(
|
|
101
|
+
resolvedTargetDirectoryPath,
|
|
102
|
+
options = {}
|
|
103
|
+
) {
|
|
104
|
+
const shouldIncludeMcpTemplate = options.includeMcpTemplate === true;
|
|
105
|
+
|
|
97
106
|
for (const sourceDirectoryName of directoryCopies) {
|
|
98
107
|
const sourceDirectoryPath = path.join(REPO_ROOT, sourceDirectoryName);
|
|
99
108
|
if (!(await pathExists(sourceDirectoryPath))) {
|
|
@@ -118,6 +127,18 @@ export async function copyGovernanceAssetsToTarget(resolvedTargetDirectoryPath)
|
|
|
118
127
|
await ensureDirectory(path.dirname(targetFilePath));
|
|
119
128
|
await fs.copyFile(sourceFilePath, targetFilePath);
|
|
120
129
|
}
|
|
130
|
+
|
|
131
|
+
if (shouldIncludeMcpTemplate) {
|
|
132
|
+
const sourceMcpPath = path.join(REPO_ROOT, 'mcp.json');
|
|
133
|
+
const targetMcpPath = path.join(resolvedTargetDirectoryPath, 'mcp.json');
|
|
134
|
+
|
|
135
|
+
if (
|
|
136
|
+
await pathExists(sourceMcpPath)
|
|
137
|
+
&& path.resolve(sourceMcpPath) !== path.resolve(targetMcpPath)
|
|
138
|
+
) {
|
|
139
|
+
await fs.copyFile(sourceMcpPath, targetMcpPath);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
121
142
|
}
|
|
122
143
|
|
|
123
144
|
export async function askChoice(promptMessage, options, userInterface) {
|