@ryuenn3123/agentic-senior-core 4.3.15 → 5.1.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 (198) hide show
  1. package/.agents/plugins/marketplace.json +21 -0
  2. package/.agents/rules/agentic-senior-core.md +126 -0
  3. package/.claude-plugin/marketplace.json +17 -0
  4. package/.claude-plugin/plugin.json +17 -0
  5. package/.clinerules/agentic-senior-core.md +94 -0
  6. package/.codex-plugin/plugin.json +24 -0
  7. package/.cursor/rules/agentic-senior-core.mdc +99 -0
  8. package/.devin-plugin/plugin.json +13 -0
  9. package/.github/copilot-instructions.md +94 -0
  10. package/.github/plugin/marketplace.json +20 -0
  11. package/.github/plugin/plugin.json +16 -0
  12. package/.kiro/steering/agentic-senior-core.md +94 -0
  13. package/.openclaw/skills/asc/SKILL.md +23 -0
  14. package/.openclaw/skills/asc-audit/SKILL.md +28 -0
  15. package/.openclaw/skills/asc-review/SKILL.md +54 -0
  16. package/.opencode/plugins/agentic-senior-core.mjs +31 -0
  17. package/.windsurf/rules/agentic-senior-core.md +94 -0
  18. package/AGENTS.md +126 -179
  19. package/CONTRIBUTING.md +93 -63
  20. package/README.md +160 -111
  21. package/__init__.py +61 -0
  22. package/bin/agentic-senior-core.js +41 -43
  23. package/commands/asc-audit.md +1 -0
  24. package/commands/asc-audit.toml +2 -0
  25. package/commands/asc-help.md +9 -0
  26. package/commands/asc-help.toml +2 -0
  27. package/commands/asc-refactor.md +1 -0
  28. package/commands/asc-refactor.toml +2 -0
  29. package/commands/asc-review.md +1 -0
  30. package/commands/asc-review.toml +2 -0
  31. package/gemini-extension.json +10 -0
  32. package/hooks/copilot-hooks.json +21 -0
  33. package/hooks/hooks.json +31 -0
  34. package/hooks/session-start.js +36 -0
  35. package/hooks/subagent-start.js +38 -0
  36. package/lib/cli/commands/adapter.mjs +109 -0
  37. package/lib/cli/commands/clean.mjs +63 -0
  38. package/lib/cli/commands/status.mjs +94 -0
  39. package/package.json +43 -67
  40. package/plugin.yaml +16 -0
  41. package/scripts/uninstall.js +38 -0
  42. package/skills/asc/SKILL.md +16 -0
  43. package/skills/asc-audit/SKILL.md +28 -0
  44. package/skills/asc-refactor/SKILL.md +35 -0
  45. package/skills/asc-review/SKILL.md +54 -0
  46. package/.agent-context/policies/llm-judge-threshold.json +0 -29
  47. package/.agent-context/prompts/bootstrap-design.md +0 -63
  48. package/.agent-context/prompts/compact-natural-mode.md +0 -100
  49. package/.agent-context/prompts/init-project.md +0 -60
  50. package/.agent-context/prompts/refactor.md +0 -38
  51. package/.agent-context/prompts/review-code.md +0 -31
  52. package/.agent-context/review-checklists/architecture-review.md +0 -57
  53. package/.agent-context/review-checklists/pr-checklist.md +0 -136
  54. package/.agent-context/rules/api-docs.md +0 -24
  55. package/.agent-context/rules/api-versioning.md +0 -16
  56. package/.agent-context/rules/architecture.md +0 -33
  57. package/.agent-context/rules/background-jobs.md +0 -17
  58. package/.agent-context/rules/config-and-flags.md +0 -16
  59. package/.agent-context/rules/database-design.md +0 -18
  60. package/.agent-context/rules/docker-runtime.md +0 -17
  61. package/.agent-context/rules/error-handling.md +0 -16
  62. package/.agent-context/rules/event-driven.md +0 -16
  63. package/.agent-context/rules/frontend-architecture.md +0 -54
  64. package/.agent-context/rules/microservices.md +0 -16
  65. package/.agent-context/rules/migrations.md +0 -16
  66. package/.agent-context/rules/observability.md +0 -16
  67. package/.agent-context/rules/performance.md +0 -16
  68. package/.agent-context/rules/realtime.md +0 -16
  69. package/.agent-context/rules/resilience.md +0 -18
  70. package/.agent-context/rules/security.md +0 -18
  71. package/.agent-context/rules/testing.md +0 -16
  72. package/.agent-context/state/README.md +0 -25
  73. package/.agent-context/state/architecture-map.md +0 -40
  74. package/.agent-context/state/benchmark-comparison-schema.json +0 -181
  75. package/.agent-context/state/benchmark-reproducibility.json +0 -87
  76. package/.agent-context/state/benchmark-thresholds.json +0 -10
  77. package/.agent-context/state/benchmark-writer-judge-config.json +0 -58
  78. package/.agent-context/state/dependency-map.md +0 -41
  79. package/.agent-context/state/memory-adapter-contract.json +0 -52
  80. package/.agent-context/state/memory-schema-v1.json +0 -88
  81. package/GEMINI.md +0 -1
  82. package/benchmarks/README.md +0 -60
  83. package/benchmarks/compact-natural-mode/fixtures.mjs +0 -359
  84. package/benchmarks/compact-natural-mode/scorer.mjs +0 -331
  85. package/benchmarks/runtime-token-saver/fixtures.mjs +0 -836
  86. package/lib/cli/adaptive-context/catalog.mjs +0 -390
  87. package/lib/cli/adaptive-context/file-signals.mjs +0 -100
  88. package/lib/cli/adaptive-context/implications.mjs +0 -44
  89. package/lib/cli/adaptive-context.mjs +0 -365
  90. package/lib/cli/audits/typography-palette-anti-repeat/color-utils.mjs +0 -156
  91. package/lib/cli/audits/typography-palette-anti-repeat/file-scanner.mjs +0 -103
  92. package/lib/cli/audits/typography-palette-anti-repeat/typography-utils.mjs +0 -70
  93. package/lib/cli/audits/typography-palette-anti-repeat-audit.mjs +0 -239
  94. package/lib/cli/backup.mjs +0 -210
  95. package/lib/cli/commands/audit-design-anti-repeat.mjs +0 -39
  96. package/lib/cli/commands/context.mjs +0 -140
  97. package/lib/cli/commands/init/project-context.mjs +0 -60
  98. package/lib/cli/commands/init/runtime-environment.mjs +0 -59
  99. package/lib/cli/commands/init/setup-decisions.mjs +0 -83
  100. package/lib/cli/commands/init.mjs +0 -654
  101. package/lib/cli/commands/launch.mjs +0 -76
  102. package/lib/cli/commands/optimize.mjs +0 -284
  103. package/lib/cli/commands/rollback.mjs +0 -64
  104. package/lib/cli/commands/upgrade/token-optimization-state.mjs +0 -51
  105. package/lib/cli/commands/upgrade.mjs +0 -451
  106. package/lib/cli/compiler.mjs +0 -570
  107. package/lib/cli/constants.mjs +0 -136
  108. package/lib/cli/detector/constants.mjs +0 -135
  109. package/lib/cli/detector/design-evidence/collector.mjs +0 -256
  110. package/lib/cli/detector/design-evidence/constants.mjs +0 -39
  111. package/lib/cli/detector/design-evidence/file-traversal.mjs +0 -83
  112. package/lib/cli/detector/design-evidence/structured-attribute-evidence.mjs +0 -117
  113. package/lib/cli/detector/design-evidence/summary.mjs +0 -109
  114. package/lib/cli/detector/design-evidence/utility-helpers.mjs +0 -122
  115. package/lib/cli/detector/design-evidence.mjs +0 -25
  116. package/lib/cli/detector/stack-detection.mjs +0 -243
  117. package/lib/cli/detector/ui-signals.mjs +0 -150
  118. package/lib/cli/detector/workspace-scan.mjs +0 -177
  119. package/lib/cli/detector.mjs +0 -23
  120. package/lib/cli/init-detection-flow.mjs +0 -48
  121. package/lib/cli/init-options.mjs +0 -237
  122. package/lib/cli/init-selection.mjs +0 -29
  123. package/lib/cli/memory-continuity.mjs +0 -537
  124. package/lib/cli/preflight.mjs +0 -76
  125. package/lib/cli/project-scaffolder/constants.mjs +0 -69
  126. package/lib/cli/project-scaffolder/discovery.mjs +0 -272
  127. package/lib/cli/project-scaffolder/prompt-builders.mjs +0 -171
  128. package/lib/cli/project-scaffolder/storage.mjs +0 -144
  129. package/lib/cli/project-scaffolder/ui-scope-detection.mjs +0 -36
  130. package/lib/cli/project-scaffolder.mjs +0 -29
  131. package/lib/cli/rollback.mjs +0 -66
  132. package/lib/cli/token-optimization.mjs +0 -486
  133. package/lib/cli/utils/filesystem.mjs +0 -81
  134. package/lib/cli/utils/managed-surface.mjs +0 -280
  135. package/lib/cli/utils/prompting.mjs +0 -44
  136. package/lib/cli/utils.mjs +0 -479
  137. package/mcp.json +0 -134
  138. package/scripts/adaptive-context/fixtures.mjs +0 -183
  139. package/scripts/adaptive-context-benchmark.mjs +0 -9
  140. package/scripts/ascx-runtime-token-saver-benchmark.mjs +0 -9
  141. package/scripts/audit-cache-layer-contract.mjs +0 -263
  142. package/scripts/audit-caching-scope-hygiene.mjs +0 -268
  143. package/scripts/audit-file-size.mjs +0 -219
  144. package/scripts/audit-reflection-citations.mjs +0 -163
  145. package/scripts/audit-release-bundle.mjs +0 -170
  146. package/scripts/audit-rule-id-uniqueness.mjs +0 -313
  147. package/scripts/audit-typography-palette-anti-repeat.mjs +0 -120
  148. package/scripts/benchmark-evidence-bundle.mjs +0 -645
  149. package/scripts/benchmark-gate.mjs +0 -121
  150. package/scripts/benchmark-intelligence.mjs +0 -33
  151. package/scripts/benchmark-writer-judge-matrix.mjs +0 -379
  152. package/scripts/build-release-benchmark-bundle.mjs +0 -202
  153. package/scripts/bump-version.mjs +0 -103
  154. package/scripts/clean-local-artifacts.mjs +0 -78
  155. package/scripts/compact-natural-mode-benchmark.mjs +0 -9
  156. package/scripts/context-triggered-audit.mjs +0 -391
  157. package/scripts/detection-benchmark.mjs +0 -127
  158. package/scripts/docs-quality-drift-report.mjs +0 -358
  159. package/scripts/documentation-boundary-audit.mjs +0 -305
  160. package/scripts/explain-on-demand-audit.mjs +0 -427
  161. package/scripts/forbidden-content-check.mjs +0 -123
  162. package/scripts/frontend-usability-audit.mjs +0 -243
  163. package/scripts/generate-sbom.mjs +0 -61
  164. package/scripts/governance-weekly-report.mjs +0 -466
  165. package/scripts/llm-judge/checklist-loader.mjs +0 -45
  166. package/scripts/llm-judge/constants.mjs +0 -66
  167. package/scripts/llm-judge/diff-collection.mjs +0 -74
  168. package/scripts/llm-judge/prompting.mjs +0 -78
  169. package/scripts/llm-judge/providers.mjs +0 -111
  170. package/scripts/llm-judge/verdict.mjs +0 -134
  171. package/scripts/llm-judge.mjs +0 -200
  172. package/scripts/memory-continuity-benchmark.mjs +0 -322
  173. package/scripts/quality-trend-report.mjs +0 -289
  174. package/scripts/release-gate/audit-checks.mjs +0 -441
  175. package/scripts/release-gate/constants.mjs +0 -53
  176. package/scripts/release-gate/runtime.mjs +0 -63
  177. package/scripts/release-gate/static-checks.mjs +0 -182
  178. package/scripts/release-gate.mjs +0 -42
  179. package/scripts/rules-guardian-audit.mjs +0 -580
  180. package/scripts/single-source-lazy-loading-audit.mjs +0 -449
  181. package/scripts/sync-thin-adapters.mjs +0 -72
  182. package/scripts/token-optimization-benchmark.mjs +0 -252
  183. package/scripts/ui-design-judge/constants.mjs +0 -13
  184. package/scripts/ui-design-judge/design-execution-summary.mjs +0 -81
  185. package/scripts/ui-design-judge/git-input.mjs +0 -134
  186. package/scripts/ui-design-judge/prompting.mjs +0 -52
  187. package/scripts/ui-design-judge/providers.mjs +0 -102
  188. package/scripts/ui-design-judge/reporting.mjs +0 -183
  189. package/scripts/ui-design-judge/rubric-calibration.mjs +0 -214
  190. package/scripts/ui-design-judge/rubric-goldset.json +0 -188
  191. package/scripts/ui-design-judge.mjs +0 -319
  192. package/scripts/ui-rubric-calibration.mjs +0 -35
  193. package/scripts/validate/config.mjs +0 -519
  194. package/scripts/validate/coverage-checks.mjs +0 -446
  195. package/scripts/validate/file-structure.mjs +0 -162
  196. package/scripts/validate/markdown-content.mjs +0 -109
  197. package/scripts/validate/project-metadata.mjs +0 -166
  198. package/scripts/validate.mjs +0 -338
@@ -1,66 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
- import { pathExists, ensureDirectory } from './utils.mjs';
4
- import { BACKUP_DIR_NAME } from './constants.mjs';
5
-
6
- /**
7
- * Performs a rollback of a target directory using the backup manifest.
8
- * @param {string} targetDirectoryPath
9
- */
10
- export async function performRollback(targetDirectoryPath) {
11
- const startTime = Date.now();
12
- const backupRoot = path.join(targetDirectoryPath, BACKUP_DIR_NAME);
13
- const manifestPath = path.join(backupRoot, 'manifest.json');
14
- const objectsDir = path.join(backupRoot, 'objects');
15
-
16
- if (!(await pathExists(manifestPath))) {
17
- throw new Error(`Rollback failed: Backup manifest not found at ${manifestPath}`);
18
- }
19
-
20
- const manifestData = JSON.parse(await fs.readFile(manifestPath, 'utf8'));
21
- const report = {
22
- restoredFiles: [],
23
- deletedFiles: [],
24
- errors: []
25
- };
26
-
27
- for (const [relativePath, fileManifest] of Object.entries(manifestData.files)) {
28
- const destinationPath = path.join(targetDirectoryPath, relativePath);
29
-
30
- if (fileManifest.action === 'restore') {
31
- const sourceObjectPath = path.join(objectsDir, fileManifest.hash);
32
- if (!(await pathExists(sourceObjectPath))) {
33
- report.errors.push(`Missing backup object for file: ${relativePath} (Expected hash: ${fileManifest.hash})`);
34
- continue;
35
- }
36
-
37
- try {
38
- await ensureDirectory(path.dirname(destinationPath));
39
- await fs.copyFile(sourceObjectPath, destinationPath);
40
- report.restoredFiles.push(relativePath);
41
- } catch (err) {
42
- report.errors.push(`Failed to restore ${relativePath}: ${err.message}`);
43
- }
44
- } else if (fileManifest.action === 'delete') {
45
- // File did not exist before, but might exist now
46
- if (await pathExists(destinationPath)) {
47
- try {
48
- const stats = await fs.stat(destinationPath);
49
- if (stats.isDirectory()) {
50
- await fs.rm(destinationPath, { recursive: true, force: true });
51
- } else {
52
- await fs.unlink(destinationPath);
53
- }
54
- report.deletedFiles.push(relativePath);
55
- } catch (err) {
56
- report.errors.push(`Failed to delete dynamically added file ${relativePath}: ${err.message}`);
57
- }
58
- }
59
- }
60
- }
61
-
62
- report.durationMs = Date.now() - startTime;
63
- report.success = report.errors.length === 0;
64
-
65
- return report;
66
- }
@@ -1,486 +0,0 @@
1
- import { existsSync } from 'node:fs';
2
- import fs from 'node:fs/promises';
3
- import path from 'node:path';
4
- import { spawnSync } from 'node:child_process';
5
- import { platform } from 'node:process';
6
-
7
- import { REPOSITORY_ROOT } from './constants.mjs';
8
- import { pathExists } from './utils.mjs';
9
-
10
- export const TOKEN_OPTIMIZATION_STATE_FILE_NAME = 'token-optimization.json';
11
- export const TOKEN_OPTIMIZATION_REPORT_FILE_NAME = 'token-optimization-report.json';
12
-
13
- const TOKEN_OPTIMIZATION_SCHEMA_VERSION = 'token-optimization-v1';
14
- const FALLBACK_AGENT_NAME = 'copilot';
15
-
16
- const SUPPORTED_AGENT_NAMES = new Set([
17
- 'copilot',
18
- 'claude',
19
- 'cursor',
20
- 'windsurf',
21
- 'gemini',
22
- 'codex',
23
- 'cline',
24
- ]);
25
-
26
- const COMMAND_REWRITE_MAPPINGS = [
27
- {
28
- rawCommand: 'ls -la',
29
- optimizedCommand: 'rtk ls .',
30
- reason: 'Directory listings are grouped and compacted before entering the model context.',
31
- },
32
- {
33
- rawCommand: 'tree',
34
- optimizedCommand: 'rtk ls .',
35
- reason: 'Large trees are summarized without losing high-signal structure.',
36
- },
37
- {
38
- rawCommand: 'cat file.ext',
39
- optimizedCommand: 'rtk read file.ext',
40
- reason: 'File reads keep signatures and relevant lines while trimming boilerplate.',
41
- },
42
- {
43
- rawCommand: 'rg pattern .',
44
- optimizedCommand: 'rtk grep "pattern" .',
45
- reason: 'Search hits are grouped and deduplicated for faster reasoning.',
46
- },
47
- {
48
- rawCommand: 'git status',
49
- optimizedCommand: 'ascx git status',
50
- reason: 'ASCX condenses status output while preserving changed-file evidence and raw tee safety.',
51
- },
52
- {
53
- rawCommand: 'git diff',
54
- optimizedCommand: 'ascx git diff',
55
- reason: 'ASCX preserves changed files, hunk anchors, binary/deleted markers, truncation notes, and raw tee safety.',
56
- },
57
- {
58
- rawCommand: 'git log -n 10',
59
- optimizedCommand: 'rtk git log -n 10',
60
- reason: 'History is converted to compact one-line summaries.',
61
- },
62
- {
63
- rawCommand: 'npm test',
64
- optimizedCommand: 'ascx npm test',
65
- reason: 'ASCX preserves exit code, failing tests, assertions, file paths, and raw tee safety.',
66
- },
67
- {
68
- rawCommand: 'npm run build',
69
- optimizedCommand: 'rtk err npm run build',
70
- reason: 'Build runs return errors and warnings only for quicker remediation.',
71
- },
72
- {
73
- rawCommand: 'tsc --noEmit',
74
- optimizedCommand: 'rtk tsc',
75
- reason: 'TypeScript diagnostics are grouped by file with less repetition.',
76
- },
77
- {
78
- rawCommand: 'eslint .',
79
- optimizedCommand: 'rtk lint',
80
- reason: 'Lint output is grouped by rule and location to reduce token churn.',
81
- },
82
- {
83
- rawCommand: 'docker ps',
84
- optimizedCommand: 'rtk docker ps',
85
- reason: 'Container state is summarized into compact rows.',
86
- },
87
- {
88
- rawCommand: 'kubectl get pods',
89
- optimizedCommand: 'rtk kubectl pods',
90
- reason: 'Kubernetes output is condensed and stable for agent consumption.',
91
- },
92
- ];
93
-
94
- const OUTPUT_FOLDING_STRATEGY = {
95
- mode: 'compact-high-signal-output',
96
- appliesTo: [
97
- 'shell-command-output',
98
- 'test-output',
99
- 'build-output',
100
- 'diff-output',
101
- 'log-output',
102
- ],
103
- preserveAlways: [
104
- 'exit-code',
105
- 'failing-command',
106
- 'file-and-line',
107
- 'error-message',
108
- 'actionable-warning',
109
- ],
110
- foldByDefault: [
111
- 'repeated-success-lines',
112
- 'large-unchanged-diff-context',
113
- 'verbose-install-progress',
114
- 'duplicated-stack-frames',
115
- 'low-signal-directory-noise',
116
- ],
117
- nativeFallback: [
118
- 'prefer --stat or --name-only before full diff',
119
- 'prefer focused rg queries before broad file dumps',
120
- 'prefer failure-focused test reporters when available',
121
- 'summarize long logs before hydrating full detail',
122
- ],
123
- safetyBoundary: [
124
- 'never hide failing checks',
125
- 'never drop the command that produced output',
126
- 'never persist secrets into summaries',
127
- 'hydrate full output only when the compact summary is insufficient',
128
- ],
129
- };
130
-
131
- function parseRtkVersion(versionOutput) {
132
- const versionMatch = versionOutput.match(/\d+\.\d+\.\d+/);
133
- return versionMatch ? versionMatch[0] : null;
134
- }
135
-
136
- export function normalizeAgentName(rawAgentName = FALLBACK_AGENT_NAME) {
137
- const normalizedAgentName = String(rawAgentName || '')
138
- .trim()
139
- .toLowerCase();
140
-
141
- if (!normalizedAgentName) {
142
- return FALLBACK_AGENT_NAME;
143
- }
144
-
145
- if (!SUPPORTED_AGENT_NAMES.has(normalizedAgentName)) {
146
- throw new Error(
147
- `Unsupported agent "${rawAgentName}". Supported values: ${Array.from(SUPPORTED_AGENT_NAMES).join(', ')}`
148
- );
149
- }
150
-
151
- return normalizedAgentName;
152
- }
153
-
154
- export function detectRtkBinary() {
155
- try {
156
- const versionResult = spawnSync('rtk', ['--version'], {
157
- encoding: 'utf8',
158
- stdio: ['ignore', 'pipe', 'pipe'],
159
- });
160
-
161
- if (versionResult.status !== 0) {
162
- return {
163
- isAvailable: false,
164
- version: null,
165
- detectionError: (versionResult.stderr || versionResult.stdout || 'Unknown external proxy detection error').trim(),
166
- };
167
- }
168
-
169
- const detectedVersion = parseRtkVersion(versionResult.stdout || '');
170
- return {
171
- isAvailable: true,
172
- version: detectedVersion,
173
- detectionError: null,
174
- };
175
- } catch (detectionError) {
176
- return {
177
- isAvailable: false,
178
- version: null,
179
- detectionError: detectionError instanceof Error ? detectionError.message : String(detectionError),
180
- };
181
- }
182
- }
183
-
184
- export function detectAscxRuntime() {
185
- const localBinPath = path.join(REPOSITORY_ROOT, 'bin', 'ascx.js');
186
- const pathDetection = spawnSync('ascx', [], {
187
- encoding: 'utf8',
188
- stdio: ['ignore', 'pipe', 'pipe'],
189
- });
190
- const pathBinaryLooksAvailable = pathDetection.error == null
191
- && typeof pathDetection.status === 'number'
192
- && /command is required/i.test(`${pathDetection.stdout || ''}\n${pathDetection.stderr || ''}`);
193
-
194
- if (pathBinaryLooksAvailable) {
195
- return {
196
- isAvailable: true,
197
- source: 'path',
198
- command: 'ascx',
199
- localBinPath,
200
- detectionError: null,
201
- };
202
- }
203
-
204
- if (existsSync(localBinPath)) {
205
- return {
206
- isAvailable: true,
207
- source: 'package-bin',
208
- command: `node ${localBinPath}`,
209
- localBinPath,
210
- detectionError: pathDetection.error ? pathDetection.error.message : null,
211
- };
212
- }
213
-
214
- return {
215
- isAvailable: false,
216
- source: 'missing',
217
- command: null,
218
- localBinPath,
219
- detectionError: pathDetection.error
220
- ? pathDetection.error.message
221
- : (pathDetection.stderr || pathDetection.stdout || 'ascx binary was not detected').trim(),
222
- };
223
- }
224
-
225
- export async function checkAscxTeeReadiness(targetDirectoryPath, options = {}) {
226
- const shouldWriteProbe = options.writeProbe === true;
227
- const stateDirectoryPath = path.join(targetDirectoryPath, '.agent-context', 'state');
228
- const teeDirectoryPath = path.join(stateDirectoryPath, 'token-saver', 'tee');
229
-
230
- try {
231
- if (shouldWriteProbe) {
232
- await fs.mkdir(teeDirectoryPath, { recursive: true });
233
- const probeFilePath = path.join(teeDirectoryPath, `.ascx-probe-${process.pid}.tmp`);
234
- await fs.writeFile(probeFilePath, 'ascx tee probe\n', 'utf8');
235
- await fs.rm(probeFilePath, { force: true });
236
- } else {
237
- await fs.access(stateDirectoryPath);
238
- }
239
-
240
- return {
241
- status: 'writable',
242
- path: teeDirectoryPath,
243
- error: null,
244
- };
245
- } catch (readinessError) {
246
- return {
247
- status: 'not-writable',
248
- path: teeDirectoryPath,
249
- error: readinessError instanceof Error ? readinessError.message : String(readinessError),
250
- };
251
- }
252
- }
253
-
254
- export function resolveRuntimeTokenSaverMode({
255
- tokenOptimizationState,
256
- ascxDetection,
257
- rtkDetection,
258
- }) {
259
- const stateEnabled = tokenOptimizationState?.enabled === true;
260
- const rtkDetected = rtkDetection?.isAvailable === true;
261
-
262
- if (stateEnabled && ascxDetection?.isAvailable && rtkDetected) {
263
- return 'conflict-risk';
264
- }
265
-
266
- if (stateEnabled && ascxDetection?.isAvailable) {
267
- return 'runtime-on';
268
- }
269
-
270
- if (stateEnabled) {
271
- return 'policy-only';
272
- }
273
-
274
- if (rtkDetected) {
275
- return 'external-runtime-detected';
276
- }
277
-
278
- return 'runtime-off';
279
- }
280
-
281
- export function buildRuntimeTokenSaverWarnings({
282
- mode,
283
- onboardingReport,
284
- ascxDetection,
285
- teeReadiness,
286
- rtkDetection,
287
- }) {
288
- const warnings = [];
289
-
290
- if (!onboardingReport) {
291
- warnings.push('project is not initialized; run init before enabling runtime token saving');
292
- }
293
-
294
- if (!ascxDetection?.isAvailable) {
295
- warnings.push('ascx binary is missing; supported commands will not be compressed');
296
- }
297
-
298
- if (teeReadiness?.status !== 'writable') {
299
- warnings.push('raw tee folder is not writable; failing commands may lose safety logs');
300
- }
301
-
302
- if (mode === 'conflict-risk') {
303
- warnings.push('ASCX and an external runtime compressor both appear active; avoid double compression');
304
- } else if (rtkDetection?.isAvailable) {
305
- warnings.push('external runtime compressor detected; keep only one runtime compressor enabled by default');
306
- }
307
-
308
- return warnings;
309
- }
310
-
311
- export function buildRuntimeTokenSaverNextAction({ mode, warnings }) {
312
- if (warnings.some((warning) => warning.includes('not initialized'))) {
313
- return 'Run agentic-senior-core init before enabling ASCX runtime saving.';
314
- }
315
-
316
- if (warnings.some((warning) => warning.includes('tee folder'))) {
317
- return 'Fix .agent-context/state write access, then rerun optimize doctor.';
318
- }
319
-
320
- if (mode === 'conflict-risk') {
321
- return 'Disable either ASCX runtime saving or the external compressor before using compressed command output.';
322
- }
323
-
324
- if (mode === 'runtime-on') {
325
- return 'Use ascx git status, ascx git diff, and ascx npm test for supported high-volume command output.';
326
- }
327
-
328
- if (mode === 'policy-only') {
329
- return 'Install or expose the ascx binary, then rerun optimize doctor.';
330
- }
331
-
332
- return 'Run agentic-senior-core optimize install to enable ASCX guidance for this repository.';
333
- }
334
-
335
- export function buildRtkInstallHint() {
336
- if (platform === 'win32') {
337
- return 'Install the external token optimizer binary for Windows, extract it, and ensure the executable is on PATH.';
338
- }
339
-
340
- if (platform === 'darwin') {
341
- return 'Install the external token optimizer with Homebrew, then verify the executable is available in your shell.';
342
- }
343
-
344
- return 'Install the external token optimizer with the vendor installer, then verify it is available in your shell PATH.';
345
- }
346
-
347
- export function buildRtkHookCommand(selectedAgentName) {
348
- const normalizedAgentName = normalizeAgentName(selectedAgentName);
349
-
350
- if (normalizedAgentName === 'copilot') {
351
- return 'rtk init -g --copilot';
352
- }
353
-
354
- if (normalizedAgentName === 'claude') {
355
- return 'rtk init -g';
356
- }
357
-
358
- if (normalizedAgentName === 'cursor') {
359
- return 'rtk init -g --agent cursor';
360
- }
361
-
362
- if (normalizedAgentName === 'windsurf') {
363
- return 'rtk init --agent windsurf';
364
- }
365
-
366
- if (normalizedAgentName === 'gemini') {
367
- return 'rtk init -g --gemini';
368
- }
369
-
370
- if (normalizedAgentName === 'codex') {
371
- return 'rtk init -g --codex';
372
- }
373
-
374
- if (normalizedAgentName === 'cline') {
375
- return 'rtk init --agent cline';
376
- }
377
-
378
- return 'rtk init -g --copilot';
379
- }
380
-
381
- export function createTokenOptimizationState({
382
- isEnabled,
383
- selectedAgentName,
384
- rtkDetection,
385
- }) {
386
- return {
387
- schemaVersion: TOKEN_OPTIMIZATION_SCHEMA_VERSION,
388
- enabled: Boolean(isEnabled),
389
- selectedAgent: normalizeAgentName(selectedAgentName),
390
- preferredShellProxy: rtkDetection.isAvailable ? 'external-proxy' : 'native-fallback',
391
- externalProxy: {
392
- detected: Boolean(rtkDetection.isAvailable),
393
- version: rtkDetection.version,
394
- detectionError: rtkDetection.detectionError,
395
- },
396
- commandRewriteMappings: COMMAND_REWRITE_MAPPINGS.map((mapping) => ({ ...mapping })),
397
- outputFoldingStrategy: {
398
- ...OUTPUT_FOLDING_STRATEGY,
399
- appliesTo: [...OUTPUT_FOLDING_STRATEGY.appliesTo],
400
- preserveAlways: [...OUTPUT_FOLDING_STRATEGY.preserveAlways],
401
- foldByDefault: [...OUTPUT_FOLDING_STRATEGY.foldByDefault],
402
- nativeFallback: [...OUTPUT_FOLDING_STRATEGY.nativeFallback],
403
- safetyBoundary: [...OUTPUT_FOLDING_STRATEGY.safetyBoundary],
404
- },
405
- generatedAt: new Date().toISOString(),
406
- };
407
- }
408
-
409
- export async function readTokenOptimizationState(targetDirectoryPath) {
410
- const stateFilePath = path.join(
411
- targetDirectoryPath,
412
- '.agent-context',
413
- 'state',
414
- TOKEN_OPTIMIZATION_STATE_FILE_NAME
415
- );
416
-
417
- if (!(await pathExists(stateFilePath))) {
418
- return null;
419
- }
420
-
421
- try {
422
- const stateContent = await fs.readFile(stateFilePath, 'utf8');
423
- const parsedState = JSON.parse(stateContent);
424
- if (typeof parsedState.enabled !== 'boolean') {
425
- return null;
426
- }
427
- return parsedState;
428
- } catch {
429
- return null;
430
- }
431
- }
432
-
433
- export async function writeTokenOptimizationState(targetDirectoryPath, tokenOptimizationState) {
434
- const stateDirectoryPath = path.join(targetDirectoryPath, '.agent-context', 'state');
435
- const stateFilePath = path.join(stateDirectoryPath, TOKEN_OPTIMIZATION_STATE_FILE_NAME);
436
-
437
- await fs.mkdir(stateDirectoryPath, { recursive: true });
438
- await fs.writeFile(stateFilePath, JSON.stringify(tokenOptimizationState, null, 2) + '\n', 'utf8');
439
- }
440
-
441
- export function buildTokenOptimizationGuidanceBlock(tokenOptimizationState) {
442
- if (!tokenOptimizationState?.enabled) {
443
- return [
444
- 'Token optimization mode is disabled for this repository.',
445
- 'Use native shell commands with manual output limiting when needed.',
446
- ].join('\n');
447
- }
448
-
449
- const rewriteLines = (tokenOptimizationState.commandRewriteMappings || []).map(
450
- (mapping) => `- ${mapping.rawCommand} => ${mapping.optimizedCommand} (${mapping.reason})`
451
- );
452
-
453
- const fallbackGuidance = [
454
- '- Use ascx git status, ascx git diff, and ascx npm test when the ascx binary is available.',
455
- '- Use command variants with bounded output such as git diff --stat, rg --max-count, and npm test -- --reporter=dot.',
456
- '- Request only the lines or sections required for the current decision.',
457
- '- If shell output is still large, summarize and continue iteratively instead of dumping full logs.',
458
- ];
459
-
460
- const outputFoldingStrategy = tokenOptimizationState.outputFoldingStrategy || OUTPUT_FOLDING_STRATEGY;
461
- const outputFoldingLines = [
462
- `- Mode: ${outputFoldingStrategy.mode || OUTPUT_FOLDING_STRATEGY.mode}.`,
463
- `- Preserve always: ${(outputFoldingStrategy.preserveAlways || OUTPUT_FOLDING_STRATEGY.preserveAlways).join(', ')}.`,
464
- `- Fold by default: ${(outputFoldingStrategy.foldByDefault || OUTPUT_FOLDING_STRATEGY.foldByDefault).join(', ')}.`,
465
- `- Safety boundary: ${(outputFoldingStrategy.safetyBoundary || OUTPUT_FOLDING_STRATEGY.safetyBoundary).join(', ')}.`,
466
- ];
467
-
468
- return [
469
- `Token optimization mode is enabled for agent: ${tokenOptimizationState.selectedAgent}.`,
470
- `Preferred shell proxy: ${tokenOptimizationState.preferredShellProxy}.`,
471
- '',
472
- 'Apply command rewrites before running verbose shell commands:',
473
- ...rewriteLines,
474
- '',
475
- 'Important scope note:',
476
- '- ASCX wrappers are explicit local command wrappers, not provider gateways.',
477
- '- Shell rewrite hooks affect shell tool calls only.',
478
- '- Built-in read/grep/glob style tools may bypass shell rewrites, so explicit compact shell commands should be preferred in high-volume sessions.',
479
- '',
480
- 'Output folding policy:',
481
- ...outputFoldingLines,
482
- '',
483
- 'Fallback behavior when external proxy is unavailable:',
484
- ...fallbackGuidance,
485
- ].join('\n');
486
- }
@@ -1,81 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
-
4
- export async function pathExists(targetPath) {
5
- try {
6
- await fs.stat(targetPath);
7
- return true;
8
- } catch {
9
- return false;
10
- }
11
- }
12
-
13
- export async function ensureDirectory(directoryPath) {
14
- await fs.mkdir(directoryPath, { recursive: true });
15
- }
16
-
17
- export async function copyDirectory(sourceDirectoryPath, targetDirectoryPath) {
18
- if (path.resolve(sourceDirectoryPath) === path.resolve(targetDirectoryPath)) {
19
- return;
20
- }
21
-
22
- await ensureDirectory(targetDirectoryPath);
23
- const directoryEntries = await fs.readdir(sourceDirectoryPath, { withFileTypes: true });
24
-
25
- for (const directoryEntry of directoryEntries) {
26
- const sourceEntryPath = path.join(sourceDirectoryPath, directoryEntry.name);
27
- const targetEntryPath = path.join(targetDirectoryPath, directoryEntry.name);
28
-
29
- if (directoryEntry.isDirectory()) {
30
- await copyDirectory(sourceEntryPath, targetEntryPath);
31
- continue;
32
- }
33
-
34
- if (path.resolve(sourceEntryPath) === path.resolve(targetEntryPath)) {
35
- continue;
36
- }
37
-
38
- await fs.copyFile(sourceEntryPath, targetEntryPath);
39
- }
40
- }
41
-
42
- export function isAgenticManagedContent(content) {
43
- const normalizedContent = Buffer.isBuffer(content)
44
- ? content.toString('utf8')
45
- : String(content || '');
46
-
47
- return [
48
- 'Agentic-Senior-Core',
49
- 'AGENTIC-SENIOR-CORE',
50
- 'Adapter Mode: thin',
51
- 'Adapter Mode: legacy-thin',
52
- 'Canonical Snapshot SHA256',
53
- 'Canonical baseline: .instructions.md',
54
- 'canonical instruction source for this repository',
55
- '@AGENTS.md',
56
- ].some((managedSignal) => normalizedContent.includes(managedSignal));
57
- }
58
-
59
- export async function syncFile(sourcePath, targetPath, options = {}) {
60
- if (!(await pathExists(sourcePath))) return { status: 'skipped' };
61
-
62
- if (!(await pathExists(targetPath))) {
63
- await ensureDirectory(path.dirname(targetPath));
64
- await fs.copyFile(sourcePath, targetPath);
65
- return { status: 'created' };
66
- }
67
-
68
- const sourceContent = await fs.readFile(sourcePath);
69
- const targetContent = await fs.readFile(targetPath);
70
-
71
- if (sourceContent.equals(targetContent)) {
72
- return { status: 'unchanged' };
73
- }
74
-
75
- if (options.preserveUserOwned === true && !isAgenticManagedContent(targetContent)) {
76
- return { status: 'preserved' };
77
- }
78
-
79
- await fs.copyFile(sourcePath, targetPath);
80
- return { status: 'updated' };
81
- }