@ryuenn3123/agentic-senior-core 4.0.3 → 4.2.0

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 (63) hide show
  1. package/.agent-context/prompts/compact-natural-mode.md +100 -0
  2. package/.agent-context/prompts/init-project.md +1 -0
  3. package/.agent-context/prompts/refactor.md +1 -0
  4. package/.agent-context/review-checklists/pr-checklist.md +1 -0
  5. package/.agent-context/rules/api-docs.md +14 -0
  6. package/.agent-context/rules/api-versioning.md +93 -0
  7. package/.agent-context/rules/architecture.md +10 -0
  8. package/.agent-context/rules/background-jobs.md +93 -0
  9. package/.agent-context/rules/config-and-flags.md +79 -0
  10. package/.agent-context/rules/database-design.md +32 -0
  11. package/.agent-context/rules/frontend-architecture.md +35 -0
  12. package/.agent-context/rules/migrations.md +84 -0
  13. package/.agent-context/rules/naming-conv.md +6 -3
  14. package/.agent-context/rules/observability.md +69 -0
  15. package/.agent-context/rules/resilience.md +78 -0
  16. package/.agent-context/rules/security.md +28 -0
  17. package/AGENTS.md +13 -15
  18. package/README.md +102 -91
  19. package/benchmarks/README.md +40 -0
  20. package/benchmarks/compact-natural-mode/fixtures.mjs +359 -0
  21. package/benchmarks/compact-natural-mode/scorer.mjs +331 -0
  22. package/benchmarks/runtime-token-saver/fixtures.mjs +613 -0
  23. package/bin/agentic-senior-core.js +6 -0
  24. package/bin/ascx.js +23 -0
  25. package/lib/cli/adaptive-context/catalog.mjs +428 -0
  26. package/lib/cli/adaptive-context/file-signals.mjs +100 -0
  27. package/lib/cli/adaptive-context/implications.mjs +44 -0
  28. package/lib/cli/adaptive-context.mjs +365 -0
  29. package/lib/cli/ascx/adapters/git-diff.mjs +223 -0
  30. package/lib/cli/ascx/adapters/git-status.mjs +145 -0
  31. package/lib/cli/ascx/adapters/npm-test.mjs +120 -0
  32. package/lib/cli/ascx/fixture-evaluator.mjs +180 -0
  33. package/lib/cli/ascx/formatter.mjs +46 -0
  34. package/lib/cli/ascx/lexer.mjs +113 -0
  35. package/lib/cli/ascx/runtime.mjs +188 -0
  36. package/lib/cli/ascx/tee-writer.mjs +38 -0
  37. package/lib/cli/ascx/token-estimate.mjs +15 -0
  38. package/lib/cli/commands/context.mjs +140 -0
  39. package/lib/cli/commands/init.mjs +2 -1
  40. package/lib/cli/commands/optimize.mjs +143 -2
  41. package/lib/cli/commands/upgrade.mjs +2 -0
  42. package/lib/cli/compiler.mjs +9 -0
  43. package/lib/cli/token-optimization.mjs +161 -6
  44. package/lib/cli/utils.mjs +15 -1
  45. package/package.json +11 -5
  46. package/scripts/adaptive-context/fixtures.mjs +188 -0
  47. package/scripts/adaptive-context-benchmark.mjs +9 -0
  48. package/scripts/ascx-runtime-token-saver-benchmark.mjs +9 -0
  49. package/scripts/audit-cache-layer-contract.mjs +5 -0
  50. package/scripts/audit-caching-scope-hygiene.mjs +5 -0
  51. package/scripts/clean-local-artifacts.mjs +0 -1
  52. package/scripts/compact-natural-mode-benchmark.mjs +9 -0
  53. package/scripts/frontend-usability-audit.mjs +5 -8
  54. package/scripts/release-gate/static-checks.mjs +7 -7
  55. package/scripts/validate/config.mjs +1 -2
  56. package/scripts/validate/coverage-checks.mjs +1 -42
  57. package/scripts/validate.mjs +11 -7
  58. package/scripts/migrate-rule-format/id-prefix-table.mjs +0 -37
  59. package/scripts/migrate-rule-format/parse-legacy.mjs +0 -180
  60. package/scripts/migrate-rule-format/render-new.mjs +0 -169
  61. package/scripts/migrate-rule-format/roundtrip-validate.mjs +0 -89
  62. package/scripts/migrate-rule-format.mjs +0 -192
  63. package/scripts/v3-purge-audit.mjs +0 -236
@@ -0,0 +1,188 @@
1
+ import { spawn } from 'node:child_process';
2
+
3
+ import { compressGitDiffOutput } from './adapters/git-diff.mjs';
4
+ import { compressGitStatusOutput } from './adapters/git-status.mjs';
5
+ import { compressNpmTestOutput } from './adapters/npm-test.mjs';
6
+ import { buildAscxFooter, shouldWriteSafetyTee } from './formatter.mjs';
7
+ import { classifyAscxInvocation, parseAscxCommand } from './lexer.mjs';
8
+ import { writeRawTeeFile } from './tee-writer.mjs';
9
+
10
+ const ADAPTERS = {
11
+ 'git-diff': compressGitDiffOutput,
12
+ 'git-status': compressGitStatusOutput,
13
+ 'npm-test': compressNpmTestOutput,
14
+ };
15
+
16
+ function buildCommandEnvironment(baseEnvironment, parsedCommand) {
17
+ const commandEnvironment = { ...baseEnvironment };
18
+
19
+ for (const assignment of parsedCommand.environment) {
20
+ const separatorIndex = assignment.indexOf('=');
21
+ const variableName = assignment.slice(0, separatorIndex);
22
+ const variableValue = assignment.slice(separatorIndex + 1);
23
+
24
+ commandEnvironment[variableName] = variableValue;
25
+ }
26
+
27
+ return commandEnvironment;
28
+ }
29
+
30
+ function runSpawnedCommand(parsedCommand, options = {}) {
31
+ const {
32
+ cwd = process.cwd(),
33
+ env = process.env,
34
+ shell = false,
35
+ } = options;
36
+
37
+ return new Promise((resolve) => {
38
+ const useWindowsNpmShell = process.platform === 'win32'
39
+ && parsedCommand.executable === 'npm'
40
+ && shell === false;
41
+ const executable = shell
42
+ ? parsedCommand.commandText
43
+ : parsedCommand.executable;
44
+ const args = shell ? [] : parsedCommand.args;
45
+ const childProcess = spawn(executable, args, {
46
+ cwd,
47
+ env: buildCommandEnvironment(env, parsedCommand),
48
+ shell: shell || useWindowsNpmShell,
49
+ windowsHide: true,
50
+ });
51
+ let stdout = '';
52
+ let stderr = '';
53
+
54
+ childProcess.stdout?.setEncoding('utf8');
55
+ childProcess.stderr?.setEncoding('utf8');
56
+ childProcess.stdout?.on('data', (chunk) => {
57
+ stdout += chunk;
58
+ });
59
+ childProcess.stderr?.on('data', (chunk) => {
60
+ stderr += chunk;
61
+ });
62
+ childProcess.on('error', (error) => {
63
+ stderr += `${error.name}: ${error.message}\n`;
64
+ });
65
+ childProcess.on('close', (exitCode) => {
66
+ resolve({
67
+ stdout,
68
+ stderr,
69
+ exitCode: typeof exitCode === 'number' ? exitCode : 1,
70
+ });
71
+ });
72
+ });
73
+ }
74
+
75
+ function combineOutput(stdout, stderr) {
76
+ return [stdout, stderr].filter(Boolean).join('\n');
77
+ }
78
+
79
+ async function formatCompressedResult({
80
+ adapterResult,
81
+ capture,
82
+ classification,
83
+ commandText,
84
+ cwd,
85
+ teeDirectoryPath,
86
+ }) {
87
+ const rawOutput = combineOutput(capture.stdout, capture.stderr);
88
+ const preliminaryFooter = buildAscxFooter({
89
+ classification: classification.kind,
90
+ commandText,
91
+ compactOutput: adapterResult.output,
92
+ exitCode: capture.exitCode,
93
+ filterName: adapterResult.filterName,
94
+ rawOutput,
95
+ rawTeePath: null,
96
+ });
97
+ const rawTeePath = shouldWriteSafetyTee({
98
+ adapterResult,
99
+ exitCode: capture.exitCode,
100
+ reductionPercent: preliminaryFooter.reductionPercent,
101
+ })
102
+ ? await writeRawTeeFile({
103
+ commandText,
104
+ cwd,
105
+ exitCode: capture.exitCode,
106
+ rawOutput,
107
+ teeDirectoryPath,
108
+ })
109
+ : null;
110
+ const footer = buildAscxFooter({
111
+ classification: classification.kind,
112
+ commandText,
113
+ compactOutput: adapterResult.output,
114
+ exitCode: capture.exitCode,
115
+ filterName: adapterResult.filterName,
116
+ rawOutput,
117
+ rawTeePath,
118
+ });
119
+
120
+ return {
121
+ stdout: `${adapterResult.output}\n\n${footer.text}\n`,
122
+ stderr: '',
123
+ exitCode: capture.exitCode,
124
+ compressed: adapterResult.confident === true,
125
+ rawTeePath,
126
+ footer,
127
+ adapterResult,
128
+ };
129
+ }
130
+
131
+ export async function runAscx(commandArguments, options = {}) {
132
+ const {
133
+ cwd = process.cwd(),
134
+ executeCommand = runSpawnedCommand,
135
+ teeDirectoryPath,
136
+ } = options;
137
+ const parsedCommand = parseAscxCommand(commandArguments);
138
+ const classification = classifyAscxInvocation(parsedCommand);
139
+
140
+ if (!parsedCommand.executable) {
141
+ return {
142
+ stdout: '',
143
+ stderr: 'ascx: command is required\n',
144
+ exitCode: 1,
145
+ parsedCommand,
146
+ classification,
147
+ compressed: false,
148
+ rawTeePath: null,
149
+ };
150
+ }
151
+
152
+ const capture = await executeCommand(parsedCommand, {
153
+ cwd,
154
+ shell: classification.kind === 'unsafe-for-compression',
155
+ });
156
+
157
+ if (classification.kind !== 'compressible') {
158
+ return {
159
+ stdout: capture.stdout,
160
+ stderr: capture.stderr,
161
+ exitCode: capture.exitCode,
162
+ parsedCommand,
163
+ classification,
164
+ compressed: false,
165
+ rawTeePath: null,
166
+ };
167
+ }
168
+
169
+ const adapter = ADAPTERS[classification.adapterName];
170
+ const adapterResult = adapter({
171
+ stdout: capture.stdout,
172
+ stderr: capture.stderr,
173
+ exitCode: capture.exitCode,
174
+ });
175
+
176
+ return {
177
+ ...await formatCompressedResult({
178
+ adapterResult,
179
+ capture,
180
+ classification,
181
+ commandText: parsedCommand.commandText,
182
+ cwd,
183
+ teeDirectoryPath,
184
+ }),
185
+ parsedCommand,
186
+ classification,
187
+ };
188
+ }
@@ -0,0 +1,38 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+
4
+ function sanitizeFileNamePart(rawValue) {
5
+ return String(rawValue || 'command')
6
+ .toLowerCase()
7
+ .replace(/[^a-z0-9._-]+/g, '-')
8
+ .replace(/^-+|-+$/g, '')
9
+ .slice(0, 60) || 'command';
10
+ }
11
+
12
+ export function getDefaultTeeDirectory(cwd = process.cwd()) {
13
+ return path.resolve(cwd, '.agent-context', 'state', 'token-saver', 'tee');
14
+ }
15
+
16
+ export async function writeRawTeeFile({
17
+ commandText,
18
+ cwd = process.cwd(),
19
+ exitCode,
20
+ rawOutput,
21
+ teeDirectoryPath = getDefaultTeeDirectory(cwd),
22
+ }) {
23
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
24
+ const commandName = sanitizeFileNamePart(commandText);
25
+ const teeFilePath = path.resolve(teeDirectoryPath, `${timestamp}-${commandName}.log`);
26
+ const fileContent = [
27
+ `[ascx raw output]`,
28
+ `command: ${commandText}`,
29
+ `exit: ${exitCode}`,
30
+ '',
31
+ rawOutput,
32
+ ].join('\n');
33
+
34
+ await fs.mkdir(path.dirname(teeFilePath), { recursive: true });
35
+ await fs.writeFile(teeFilePath, fileContent, 'utf8');
36
+
37
+ return teeFilePath;
38
+ }
@@ -0,0 +1,15 @@
1
+ export const ASCX_TOKEN_ESTIMATE_METHOD = 'chars-div-4-local-estimate';
2
+
3
+ export function estimateOutputTokens(outputText) {
4
+ const textLength = String(outputText || '').length;
5
+ return Math.max(0, Math.ceil(textLength / 4));
6
+ }
7
+
8
+ export function calculateReductionPercent(rawTokens, compactTokens) {
9
+ if (rawTokens <= 0) {
10
+ return 0;
11
+ }
12
+
13
+ const reducedTokens = Math.max(0, rawTokens - compactTokens);
14
+ return Number(((reducedTokens / rawTokens) * 100).toFixed(2));
15
+ }
@@ -0,0 +1,140 @@
1
+ import { stdin } from 'node:process';
2
+
3
+ import { buildSelectedContextManifest } from '../adaptive-context.mjs';
4
+
5
+ export function parseContextArguments(commandArguments) {
6
+ const parsedOptions = {
7
+ requestId: 'adhoc-request',
8
+ requestText: '',
9
+ contextFiles: [],
10
+ json: false,
11
+ readStdin: false,
12
+ };
13
+ const requestParts = [];
14
+
15
+ for (let argumentIndex = 0; argumentIndex < commandArguments.length; argumentIndex++) {
16
+ const currentArgument = commandArguments[argumentIndex];
17
+
18
+ if (currentArgument === '--json') {
19
+ parsedOptions.json = true;
20
+ continue;
21
+ }
22
+
23
+ if (currentArgument === '--stdin') {
24
+ parsedOptions.readStdin = true;
25
+ continue;
26
+ }
27
+
28
+ if (currentArgument === '--file') {
29
+ const contextFilePath = commandArguments[argumentIndex + 1];
30
+ if (!contextFilePath || contextFilePath.startsWith('--')) {
31
+ throw new Error('Missing value for --file');
32
+ }
33
+
34
+ parsedOptions.contextFiles.push(contextFilePath);
35
+ argumentIndex++;
36
+ continue;
37
+ }
38
+
39
+ if (currentArgument === '--files') {
40
+ const contextFileList = commandArguments[argumentIndex + 1];
41
+ if (!contextFileList || contextFileList.startsWith('--')) {
42
+ throw new Error('Missing value for --files');
43
+ }
44
+
45
+ parsedOptions.contextFiles.push(
46
+ ...contextFileList
47
+ .split(',')
48
+ .map((contextFilePath) => contextFilePath.trim())
49
+ .filter(Boolean)
50
+ );
51
+ argumentIndex++;
52
+ continue;
53
+ }
54
+
55
+ if (currentArgument === '--request-id') {
56
+ const requestId = commandArguments[argumentIndex + 1];
57
+ if (!requestId || requestId.startsWith('--')) {
58
+ throw new Error('Missing value for --request-id');
59
+ }
60
+
61
+ parsedOptions.requestId = requestId;
62
+ argumentIndex++;
63
+ continue;
64
+ }
65
+
66
+ if (currentArgument.startsWith('--')) {
67
+ throw new Error(`Unknown option: ${currentArgument}`);
68
+ }
69
+
70
+ requestParts.push(currentArgument);
71
+ }
72
+
73
+ parsedOptions.requestText = requestParts.join(' ').trim();
74
+ return parsedOptions;
75
+ }
76
+
77
+ function readRequestFromStdin() {
78
+ return new Promise((resolve, reject) => {
79
+ let requestText = '';
80
+
81
+ stdin.setEncoding('utf8');
82
+ stdin.on('data', (chunk) => {
83
+ requestText += chunk;
84
+ });
85
+ stdin.on('error', reject);
86
+ stdin.on('end', () => {
87
+ resolve(requestText.trim());
88
+ });
89
+ });
90
+ }
91
+
92
+ function formatList(label, values) {
93
+ if (values.length === 0) {
94
+ return [`${label}: none`];
95
+ }
96
+
97
+ return [
98
+ `${label}:`,
99
+ ...values.map((value) => `- ${value}`),
100
+ ];
101
+ }
102
+
103
+ function formatManifestText(manifest) {
104
+ return [
105
+ 'Adaptive Context',
106
+ `requestId: ${manifest.requestId}`,
107
+ `labels: ${manifest.labels.length > 0 ? manifest.labels.join(', ') : 'none'}`,
108
+ `uncertainty: ${manifest.uncertainty}`,
109
+ `budget: ${manifest.budget.status} (${manifest.budget.selectedRuleCount}/${manifest.budget.maxRecommendedRuleCount} recommended rules)`,
110
+ `fallbackRequired: ${manifest.fallbackRequired}`,
111
+ ...formatList('contextFiles', manifest.contextFiles),
112
+ ...formatList('selectedRules', manifest.selectedRules),
113
+ ...formatList('selectedPrompts', manifest.selectedPrompts),
114
+ ...formatList('selectedDocs', manifest.selectedDocs),
115
+ ].join('\n');
116
+ }
117
+
118
+ export async function runContextCommand(commandArguments) {
119
+ const contextOptions = parseContextArguments(commandArguments);
120
+ const requestText = contextOptions.readStdin
121
+ ? await readRequestFromStdin()
122
+ : contextOptions.requestText;
123
+
124
+ if (!requestText) {
125
+ throw new Error('Context request text is required. Pass text as arguments or use --stdin.');
126
+ }
127
+
128
+ const manifest = buildSelectedContextManifest({
129
+ contextFiles: contextOptions.contextFiles,
130
+ requestId: contextOptions.requestId,
131
+ requestText,
132
+ });
133
+
134
+ if (contextOptions.json) {
135
+ console.log(JSON.stringify(manifest, null, 2));
136
+ return;
137
+ }
138
+
139
+ console.log(formatManifestText(manifest));
140
+ }
@@ -565,6 +565,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
565
565
  console.log(`- Review thresholds: ${formatBlockingSeverities(selectedPolicyProfile.blockingSeverities)}`);
566
566
  console.log(`- Setup time: ${formatDuration(setupDurationMs)}`);
567
567
  console.log('- Generated files: AGENTS.md, CLAUDE.md, GEMINI.md, .agent-context/, and .agent-context/state/onboarding-report.json');
568
+ console.log('- Default response mode: Compact Natural Mode enabled (.agent-context/prompts/compact-natural-mode.md)');
568
569
  if (scaffoldingResult?.bootstrapMode === 'ai-synthesis') {
569
570
  console.log(`- Bootstrap prompts: ${(scaffoldingResult.generatedPromptFileNames || []).length} files generated in .agent-context/prompts/`);
570
571
  if ((scaffoldingResult.materializedFileNames || []).length > 0) {
@@ -587,7 +588,7 @@ export async function runInitCommand(targetDirectoryArgument, initOptions = {})
587
588
  console.log('- Memory continuity policy: disabled (--no-memory-continuity)');
588
589
  }
589
590
  if (isTokenOptimizationEnabled) {
590
- console.log(`- Token optimization policy: enabled for ${selectedTokenAgentName}`);
591
+ console.log(`- Token optimization policy: enabled for ${selectedTokenAgentName} (ASCX command guidance on)`);
591
592
  } else {
592
593
  console.log('- Token optimization policy: disabled (--no-token-optimize)');
593
594
  }
@@ -7,6 +7,11 @@ import {
7
7
  TOKEN_OPTIMIZATION_REPORT_FILE_NAME,
8
8
  normalizeAgentName,
9
9
  detectRtkBinary,
10
+ detectAscxRuntime,
11
+ checkAscxTeeReadiness,
12
+ resolveRuntimeTokenSaverMode,
13
+ buildRuntimeTokenSaverWarnings,
14
+ buildRuntimeTokenSaverNextAction,
10
15
  buildRtkInstallHint,
11
16
  buildRtkHookCommand,
12
17
  createTokenOptimizationState,
@@ -19,12 +24,43 @@ export function parseOptimizeArguments(commandArguments) {
19
24
  targetDirectory: '.',
20
25
  agent: 'copilot',
21
26
  enabled: true,
27
+ mode: 'configure',
22
28
  show: false,
23
29
  };
24
30
 
31
+ function setOptimizeMode(nextMode) {
32
+ if (parsedOptimizeOptions.mode !== 'configure' && parsedOptimizeOptions.mode !== nextMode) {
33
+ throw new Error(`Conflicting optimize modes: ${parsedOptimizeOptions.mode} and ${nextMode}`);
34
+ }
35
+
36
+ parsedOptimizeOptions.mode = nextMode;
37
+ }
38
+
25
39
  for (let argumentIndex = 0; argumentIndex < commandArguments.length; argumentIndex++) {
26
40
  const currentArgument = commandArguments[argumentIndex];
27
41
 
42
+ if (currentArgument === 'install') {
43
+ setOptimizeMode('install');
44
+ parsedOptimizeOptions.enabled = true;
45
+ continue;
46
+ }
47
+
48
+ if (currentArgument === 'off') {
49
+ setOptimizeMode('off');
50
+ parsedOptimizeOptions.enabled = false;
51
+ continue;
52
+ }
53
+
54
+ if (currentArgument === 'status') {
55
+ setOptimizeMode('status');
56
+ continue;
57
+ }
58
+
59
+ if (currentArgument === 'doctor') {
60
+ setOptimizeMode('doctor');
61
+ continue;
62
+ }
63
+
28
64
  if (!currentArgument.startsWith('--')) {
29
65
  parsedOptimizeOptions.targetDirectory = currentArgument;
30
66
  continue;
@@ -43,19 +79,36 @@ export function parseOptimizeArguments(commandArguments) {
43
79
 
44
80
  if (currentArgument === '--enable') {
45
81
  parsedOptimizeOptions.enabled = true;
82
+ if (parsedOptimizeOptions.mode === 'off') {
83
+ setOptimizeMode('install');
84
+ }
46
85
  continue;
47
86
  }
48
87
 
49
88
  if (currentArgument === '--disable') {
50
89
  parsedOptimizeOptions.enabled = false;
90
+ if (parsedOptimizeOptions.mode === 'install') {
91
+ setOptimizeMode('off');
92
+ }
51
93
  continue;
52
94
  }
53
95
 
54
96
  if (currentArgument === '--show') {
97
+ setOptimizeMode('show');
55
98
  parsedOptimizeOptions.show = true;
56
99
  continue;
57
100
  }
58
101
 
102
+ if (currentArgument === '--status') {
103
+ setOptimizeMode('status');
104
+ continue;
105
+ }
106
+
107
+ if (currentArgument === '--doctor') {
108
+ setOptimizeMode('doctor');
109
+ continue;
110
+ }
111
+
59
112
  throw new Error(`Unknown option: ${currentArgument}`);
60
113
  }
61
114
 
@@ -63,6 +116,78 @@ export function parseOptimizeArguments(commandArguments) {
63
116
  return parsedOptimizeOptions;
64
117
  }
65
118
 
119
+ function formatStatusLine(label, value) {
120
+ return `${label}: ${value}`;
121
+ }
122
+
123
+ async function buildRuntimeTokenSaverStatus(resolvedTargetDirectoryPath, options = {}) {
124
+ const onboardingReport = await loadOnboardingReportIfExists(resolvedTargetDirectoryPath);
125
+ const existingOptimizationState = await readTokenOptimizationState(resolvedTargetDirectoryPath);
126
+ const ascxDetection = detectAscxRuntime();
127
+ const rtkDetection = detectRtkBinary();
128
+ const teeReadiness = await checkAscxTeeReadiness(resolvedTargetDirectoryPath, {
129
+ writeProbe: options.writeProbe === true,
130
+ });
131
+ const mode = resolveRuntimeTokenSaverMode({
132
+ tokenOptimizationState: existingOptimizationState,
133
+ ascxDetection,
134
+ rtkDetection,
135
+ });
136
+ const warnings = buildRuntimeTokenSaverWarnings({
137
+ mode,
138
+ onboardingReport,
139
+ ascxDetection,
140
+ teeReadiness,
141
+ rtkDetection,
142
+ });
143
+
144
+ return {
145
+ targetDirectory: resolvedTargetDirectoryPath,
146
+ initialized: Boolean(onboardingReport),
147
+ mode,
148
+ ascx: ascxDetection,
149
+ tee: teeReadiness,
150
+ rtk: rtkDetection,
151
+ nineRouter: {
152
+ status: 'not-checked',
153
+ reason: 'localhost probing is intentionally deferred',
154
+ },
155
+ warnings,
156
+ nextAction: buildRuntimeTokenSaverNextAction({ mode, warnings }),
157
+ tokenOptimizationState: existingOptimizationState,
158
+ };
159
+ }
160
+
161
+ function printRuntimeTokenSaverStatus(statusReport, options = {}) {
162
+ const title = options.title || 'Runtime token saver status';
163
+ const ascxStatus = statusReport.ascx.isAvailable
164
+ ? `found (${statusReport.ascx.source})`
165
+ : 'missing';
166
+ const rtkStatus = statusReport.rtk.isAvailable
167
+ ? `detected${statusReport.rtk.version ? ` (${statusReport.rtk.version})` : ''}`
168
+ : 'not-detected';
169
+
170
+ console.log(title);
171
+ console.log(formatStatusLine('target', statusReport.targetDirectory));
172
+ console.log(formatStatusLine('initialized', statusReport.initialized ? 'yes' : 'no'));
173
+ console.log(formatStatusLine('mode', statusReport.mode));
174
+ console.log(formatStatusLine('ascx', ascxStatus));
175
+ console.log(formatStatusLine('tee', `${statusReport.tee.status} (${statusReport.tee.path})`));
176
+ console.log(formatStatusLine('rtk', rtkStatus));
177
+ console.log(formatStatusLine('9router', statusReport.nineRouter.status));
178
+
179
+ if (statusReport.warnings.length > 0) {
180
+ console.log('warnings:');
181
+ for (const warning of statusReport.warnings) {
182
+ console.log(`- ${warning}`);
183
+ }
184
+ } else {
185
+ console.log('warnings: none');
186
+ }
187
+
188
+ console.log(formatStatusLine('next_action', statusReport.nextAction));
189
+ }
190
+
66
191
  export async function runOptimizeCommand(targetDirectoryArgument, optimizeOptions = {}) {
67
192
  const optimizationStartedAt = Date.now();
68
193
  const resolvedTargetDirectoryPath = path.resolve(targetDirectoryArgument || '.');
@@ -72,7 +197,23 @@ export async function runOptimizeCommand(targetDirectoryArgument, optimizeOption
72
197
  const selectedAgentName = normalizeAgentName(optimizeOptions.agent || 'copilot');
73
198
  const rtkDetection = detectRtkBinary();
74
199
 
75
- if (optimizeOptions.show) {
200
+ if (optimizeOptions.mode === 'status') {
201
+ const statusReport = await buildRuntimeTokenSaverStatus(resolvedTargetDirectoryPath);
202
+ printRuntimeTokenSaverStatus(statusReport);
203
+ return;
204
+ }
205
+
206
+ if (optimizeOptions.mode === 'doctor') {
207
+ const statusReport = await buildRuntimeTokenSaverStatus(resolvedTargetDirectoryPath, {
208
+ writeProbe: true,
209
+ });
210
+ printRuntimeTokenSaverStatus(statusReport, {
211
+ title: 'ASCX runtime token saver doctor',
212
+ });
213
+ return;
214
+ }
215
+
216
+ if (optimizeOptions.show || optimizeOptions.mode === 'show') {
76
217
  const existingOptimizationState = await readTokenOptimizationState(resolvedTargetDirectoryPath);
77
218
  console.log(
78
219
  JSON.stringify(
@@ -97,7 +238,7 @@ export async function runOptimizeCommand(targetDirectoryArgument, optimizeOption
97
238
  }
98
239
 
99
240
  const tokenOptimizationState = createTokenOptimizationState({
100
- isEnabled: optimizeOptions.enabled,
241
+ isEnabled: optimizeOptions.mode === 'off' ? false : optimizeOptions.enabled,
101
242
  selectedAgentName,
102
243
  rtkDetection,
103
244
  });
@@ -302,6 +302,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
302
302
  }
303
303
  console.log(`- CI/CD quality checks (guardrails): ${includeCiGuardrails ? 'enabled' : 'disabled'}`);
304
304
  console.log('- Instruction surface: AGENTS.md canonical with CLAUDE.md and GEMINI.md import bridges');
305
+ console.log('- Default response mode: Compact Natural Mode enabled');
305
306
  console.log(`- Managed surface stale files: ${managedSurfacePlan.staleFiles.length}`);
306
307
  console.log(`- Managed surface stale directories: ${managedSurfacePlan.staleDirectories.length}`);
307
308
  console.log(`- Managed surface sync mode: 1:1 (prune enabled)`);
@@ -464,6 +465,7 @@ export async function runUpgradeCommand(targetDirectoryArgument, upgradeOptions
464
465
  }
465
466
 
466
467
  console.log('\nRefreshed files: AGENTS.md, CLAUDE.md, GEMINI.md, .agent-context/, and .agent-context/state/onboarding-report.json');
468
+ console.log('Default response mode remains Compact Natural Mode through .agent-context/prompts/compact-natural-mode.md.');
467
469
  console.log('\nNext-step suggestion (UI scope): run `npx @ryuenn3123/agentic-senior-core audit:design-anti-repeat` to scan CSS, SCSS, SASS, LESS, Tailwind config, and design-token files in this project for typography or palette values that match the anti-repeat ledger in docs/design-intent.json. Add it to your CI alongside `npm test` once the design dossier is populated.');
468
470
  } catch (error) {
469
471
  console.error('\n[FATAL] An error occurred during upgrade. Attempting automatic rollback...');
@@ -202,6 +202,14 @@ export async function writeOnboardingReport({
202
202
  containerizationStrategy: buildContainerizationStrategySnapshot(dockerStrategy),
203
203
  tokenOptimization: resolvedTokenOptimization,
204
204
  memoryContinuity: resolvedMemoryContinuity,
205
+ responseCompression: {
206
+ enabled: true,
207
+ mode: 'compact-natural-mode',
208
+ defaultOn: true,
209
+ promptFile: '.agent-context/prompts/compact-natural-mode.md',
210
+ appliesTo: 'agent-final-responses',
211
+ commandOutputBoundary: 'ASCX handles command-output compression separately',
212
+ },
205
213
  autoDetection: {
206
214
  detectedStack: projectDetection.detectedStackFileName,
207
215
  detectedAdditionalStacks: projectDetection.secondaryStackFileNames || [],
@@ -383,6 +391,7 @@ export async function buildCompiledRulesContent({
383
391
  [
384
392
  '## LAYER 5: EXECUTION PROMPTS AND UI TRIGGERS',
385
393
  'Load these prompt contracts only when their trigger matches the user request:',
394
+ 'Default. .agent-context/prompts/compact-natural-mode.md -> final response shape and evidence-preserving compact prose',
386
395
  '0. Documentation-first mode -> docs, documentation, dokumen, docs/*, architecture docs, flow docs, API docs, lengkapkan docs',
387
396
  '1. .agent-context/prompts/init-project.md -> create, build, new project, scaffold',
388
397
  '2. .agent-context/prompts/refactor.md -> refactor, improve, clean up, fix',