@ryuenn3123/agentic-senior-core 5.9.0 → 6.0.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.
@@ -0,0 +1 @@
1
+ Run the duplicate code audit from skills/asc-dedup/SKILL.md. Scan the specified scope (directory, package, or full repo) for near-duplicate code blocks using jscpd token-level clone detection. Report clusters ranked by duplicated lines, and suggest consolidation only for patterns appearing 3+ times (Rule of Three).
@@ -0,0 +1,2 @@
1
+ description = "On-demand duplicate code audit using token-level clone detection"
2
+ prompt = "Load and follow the asc-dedup skill. Scan the current project (or specified scope) for near-duplicate code blocks using jscpd. Report clusters ranked by duplicated lines. Suggest consolidation only for patterns appearing 3+ times per the Rule of Three."
@@ -0,0 +1,21 @@
1
+ // Agentic Senior Core — shared constants for hook modules
2
+ // Single source of truth for thresholds and extension sets used by
3
+ // post-edit-enforce.js and dedup-gate.js.
4
+
5
+ const SOURCE_EXTENSIONS = new Set([
6
+ 'js', 'ts', 'mjs', 'cjs', 'jsx', 'tsx',
7
+ 'py', 'rb', 'go', 'rs', 'java', 'kt', 'swift', 'cs',
8
+ ]);
9
+
10
+ const LOC_DELTA_THRESHOLD = 30;
11
+ const NEW_FILE_LINE_THRESHOLD = 50;
12
+ const SESSION_DRIFT_THRESHOLD = 4;
13
+ const LADDER_PULSE_INTERVAL = 3;
14
+
15
+ module.exports = {
16
+ SOURCE_EXTENSIONS,
17
+ LOC_DELTA_THRESHOLD,
18
+ NEW_FILE_LINE_THRESHOLD,
19
+ SESSION_DRIFT_THRESHOLD,
20
+ LADDER_PULSE_INTERVAL,
21
+ };
@@ -0,0 +1,283 @@
1
+ #!/usr/bin/env node
2
+ // Agentic Senior Core — PostToolUse duplicate-code detection hook
3
+ // Fires after Edit/Write on qualifying source files. Runs a scoped jscpd scan
4
+ // to detect near-duplicate code blocks. Advisory by default; configurable to block.
5
+ // Supports Claude Code, Codex CLI, GitHub Copilot CLI, and Antigravity IDE.
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const os = require('os');
10
+ const { execSync } = require('child_process');
11
+
12
+ const {
13
+ SOURCE_EXTENSIONS,
14
+ LOC_DELTA_THRESHOLD,
15
+ NEW_FILE_LINE_THRESHOLD,
16
+ } = require('./constants.cjs');
17
+
18
+ const JSCPD_TIMEOUT_MS = 10000;
19
+
20
+ // Recognized source root directories — scan scope walks up to the first match
21
+ const SOURCE_ROOTS = ['src', 'lib', 'app'];
22
+
23
+ let inputBuffer = '';
24
+ process.stdin.setEncoding('utf8');
25
+ process.stdin.on('data', chunk => {
26
+ inputBuffer += chunk;
27
+ try {
28
+ const data = JSON.parse(inputBuffer);
29
+
30
+ let toolName = '';
31
+ let toolInput = {};
32
+ let isAntigravity = false;
33
+
34
+ if (data.toolCall) {
35
+ // Antigravity PreToolUse shape (has toolCall directly)
36
+ isAntigravity = true;
37
+ toolName = data.toolCall.name;
38
+ toolInput = data.toolCall.args || {};
39
+ } else if (data.stepIdx !== undefined && data.transcriptPath) {
40
+ // Antigravity PostToolUse shape — no toolCall in payload,
41
+ // read the tool call details from the transcript at stepIdx
42
+ isAntigravity = true;
43
+ var extracted = extractToolCallFromTranscript(data.transcriptPath, data.stepIdx);
44
+ if (!extracted) { process.exit(0); return; }
45
+ toolName = extracted.toolName;
46
+ toolInput = extracted.toolInput;
47
+ } else {
48
+ // Claude Code / Codex / Copilot path
49
+ toolName = data.tool_name || data.toolName || '';
50
+ toolInput = data.tool_input || data.toolInput || {};
51
+ }
52
+
53
+ const filePath = toolInput.file_path || toolInput.TargetFile || toolInput.path || toolInput.target_file || '';
54
+ if (!filePath) { process.exit(0); return; }
55
+
56
+ const ext = path.extname(filePath).slice(1);
57
+ if (!SOURCE_EXTENSIONS.has(ext)) { process.exit(0); return; }
58
+
59
+ if (!isQualifyingEdit(toolName, toolInput)) { process.exit(0); return; }
60
+
61
+ const config = loadDedupConfig();
62
+ const scanDir = resolveScanDir(filePath, config);
63
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'asc-dedup-'));
64
+
65
+ const ignoreFlags = (config.ignoreDirs || []).map(function (d) { return '--ignore "' + d + '"'; }).join(' ');
66
+ const minTokens = config.minTokens || 30;
67
+ const scanCmd = ' "' + scanDir + '" --min-tokens ' + minTokens
68
+ + ' --reporters json --silent --output "' + tmpDir + '" ' + ignoreFlags;
69
+
70
+ const report = runJscpdScan(scanCmd, tmpDir);
71
+ if (!report) { cleanup(tmpDir); process.exit(0); return; }
72
+
73
+ const finding = checkForDuplicates(report, filePath);
74
+ if (!finding) { cleanup(tmpDir); process.exit(0); return; }
75
+
76
+ const nudge = '[ASC Dedup] ' + path.basename(filePath) + ' looks similar to '
77
+ + finding.matchedFile + ' (' + finding.percent + '% overlap, '
78
+ + finding.lines + ' lines). Ladder step 2: does the codebase already have this? '
79
+ + 'Reuse it, or confirm this is intentional.';
80
+
81
+ if (config.mode === 'block') {
82
+ emitDeny(nudge, isAntigravity);
83
+ } else {
84
+ emitAdvisory(nudge, isAntigravity);
85
+ }
86
+
87
+ cleanup(tmpDir);
88
+ process.exit(0);
89
+ } catch (e) {
90
+ // incomplete json, wait for more chunks
91
+ }
92
+ });
93
+
94
+ // Extract tool call details from the Antigravity transcript at a given step index.
95
+ // PostToolUse on Antigravity only provides stepIdx — the actual tool call args
96
+ // must be recovered from the transcript log. Same approach as post-edit-enforce.js.
97
+ function extractToolCallFromTranscript(transcriptPath, stepIdx) {
98
+ try {
99
+ if (!fs.existsSync(transcriptPath)) return null;
100
+ var lines = fs.readFileSync(transcriptPath, 'utf8').split('\n').filter(Boolean);
101
+
102
+ // Find the step with matching step_index that contains tool_calls
103
+ for (var i = lines.length - 1; i >= 0; i--) {
104
+ var step = JSON.parse(lines[i]);
105
+ if (step.step_index !== stepIdx || !step.tool_calls) continue;
106
+
107
+ for (var j = 0; j < step.tool_calls.length; j++) {
108
+ var tc = step.tool_calls[j];
109
+ if (tc.name === 'replace_file_content' || tc.name === 'multi_replace_file_content') {
110
+ return {
111
+ toolName: 'Edit',
112
+ toolInput: {
113
+ file_path: tc.args.TargetFile || '',
114
+ new_string: tc.args.ReplacementContent || '',
115
+ old_string: tc.args.TargetContent || '',
116
+ },
117
+ };
118
+ } else if (tc.name === 'write_to_file') {
119
+ return {
120
+ toolName: 'Write',
121
+ toolInput: {
122
+ file_path: tc.args.TargetFile || '',
123
+ content: tc.args.CodeContent || '',
124
+ },
125
+ };
126
+ }
127
+ }
128
+ }
129
+ return null;
130
+ } catch (_) {
131
+ return null;
132
+ }
133
+ }
134
+
135
+ function isQualifyingEdit(toolName, toolInput) {
136
+ var isWrite = ['Write', 'write_to_file', 'write_file'].indexOf(toolName) !== -1;
137
+ var isEdit = ['Edit', 'replace_file_content', 'multi_replace_file_content'].indexOf(toolName) !== -1;
138
+
139
+ if (isWrite) {
140
+ var content = toolInput.content || toolInput.CodeContent || '';
141
+ return content.split('\n').length > NEW_FILE_LINE_THRESHOLD;
142
+ }
143
+ if (isEdit) {
144
+ var newStr = toolInput.new_string || toolInput.ReplacementContent || toolInput.content || '';
145
+ var oldStr = toolInput.old_string || toolInput.TargetContent || '';
146
+ var delta = newStr.split('\n').length - oldStr.split('\n').length;
147
+ return delta > LOC_DELTA_THRESHOLD;
148
+ }
149
+ return false;
150
+ }
151
+
152
+ function resolveScanDir(filePath, config) {
153
+ var cwd = process.cwd();
154
+
155
+ // User override takes priority
156
+ if (config.scanRoot) {
157
+ var override = path.resolve(cwd, config.scanRoot);
158
+ if (fs.existsSync(override)) return override;
159
+ }
160
+
161
+ // Walk up from the file's directory to find a recognized source root
162
+ var dir = path.dirname(path.resolve(filePath));
163
+ while (dir.length >= cwd.length) {
164
+ var basename = path.basename(dir);
165
+ if (SOURCE_ROOTS.indexOf(basename) !== -1) return dir;
166
+ var parent = path.dirname(dir);
167
+ if (parent === dir) break;
168
+ dir = parent;
169
+ }
170
+
171
+ // Fallback: project root
172
+ return cwd;
173
+ }
174
+
175
+ function loadDedupConfig() {
176
+ var candidates = [
177
+ path.join(process.cwd(), '.asc', 'dedup-config.json'),
178
+ path.join(process.cwd(), '.agents', 'dedup-config.json'),
179
+ ];
180
+ for (var i = 0; i < candidates.length; i++) {
181
+ try {
182
+ if (fs.existsSync(candidates[i])) {
183
+ return JSON.parse(fs.readFileSync(candidates[i], 'utf8'));
184
+ }
185
+ } catch (_) {}
186
+ }
187
+ return { mode: 'advisory', minTokens: 30, ignoreDirs: ['tests', 'migrations', 'generated', 'node_modules'] };
188
+ }
189
+
190
+ // minimal: attempt-then-fallback — try scan directly, fall back on failure.
191
+ // No separate --version probes. Upgrade if jscpd provides a stable JS API.
192
+ function runJscpdScan(scanCmd, tmpDir) {
193
+ var binaries = ['bunx jscpd', 'npx jscpd@5', 'npx jscpd'];
194
+ for (var i = 0; i < binaries.length; i++) {
195
+ try {
196
+ execSync(binaries[i] + scanCmd, {
197
+ timeout: JSCPD_TIMEOUT_MS,
198
+ stdio: 'pipe',
199
+ cwd: process.cwd(),
200
+ });
201
+ return loadReport(tmpDir);
202
+ } catch (_) {
203
+ // Try next binary
204
+ }
205
+ }
206
+ return null;
207
+ }
208
+
209
+ function loadReport(tmpDir) {
210
+ var reportPath = path.join(tmpDir, 'jscpd-report.json');
211
+ if (!fs.existsSync(reportPath)) return null;
212
+ try {
213
+ return JSON.parse(fs.readFileSync(reportPath, 'utf8'));
214
+ } catch (_) {
215
+ return null;
216
+ }
217
+ }
218
+
219
+ function checkForDuplicates(report, filePath) {
220
+ var duplicates = report.duplicates || [];
221
+ if (duplicates.length === 0) return null;
222
+
223
+ var normalizedTarget = path.resolve(filePath).replace(/\\/g, '/').toLowerCase();
224
+
225
+ for (var i = 0; i < duplicates.length; i++) {
226
+ var dup = duplicates[i];
227
+ var firstName = path.resolve(dup.firstFile.name).replace(/\\/g, '/').toLowerCase();
228
+ var secondName = path.resolve(dup.secondFile.name).replace(/\\/g, '/').toLowerCase();
229
+
230
+ if (firstName === normalizedTarget || secondName === normalizedTarget) {
231
+ var matchedFile = firstName === normalizedTarget
232
+ ? path.basename(dup.secondFile.name)
233
+ : path.basename(dup.firstFile.name);
234
+ var lines = dup.lines || 0;
235
+ // jscpd v5 reports fragments; estimate overlap percentage from line count
236
+ var totalLines = (report.statistics && report.statistics.total && report.statistics.total.lines) || 1;
237
+ var percent = Math.round((lines / totalLines) * 100);
238
+ return { matchedFile: matchedFile, lines: lines, percent: percent };
239
+ }
240
+ }
241
+ return null;
242
+ }
243
+
244
+ function emitAdvisory(nudge, isAntigravity) {
245
+ if (isAntigravity) {
246
+ process.stdout.write(JSON.stringify({
247
+ injectSteps: [{ ephemeralMessage: nudge }],
248
+ }) + '\n');
249
+ } else {
250
+ var isCopilot = Boolean(process.env.COPILOT_PLUGIN_DATA);
251
+ if (isCopilot) {
252
+ process.stdout.write(JSON.stringify({ additionalContext: nudge }) + '\n');
253
+ } else {
254
+ process.stdout.write(JSON.stringify({
255
+ hookSpecificOutput: {
256
+ hookEventName: 'PostToolUse',
257
+ additionalContext: nudge,
258
+ },
259
+ }) + '\n');
260
+ }
261
+ }
262
+ }
263
+
264
+ function emitDeny(reason, isAntigravity) {
265
+ if (isAntigravity) {
266
+ process.stdout.write(JSON.stringify({ decision: 'deny', reason: reason }) + '\n');
267
+ } else {
268
+ process.stdout.write(JSON.stringify({
269
+ allow_tool: false,
270
+ deny_reason: reason,
271
+ hookSpecificOutput: {
272
+ hookEventName: 'PostToolUse',
273
+ permissionDecision: 'deny',
274
+ permissionDecisionReason: reason,
275
+ },
276
+ }) + '\n');
277
+ }
278
+ process.exit(2);
279
+ }
280
+
281
+ function cleanup(tmpDir) {
282
+ try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch (_) {}
283
+ }
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ // Agentic Senior Core — PreInvocation ladder persistence hook
3
+ // Counters context rot by re-injecting a short decision-ladder reminder
4
+ // periodically, late in context, rather than relying only on rules/ content
5
+ // that sits at the start of the conversation.
6
+ // Antigravity-only: PreInvocation fires before every model call with
7
+ // invocationNum in the input payload. For other hosts, the equivalent
8
+ // pulse is integrated into post-edit-enforce.js via the sourceEditCount counter.
9
+
10
+ const { LADDER_PULSE_INTERVAL } = require('./constants.cjs');
11
+
12
+ const LADDER_REMINDER = '[ASC] Ladder check: (1) needed? (2) exists already \u2014 reuse? '
13
+ + '(3) stdlib/native? (4) existing dep? (5) one function? Then minimal code.';
14
+
15
+ let inputBuffer = '';
16
+ process.stdin.setEncoding('utf8');
17
+ process.stdin.on('data', chunk => {
18
+ inputBuffer += chunk;
19
+ try {
20
+ const payload = JSON.parse(inputBuffer);
21
+
22
+ let shouldInject = false;
23
+ const invNum = payload.invocationNum || 0;
24
+ if (invNum > 0 && invNum % LADDER_PULSE_INTERVAL === 0) {
25
+ shouldInject = true;
26
+ }
27
+
28
+ if (shouldInject) {
29
+ process.stdout.write(JSON.stringify({
30
+ injectSteps: [{
31
+ ephemeralMessage: `**ASC LADDER PULSE**: You have completed several steps. Remember to review the 1-6 decision ladder. Document deferred debt if you take shortcuts.`
32
+ }]
33
+ }) + '\n');
34
+ } else {
35
+ process.stdout.write('{}\n');
36
+ }
37
+ process.exit(0);
38
+ } catch (e) {
39
+ // wait for more chunks
40
+ }
41
+ });
@@ -37,22 +37,21 @@ try {
37
37
  }
38
38
  } catch (_) {}
39
39
 
40
- const SOURCE_EXTENSIONS = new Set([
41
- 'js', 'ts', 'mjs', 'cjs', 'jsx', 'tsx',
42
- 'py', 'rb', 'go', 'rs', 'java', 'kt', 'swift', 'cs',
43
- ]);
44
-
45
- const LOC_DELTA_THRESHOLD = 30;
46
- const NEW_FILE_LINE_THRESHOLD = 50;
47
- const SESSION_DRIFT_THRESHOLD = 4;
40
+ const {
41
+ SOURCE_EXTENSIONS,
42
+ LOC_DELTA_THRESHOLD,
43
+ NEW_FILE_LINE_THRESHOLD,
44
+ SESSION_DRIFT_THRESHOLD,
45
+ LADDER_PULSE_INTERVAL,
46
+ } = require('./constants.cjs');
48
47
 
49
48
  // Module-level counter for Claude Code path (resets per process spawn)
50
49
  let sourceEditCount = 0;
51
50
 
52
51
  let inputBuffer = '';
53
52
  process.stdin.setEncoding('utf8');
54
- process.stdin.on('data', function (chunk) { inputBuffer += chunk; });
55
- process.stdin.on('end', function () {
53
+ process.stdin.on('data', chunk => {
54
+ inputBuffer += chunk;
56
55
  try {
57
56
  const data = JSON.parse(inputBuffer);
58
57
 
@@ -66,8 +65,9 @@ process.stdin.on('end', function () {
66
65
  processSingleEdit(toolName, toolInput, function(nudge) {
67
66
  emitClaude(nudge);
68
67
  });
69
- } catch (_) {
70
- // Silent fail
68
+ process.exit(0);
69
+ } catch (e) {
70
+ // incomplete json, wait for more chunks
71
71
  }
72
72
  });
73
73
 
@@ -146,6 +146,9 @@ function processSingleEdit(toolName, toolInput, emitFn, skipArray) {
146
146
  findings.push('[ASC Session Drift] ' + SESSION_DRIFT_THRESHOLD + '+ source file edits this session. '
147
147
  + 'Re-read the decision ladder before continuing: (1) Does this need to be built? '
148
148
  + '(2) Does the codebase already have this? (3) Stdlib/native? (4) Existing dependency?');
149
+ } else if (sourceEditCount > 0 && sourceEditCount % LADDER_PULSE_INTERVAL === 0) {
150
+ findings.push('[ASC] Ladder check: (1) needed? (2) exists already \u2014 reuse? '
151
+ + '(3) stdlib/native? (4) existing dep? (5) one function? Then minimal code.');
149
152
  }
150
153
  }
151
154
 
@@ -243,9 +246,11 @@ function checkLocDelta(toolInput, filePath, findings) {
243
246
  function checkNewFileSize(toolInput, filePath, findings) {
244
247
  var lines = (toolInput.content || '').split('\n').length;
245
248
  if (lines > NEW_FILE_LINE_THRESHOLD) {
249
+ // Step 1-2 coverage ("does this already exist?") moved to dedup-gate.js
250
+ // which provides concrete file-name + overlap-percentage feedback.
246
251
  findings.push(
247
252
  'New file ' + path.basename(filePath) + ' created with ' + lines + ' lines. '
248
- + 'Ladder step 1-2: does this need to be built? Does the codebase already have this?'
253
+ + 'Ladder step 5: can this be one straightforward function?'
249
254
  );
250
255
  }
251
256
  }
@@ -23,8 +23,8 @@ try {
23
23
 
24
24
  let inputBuffer = '';
25
25
  process.stdin.setEncoding('utf8');
26
- process.stdin.on('data', function (chunk) { inputBuffer += chunk; });
27
- process.stdin.on('end', function () {
26
+ process.stdin.on('data', chunk => {
27
+ inputBuffer += chunk;
28
28
  try {
29
29
  const data = JSON.parse(inputBuffer);
30
30
  const isAntigravity = !!data.toolCall;
@@ -117,10 +117,10 @@ process.stdin.on('end', function () {
117
117
  process.exit(2);
118
118
  return;
119
119
  }
120
- } catch (_) {
121
- // Silent fail to ensure session stability
120
+ process.exit(0);
121
+ } catch (e) {
122
+ // incomplete json, wait for more chunks
122
123
  }
123
- process.exit(0);
124
124
  });
125
125
 
126
126
  function isGitCommitOrPush(command) {
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+ // Agentic Senior Core — PreInvocation session pulse hook (Antigravity-specific)
3
+ // Antigravity has no SessionStart event. This fires on the FIRST model call
4
+ // (invocationNum === 0) to inject AGENTS.md into the conversation — the same
5
+ // role session-start.js fills for Claude Code / Codex / Copilot via their
6
+ // real SessionStart hook.
7
+ // Does NOT replace session-start.js — that file still serves other hosts.
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+
12
+ const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || path.resolve(__dirname, '..');
13
+
14
+ let inputBuffer = '';
15
+ process.stdin.setEncoding('utf8');
16
+ process.stdin.on('data', chunk => {
17
+ inputBuffer += chunk;
18
+ try {
19
+ const data = JSON.parse(inputBuffer);
20
+
21
+ // Only fire on the very first model call of the session
22
+ if (data.invocationNum !== 0) {
23
+ process.stdout.write(JSON.stringify({}) + '\n');
24
+ process.exit(0);
25
+ return;
26
+ }
27
+
28
+ const agentsPath = path.join(pluginRoot, 'rules', 'agentic-senior-core.md');
29
+ let content;
30
+ try {
31
+ content = fs.readFileSync(agentsPath, 'utf8');
32
+ } catch (_) {
33
+ // Fallback to AGENTS.md at plugin root
34
+ content = fs.readFileSync(path.join(pluginRoot, 'AGENTS.md'), 'utf8');
35
+ }
36
+
37
+ process.stdout.write(JSON.stringify({
38
+ injectSteps: [{ ephemeralMessage: content }],
39
+ }) + '\n');
40
+ process.exit(0);
41
+ } catch (e) {
42
+ // wait for more chunks
43
+ }
44
+ });
@@ -74,14 +74,31 @@
74
74
  "statusMessage": "ASC ladder & spec gate check..."
75
75
  },
76
76
  {
77
- "type": "prompt",
78
- "if": "Edit(**/package.json)",
79
- "prompt": "A new dependency '$ARGUMENTS' was added to package.json. Does it duplicate Node.js standard library or platform features? If yes, return JSON: {\"hookSpecificOutput\": {\"hookEventName\": \"PostToolUse\", \"additionalContext\": \"[ASC Advisory] The newly added dependency appears to duplicate stdlib or platform features. Consider native alternatives.\"}}. If no, return {}.",
80
- "timeout": 30
77
+ "type": "command",
78
+ "command": "node -e \"const p=require('path'),fs=require('fs'),os=require('os');const local=p.join(process.cwd(),'.agents','plugins','agentic-senior-core','hooks','dedup-gate.js');const global=p.join(os.homedir(),'.gemini','config','plugins','agentic-senior-core','hooks','dedup-gate.js');require(fs.existsSync(local)?local:global);\"",
79
+ "commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { $root = if ($env:CLAUDE_PLUGIN_ROOT) { $env:CLAUDE_PLUGIN_ROOT } else { \"$env:USERPROFILE\\.gemini\\config\\plugins\\agentic-senior-core\" }; node \"$root\\hooks\\dedup-gate.js\" }",
80
+ "timeout": 15,
81
+ "statusMessage": "ASC duplicate-code scan..."
81
82
  }
82
83
  ]
83
84
  }
84
85
  ],
86
+ "PreInvocation": [
87
+ {
88
+ "type": "command",
89
+ "command": "node -e \"const p=require('path'),fs=require('fs'),os=require('os');const local=p.join(process.cwd(),'.agents','plugins','agentic-senior-core','hooks','session-pulse.js');const global=p.join(os.homedir(),'.gemini','config','plugins','agentic-senior-core','hooks','session-pulse.js');require(fs.existsSync(local)?local:global);\"",
90
+ "commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { $root = if ($env:CLAUDE_PLUGIN_ROOT) { $env:CLAUDE_PLUGIN_ROOT } else { \"$env:USERPROFILE\\.gemini\\config\\plugins\\agentic-senior-core\" }; node \"$root\\hooks\\session-pulse.js\" }",
91
+ "timeout": 5,
92
+ "statusMessage": "Loading ASC rules..."
93
+ },
94
+ {
95
+ "type": "command",
96
+ "command": "node -e \"const p=require('path'),fs=require('fs'),os=require('os');const local=p.join(process.cwd(),'.agents','plugins','agentic-senior-core','hooks','ladder-pulse.js');const global=p.join(os.homedir(),'.gemini','config','plugins','agentic-senior-core','hooks','ladder-pulse.js');require(fs.existsSync(local)?local:global);\"",
97
+ "commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { $root = if ($env:CLAUDE_PLUGIN_ROOT) { $env:CLAUDE_PLUGIN_ROOT } else { \"$env:USERPROFILE\\.gemini\\config\\plugins\\agentic-senior-core\" }; node \"$root\\hooks\\ladder-pulse.js\" }",
98
+ "timeout": 5,
99
+ "statusMessage": "ASC ladder pulse..."
100
+ }
101
+ ],
85
102
  "PostInvocation": [
86
103
  {
87
104
  "type": "command",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agentic-senior-core",
3
- "version": "5.9.0",
4
- "description": "Universal AI coding rules. Write code like a staff engineer.",
3
+ "version": "6.0.0",
4
+ "description": "Universal AI coding rules. Because your AI writes code like it gets paid by the line.",
5
5
  "contextFileName": "rules/agentic-senior-core.md",
6
6
  "rules": [
7
7
  "rules/"
@@ -80,6 +80,10 @@ whether to invoke it. Skip this for trivial edits.
80
80
  - Non-trivial feature in an existing codebase → `/asc-add-feature` (research/plan gate before implementation)
81
81
  - Refactor spanning multiple files or changing architecture → `/asc-refactor` (classifies scope, gates on high-level changes)
82
82
 
83
+ ### Enforcement Fallbacks (For hosts without hook support)
84
+ - **Duplicate-Code Check**: When creating new functions or components, actively check for existing near-duplicates across directories (not just siblings) before implementing. If a similar pattern exists, reuse it. Apply the Rule of Three: consolidate only if a pattern appears 3+ times.
85
+ - **Ladder Persistence**: Before completing a task, explicitly verify you have selected the lowest feasible step on the 1-6 decision ladder. Document deferred technical debt (via `/asc-debt` or inline comment) if a shortcut is taken.
86
+
83
87
  ## Response Style
84
88
 
85
89
  Lead with what the developer needs to act: the command, file path, code change, or decision point. Follow with context only when the action depends on it.
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: asc-dedup
3
+ description: >
4
+ Trigger this skill when the user says: "find duplicate code", "check
5
+ for clones", "audit for duplication", "is this repeated elsewhere",
6
+ "scan for copy-paste", "run jscpd", "dedup report", "consolidate
7
+ duplicate logic". Use for whole-repo or whole-directory duplication
8
+ audits on demand — this is a deep, on-demand scan, distinct from the
9
+ continuous per-edit check already enforced by the dedup-gate hook.
10
+ ---
11
+
12
+ # Duplicate Code Audit
13
+
14
+ On-demand deep duplication scan using jscpd (token-level clone detection). Distinct from the continuous per-edit `dedup-gate` hook — this skill runs a full-scope scan and produces a ranked report.
15
+
16
+ Grounded in: GitClear 2024 analysis (211M LOC, 8x increase in duplicated code blocks in AI-assisted repos). Token-level clone detection catches near-duplicates that differ in names/structure — something diff-only review tools and pattern matching cannot do.
17
+
18
+ ## When to Use
19
+
20
+ - User asks to scan a directory, package, or entire repo for duplicated code
21
+ - Before a refactoring pass, to identify consolidation targets
22
+ - After a multi-file feature addition, to verify no accidental duplication was introduced
23
+
24
+ ## Scan Procedure
25
+
26
+ 1. Determine scope from user's request (specific directory, package, or full repo).
27
+ 2. Check for `.asc/dedup-config.json` — use `ignoreDirs` and `minTokens` from it if present.
28
+ 3. Run: `npx jscpd@5 "<scope>" --min-tokens <minTokens> --reporters console,json --output ./report/`
29
+ - If `bunx` is available, prefer `bunx jscpd` for speed (24-37x faster per jscpd v5 benchmarks).
30
+ - Apply `--ignore` flags from config `ignoreDirs`.
31
+ 4. Parse the JSON report and present findings ranked by number of duplicated lines (largest clusters first).
32
+
33
+ ## Report Format
34
+
35
+ For each duplicate cluster, report:
36
+ - **Files involved** and line ranges
37
+ - **Duplicated lines count** and overlap percentage
38
+ - **Consolidation recommendation** (only if pattern appears 3+ times — Rule of Three)
39
+
40
+ ## Consolidation Rules
41
+
42
+ Per this repo's asc-refactor YAGNI and Rule of Three conventions:
43
+
44
+ - **2 occurrences**: Report the duplication. Do NOT suggest a shared abstraction — "three similar lines is better than a premature abstraction."
45
+ - **3+ occurrences**: Suggest the smallest safe consolidation — extract a shared function, component, or module. Explain what risk or friction the duplication creates and what the consolidated shape looks like.
46
+ - **Structural boilerplate** (imports, prop types, export statements): Flag but do not count as actionable duplication — these are framework-mandated patterns, not logic clones.
47
+
48
+ ## Integration
49
+
50
+ - The `dedup-gate` hook provides continuous per-edit detection (PostToolUse, scoped, fast).
51
+ - This skill provides deep on-demand audits (full scope, thorough, user-triggered).
52
+ - Findings from either can be logged to the debt ledger via `/asc-debt` if deferred.
@@ -0,0 +1,6 @@
1
+ {
2
+ "mode": "advisory",
3
+ "minTokens": 30,
4
+ "scanRoot": null,
5
+ "ignoreDirs": ["tests", "migrations", "generated", "node_modules"]
6
+ }
package/AGENTS.md CHANGED
@@ -75,6 +75,9 @@ whether to invoke it. Skip this for trivial edits.
75
75
  - Non-trivial feature in an existing codebase → `/asc-add-feature` (research/plan gate before implementation)
76
76
  - Refactor spanning multiple files or changing architecture → `/asc-refactor` (classifies scope, gates on high-level changes)
77
77
 
78
+ ### Enforcement Fallbacks (For hosts without hook support)
79
+ - **Duplicate-Code Check**: When creating new functions or components, actively check for existing near-duplicates across directories (not just siblings) before implementing. If a similar pattern exists, reuse it. Apply the Rule of Three: consolidate only if a pattern appears 3+ times.
80
+ - **Ladder Persistence**: Before completing a task, explicitly verify you have selected the lowest feasible step on the 1-6 decision ladder. Document deferred technical debt (via `/asc-debt` or inline comment) if a shortcut is taken.
78
81
  ## Response Style
79
82
 
80
83
  Lead with what the developer needs to act: the command, file path, code change, or decision point. Follow with context only when the action depends on it.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Agentic-Senior-Core
4
4
 
5
- ### Universal AI coding rules. Write code like a staff engineer, not a junior.
5
+ ### Universal AI coding rules. Because your AI writes code like it gets paid by the line.
6
6
 
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
8
8
  [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
@@ -13,326 +13,23 @@
13
13
 
14
14
  </div>
15
15
 
16
- ## Project Status
17
-
18
- | Component | Status | Notes |
19
- |-----------|--------|-------|
20
- | Rules & Skills (Instructional Layer) | Stable | Universal across 23+ AI tools |
21
- | Hooks (Enforcement Layer) | Stable | Claude Code, Antigravity IDE, Copilot CLI, Cursor |
22
- | `ascx` (Output Compression) | Beta | 7 adapters (git, npm, tsc, rg); unsupported commands pass through safely |
23
- | CLI (`asc adapter`, `asc global`) | Stable | Install adapters for any supported host |
24
-
25
- ## How Skills & Hooks Work (Multi-Tier Architecture)
26
-
27
- Agentic Senior Core operates on a two-tier architecture:
28
-
29
- 1. **Instructional Layer (Universal — Works in 23+ AI Tools)**:
30
- - **Rules (`AGENTS.md` / `agentic-senior-core.md`) & Skills (`SKILL.md`)** are cross-compatible across **Google Antigravity IDE, Claude Code, Cursor, Windsurf, Copilot, Codex, Kiro, Roo, OpenCode, Zed, Aider, etc.**.
31
- - **Automatic Skill Triggering**: Agents attempt to detect and load skills if your prompt matches the skill's description (e.g., asking "perform a security audit" loads `asc-audit`).
32
- - **Manual Skill Triggering (Highly Recommended)**: Explicitly call skills using commands like `/asc-refactor` or `/asc-new-project` for guaranteed execution.
33
-
34
- 2. **Active Enforcement Layer (Hooks — Host-Specific Hard Guardrails)**:
35
- - **Hard-Block Guardrails**: For tools supporting active hook execution engines (Claude Code, GitHub Copilot CLI, Google Antigravity IDE, Cursor), ASC automatically intercepts tool calls:
36
- - **PreToolUse Hard Block**: Immediately rejects edits adding stdlib-duplicating dependencies (e.g., `lodash`, `moment`, `uuid`) before execution (`permissionDecision: "deny"`). Escape hatch available via `.asc/dependency-allowlist.json`.
37
- - **PostToolUse Advisory**: Soft nudges for LOC deltas, spec drift, and workflow gate bypasses.
38
-
39
- ---
40
-
41
- ## Install
42
-
43
- ### Step 1: Install / Update the package
16
+ ## Quick Start
44
17
 
18
+ ### 1. Install the package
45
19
  To install or forcefully update to the absolute latest version:
46
20
 
47
21
  ```bash
48
22
  npm install -g @ryuenn3123/agentic-senior-core@latest
49
23
  ```
50
24
 
51
- > [!TIP]
52
- > **Why not `npm update -g`?** npm's update command aggressively respects SemVer restrictions and local cache, which can trap you on older patch versions. Always use `@latest` to forcefully pull the absolute newest build.
53
-
54
- ### Step 2: Set up for your AI tool
55
-
56
- <details>
57
- <summary><b>Claude Code</b> (terminal agent)</summary>
58
-
59
- Rules load automatically via plugin hooks. No per-project files needed.
60
-
61
- From inside Claude Code, add the marketplace then install:
62
-
63
- ```
64
- /plugin marketplace add fatidaprilian/Agentic-Senior-Core
65
- /plugin install agentic-senior-core@agentic-senior-core
66
- ```
67
-
68
- Or from your terminal shell:
69
-
70
- ```bash
71
- claude plugin marketplace add fatidaprilian/Agentic-Senior-Core
72
- claude plugin install agentic-senior-core@agentic-senior-core
73
- ```
74
-
75
- After install, every Claude Code session injects the rules on startup -- including subagents.
76
-
77
- </details>
78
-
79
- <details>
80
- <summary><b>Codex CLI</b> (terminal agent)</summary>
81
-
82
- ```bash
83
- codex plugins install agentic-senior-core
84
- ```
85
-
86
- Rules load automatically via plugin hooks on every session.
87
-
88
- </details>
89
-
90
- <details>
91
- <summary><b>Gemini CLI</b> (terminal agent)</summary>
92
-
93
- Auto-detected. Gemini CLI reads `gemini-extension.json` from the installed package and loads `AGENTS.md` as context. Commands available as `.toml` format (`/asc-refactor`, `/asc-review`, `/asc-audit`).
94
-
95
- </details>
96
-
97
- <details>
98
- <summary><b>Copilot CLI</b> (terminal agent)</summary>
99
-
100
- Plugin files ship at `.github/plugin/`. After global npm install, register the plugin per your Copilot CLI version. Rules inject via hooks on every session.
101
-
102
- </details>
103
-
104
- <details>
105
- <summary><b>Cursor</b> (IDE)</summary>
106
-
107
- Run from your project root:
108
-
109
- ```bash
110
- asc adapter --cursor
111
- ```
112
-
113
- This copies one file to `.cursor/rules/agentic-senior-core.mdc`. Cursor reads it automatically on every session. Repeat per project.
114
-
115
- </details>
116
-
117
- <details>
118
- <summary><b>Windsurf / Devin Desktop</b> (IDE)</summary>
119
-
120
- Windsurf was acquired by Cognition and renamed to Devin Desktop. Use `--devin` for the preferred path:
121
-
122
- ```bash
123
- asc adapter --devin
124
- ```
125
-
126
- This copies one file to `.devin/rules/agentic-senior-core.md`. For legacy Windsurf installations:
127
-
128
- ```bash
129
- asc adapter --windsurf
130
- ```
131
-
132
- Repeat per project — or install once globally with `asc global --windsurf` (writes `~/.codeium/windsurf/memories/global_rules.md`, applies to all workspaces; skipped if you already have your own global rules file).
133
-
134
- </details>
135
-
136
- <details>
137
- <summary><b>Cline</b> (VS Code extension)</summary>
138
-
139
- ```bash
140
- asc adapter --cline
141
- ```
142
-
143
- Copies one file to `.clinerules/agentic-senior-core.md`. Repeat per project — or install once globally with `asc global --cline` (rules land in `~/Documents/Cline/Rules/`, apply to all projects).
144
-
145
- </details>
146
-
147
- <details>
148
- <summary><b>GitHub Copilot</b> (VS Code extension)</summary>
149
-
150
- ```bash
151
- asc adapter --copilot
152
- ```
153
-
154
- Copies one file to `.github/copilot-instructions.md`. Repeat per project — or install once globally with `asc global --copilot` (user-level instructions file in your VS Code profile, applies to all workspaces).
155
-
156
- </details>
157
-
158
- <details>
159
- <summary><b>Kiro</b> (IDE)</summary>
160
-
161
- ```bash
162
- asc adapter --kiro
163
- ```
164
-
165
- Copies one file to `.kiro/steering/agentic-senior-core.md`. Repeat per project. A global option exists (`asc global --kiro` → `~/.kiro/steering/`), but some Kiro builds have known bugs loading global steering — prefer the per-project adapter if rules are not picked up.
166
-
167
- </details>
168
-
169
- <details>
170
- <summary><b>Continue</b> (VS Code extension)</summary>
171
-
172
- ```bash
173
- asc adapter --continue
174
- ```
175
-
176
- Copies one file to `.continue/rules/agentic-senior-core.md`. Repeat per project.
177
-
178
- </details>
179
-
180
- <details>
181
- <summary><b>Zed</b> (IDE)</summary>
182
-
183
- ```bash
184
- asc adapter --zed
185
- ```
186
-
187
- Copies one file to `.zed/rules/agentic-senior-core.md`. Zed also reads `AGENTS.md` natively, so this is optional if you already have AGENTS.md in your project. Repeat per project.
188
-
189
- </details>
190
-
191
- <details>
192
- <summary><b>Aider</b> (terminal agent)</summary>
193
-
194
- ```bash
195
- asc adapter --aider
196
- ```
197
-
198
- Copies one file to `CONVENTIONS.md` at project root. Aider reads this automatically. Repeat per project — or set it once globally in `~/.aider.conf.yml` with an absolute path into the npm package (`read: <npm root -g>/@ryuenn3123/agentic-senior-core/CONVENTIONS.md`). That pointer auto-updates with `npm update -g`.
199
-
200
- </details>
201
-
202
- <details>
203
- <summary><b>Kilo Code</b> (VS Code extension)</summary>
204
-
205
- ```bash
206
- asc adapter --kilocode
207
- ```
208
-
209
- Copies one file to `.kilocode/rules/agentic-senior-core.md`. Repeat per project — or install once globally with `asc global --kilocode`. On Kilo v7+, the zero-maintenance option is pointing the `instructions:` array in `~/.config/kilo/kilo.jsonc` at the rules file inside the npm package (auto-updates with `npm update -g`).
210
-
211
- </details>
212
-
213
- <details>
214
- <summary><b>Roo Code</b> (VS Code extension)</summary>
215
-
216
- ```bash
217
- asc adapter --roo
218
- ```
219
-
220
- Copies one file to `.roo/rules/agentic-senior-core.md`. Repeat per project — or install once globally with `asc global --roo` (`~/.roo/rules/`). Note: Roo Code was discontinued in May 2026; support is kept for existing installs.
221
-
222
- </details>
223
-
224
- <details>
225
- <summary><b>OpenHands</b></summary>
226
-
227
- ```bash
228
- asc adapter --openhands
229
- ```
230
-
231
- Copies one file to `.openhands/microagents/agentic-senior-core.md`. Repeat per project — or install once globally with `asc global --openhands` (`~/.openhands/microagents/`, loaded in all conversations for CLI/headless/dev modes; Docker runs need the directory mounted).
232
-
233
- </details>
234
-
235
- <details>
236
- <summary><b>Google Antigravity (2.0, IDE, and CLI)</b></summary>
237
-
238
- **Option A -- workspace rules (per project for 2.0 and IDE only):**
239
-
240
- Copy the rules file into your project's `.agents/rules/` directory:
241
-
242
- ```bash
243
- # Create the directory first, then copy
244
- mkdir -p .agents/rules
245
-
246
- # From the npm package (after Step 1)
247
- cp "$(npm root -g)/@ryuenn3123/agentic-senior-core/.agents/rules/agentic-senior-core.md" .agents/rules/
248
- ```
249
-
250
- PowerShell (Windows):
251
- ```powershell
252
- mkdir .agents\rules -Force
253
- cp "$(npm root -g)/@ryuenn3123/agentic-senior-core/.agents/rules/agentic-senior-core.md" .agents\rules\
254
- ```
255
-
256
- Antigravity IDE and 2.0 read it automatically with `trigger: always_on`. *(Note: Antigravity CLI does not support workspace plugins, use Option B for CLI).*
257
-
258
- **Option B -- global install (all projects and ALL clients):**
259
-
260
- One command (works on all platforms):
261
-
262
- ```bash
263
- asc global --antigravity
264
- ```
265
-
266
- This automatically stages the plugin bundle (skills, rules, hooks, and MCP servers) for:
267
- - **Antigravity 2.0 & IDE** (`~/.gemini/config/plugins/agentic-senior-core/`)
268
- - **Antigravity CLI** (`~/.gemini/antigravity-cli/plugins/agentic-senior-core/`)
269
-
270
- If you previously installed to legacy locations (v5.8.4 or earlier), the old paths are cleaned up automatically.
271
-
272
- > Note: `npm update -g` refreshes the npm package only. The global copy does not auto-update -- re-run `asc global --antigravity` after each update.
273
-
274
- > **WSL / dual-environment:** `asc global --antigravity` writes to the HOME directory of the current environment. If you use both Windows native and WSL, run it separately in each terminal.
275
-
276
- </details>
277
-
278
- <details>
279
- <summary><b>Devin / Hermes / OpenCode / OpenClaw</b></summary>
280
-
281
- Plugin manifests ship in the npm package at their standard paths (`.devin-plugin/`, `plugin.yaml`, `.opencode/plugins/`, `.openclaw/skills/`). After global npm install, each host auto-discovers or manually register per host docs.
282
-
283
- </details>
284
-
285
- <details>
286
- <summary><b>All IDE adapters at once</b></summary>
287
-
288
- ```bash
289
- asc adapter --all
290
- ```
291
-
292
- Generates adapter files for Cursor, Devin Desktop, Windsurf, Cline, Copilot, Kiro, Continue, Zed, Aider, Kilo Code, Roo Code, and OpenHands in one go.
293
-
294
- </details>
295
-
296
- **Terminal agents** (Claude Code, Codex, Gemini, Copilot CLI) = install once, always-on, zero per-project files.
297
- **IDE agents** = one file per project via `asc adapter`, or install once globally via `asc global` (below).
298
-
299
- ### Global install (all projects, zero project files)
300
-
301
- Most IDE tools also support user-level rules that apply to **every project** — no files in any repo root. One command installs them all:
25
+ ### 2. Set up globally (Recommended)
26
+ To automatically configure all supported IDEs and Agents at once across your entire system, run:
302
27
 
303
28
  ```bash
304
29
  asc global --all
305
30
  ```
306
31
 
307
- | Tool | Global location | Notes |
308
- |------|----------------|-------|
309
- | Google Antigravity (2.0, IDE, CLI) | `~/.gemini/config/plugins/...` and `~/.gemini/antigravity-cli/plugins/...` | Plugin bundle (skills, hooks, rules) |
310
- | Cline | `~/Documents/Cline/Rules/` | Toggleable in the Cline rules panel |
311
- | Kilo Code | `~/.kilocode/rules/` | Or point `instructions:` in `~/.config/kilo/kilo.jsonc` at the npm package path — that variant auto-updates |
312
- | Kiro | `~/.kiro/steering/` | Some builds have global-steering loading bugs; fall back to `asc adapter --kiro` |
313
- | OpenHands | `~/.openhands/microagents/` | CLI/headless/dev modes; Docker runs need the mount |
314
- | Windsurf / Devin Desktop | `~/.codeium/windsurf/memories/global_rules.md` | 6,000-char global limit (ASC rules fit); skipped if you already have your own file |
315
- | GitHub Copilot (VS Code) | VS Code profile `prompts/` folder | Installed as a user `*.instructions.md` with `applyTo: '**'` |
316
- | Roo Code | `~/.roo/rules/` | Roo Code was discontinued May 2026; kept for existing installs |
317
-
318
- Tools without a global rules **file** (manual one-time setup instead):
319
-
320
- - **Cursor** — Settings → Rules → User Rules: paste the contents of `AGENTS.md` (plain text field; a global rules directory is still a Cursor feature request).
321
- - **Zed** — Rules Library in the Agent Panel: create a rule from `AGENTS.md` and mark it as default (paper clip icon).
322
- - **Continue** — add a rules block to the global `config.yaml`.
323
- - **Aider** — add `read: <absolute path to npm package>/CONVENTIONS.md` in `~/.aider.conf.yml`. This is a live pointer: it auto-updates with `npm update -g`, no re-copy ever.
324
-
325
- Global rules load first; per-project adapter files (if present) take precedence on conflicts in every tool that supports both.
326
-
327
- ### Updating
328
-
329
- Already installed? Just update the global package:
330
-
331
- ```bash
332
- npm update -g @ryuenn3123/agentic-senior-core
333
- ```
334
-
335
- Terminal agent plugins pick up the new version automatically on next session. Global installs and IDE adapter files are static copies — after updating, re-run `asc global --all` once and `asc adapter --all` in each project that uses per-project files. (Aider's `read:` pointer and Kilo's `kilo.jsonc` path variant auto-update — nothing to re-run.)
32
+ **[See the full Installation Guide](docs/INSTALLATION.md)** for per-project (local) setups or specific tool instructions.
336
33
 
337
34
  ---
338
35
 
@@ -351,16 +48,6 @@ This plugin loads universal engineering rules on every session. Before writing a
351
48
  5. Can this be one straightforward function?
352
49
  6. Only then: write the minimum code that works.
353
50
 
354
- ## Marking Simplification
355
-
356
- When you pick the minimal option at step 5 or 6, and it isn't obviously trivial:
357
- - Leave a one-line comment noting why, and the upgrade trigger if there is a ceiling.
358
- Example: `// minimal: single global lock — split per-account if throughput becomes an issue`
359
- - Leave one runnable check (assertion, small test, or `__main__` demo) proving it works.
360
- Skip only for genuinely trivial one-liners.
361
-
362
- The rules also cover security, architecture, testing, error handling, API design, database safety, frontend accessibility, infrastructure, resilience, and async patterns. All universal invariants -- no project-specific configuration needed.
363
-
364
51
  ### Before / After
365
52
 
366
53
  <details>
@@ -384,9 +71,7 @@ app.post('/users', (req, res) => {
384
71
  });
385
72
  });
386
73
  ```
387
-
388
74
  Issues: no input validation, SQL injection, plaintext password stored and returned, internal error details leaked, no auth check.
389
-
390
75
  </details>
391
76
 
392
77
  <details>
@@ -406,152 +91,39 @@ app.post('/users', authenticate, async (req, res) => {
406
91
  res.status(201).json({ name, email });
407
92
  });
408
93
  ```
409
-
410
94
  Validated input, parameterized query, hashed password, safe error response, auth middleware, no sensitive data in response.
411
-
412
95
  </details>
413
96
 
414
- ### Not lazy about
415
-
416
- Input validation at trust boundaries, parameterized queries, auth checks, error handling that prevents data loss, accessibility, anything explicitly requested. These are never skipped.
417
-
418
- ---
419
-
420
- ## Supported Hosts
421
-
422
- | Host | Type | Install | Per-project files? |
423
- |------|------|---------|-------------------|
424
- | Claude Code | Terminal agent | `/plugin install` | No |
425
- | Codex CLI | Terminal agent | `codex plugins install` | No |
426
- | Gemini CLI | Terminal agent | Auto-detected | No |
427
- | Copilot CLI | Terminal agent | Plugin registration | No |
428
- | Devin | Terminal agent | Auto-detected | No |
429
- | Hermes | Terminal agent | Plugin registration | No |
430
- | OpenCode | Terminal agent | Auto-detected | No |
431
- | OpenClaw | Terminal agent | Auto-detected | No |
432
- | Antigravity IDE | IDE | `asc global --antigravity` | No (global) |
433
- | Antigravity CLI | Terminal agent | `agy plugin install` | No |
434
- | Cursor | IDE | `asc adapter --cursor` | Yes (1 file) — or paste User Rules once |
435
- | Devin Desktop | IDE | `asc adapter --devin` | Yes (1 file) |
436
- | Windsurf (legacy) | IDE | `asc global --windsurf` | No (global) — or `asc adapter --windsurf` |
437
- | Cline | VS Code ext | `asc global --cline` | No (global) — or `asc adapter --cline` |
438
- | GitHub Copilot | VS Code ext | `asc global --copilot` | No (global) — or `asc adapter --copilot` |
439
- | Kiro | IDE | `asc adapter --kiro` | Yes (1 file) — global via `asc global --kiro` (buggy in some builds) |
440
- | Continue | VS Code ext | `asc adapter --continue` | Yes (1 file) — or global config.yaml rules |
441
- | Zed | IDE | `asc adapter --zed` | Yes (1 file) — or default rule in Rules Library |
442
- | Aider | Terminal agent | `asc adapter --aider` | Yes (1 file) — or `read:` pointer in `~/.aider.conf.yml` |
443
- | Kilo Code | VS Code ext | `asc global --kilocode` | No (global) — or `asc adapter --kilocode` |
444
- | Roo Code | VS Code ext | `asc global --roo` | No (global) — discontinued May 2026 |
445
- | OpenHands | Agent | `asc global --openhands` | No (global) — or `asc adapter --openhands` |
446
-
447
- ---
448
-
449
- ## Commands
450
-
451
- Available on plugin hosts (Claude Code, Codex, Gemini CLI):
452
-
453
- | Command | Purpose |
454
- |---------|---------|
455
- | `/asc-new-project` | Greenfield workflow (Define -> Spec -> Implement -> Validate) |
456
- | `/asc-add-feature` | Brownfield workflow (Research -> Plan -> Implement) |
457
- | `/asc-refactor` | Structured refactoring workflow |
458
- | `/asc-review` | Production-risk code review with severity-ordered findings |
459
- | `/asc-audit` | Security and architecture audit |
460
- | `/asc-reference` | Domain-specific rules (testing, API, database, frontend, infra, resilience) |
461
- | `/asc-debt` | Track deferred enforcement violations (add, list, resolve, summary) |
462
- | `/asc-help` | Show available commands |
463
-
464
- ---
465
-
466
- ## CLI
467
-
468
- ```bash
469
- asc adapter [--cursor|--devin|--windsurf|--cline|--copilot|--kiro|--continue|--zed|--aider|--kilocode|--roo|--openhands|--all]
470
- asc global [--antigravity|--cline|--kilocode|--kiro|--openhands|--windsurf|--copilot|--roo|--all]
471
- asc uninstall [--dry-run]
472
- asc clean [--dry-run]
473
- asc status
474
- asc mcp
475
- asc --version
476
- asc --help
477
- ```
478
-
479
- `ascx` is a token-saving command wrapper that compresses noisy output while preserving debugging evidence. Install globally and use as: `ascx git status`, `ascx npm test`.
480
-
481
- ---
482
-
483
- ## Works With Other Plugins
484
-
485
- ASC covers security, architecture, testing, API design, database safety, accessibility, infrastructure, and resilience — domains that code-reduction and minimalism plugins explicitly leave out of scope. They reduce volume; ASC enforces safety on what remains.
486
-
487
- Use them together. No conflicts — ASC is designed to be complementary.
488
-
489
97
  ---
490
98
 
491
- ## Benchmarks
492
-
493
- Measured on `claude-opus-4-6` using headless Claude Code sessions against real tasks.
99
+ ## Configuration & Overrides
494
100
 
495
- | | LOC | Tokens | Cost | Duration | Safety |
496
- |---|---|---|---|---|---|
497
- | **Simple tasks** | 0% | -3% to -8% | -1% | -2% to -13% | 100% |
498
- | **Complex tasks** | **-18%** | **-30%** | **-42%** | **-18%** | 100% |
101
+ By default, ASC works perfectly out of the box with zero configuration. It enforces guardrails silently in the background.
499
102
 
500
- On complex, ambiguous tasks (auth systems, insecure CRUD refactors) where over-engineering typically occurs ASC produces **18% less code**, uses **30% fewer tokens**, costs **42% less**, and finishes **18% faster**.
103
+ If you need to override these defaults (e.g., to whitelist a specific dependency or ignore specific folders for code-duplication scanning), you can create an `.asc/` folder in your project root.
501
104
 
502
- On trivial tasks the model is already concise, so gains are marginal.
503
-
504
- Full methodology and raw data: [`benchmarks/RESULTS.md`](benchmarks/RESULTS.md)
505
-
506
- > Model: `claude-opus-4-6` · n=1-2 per task · Baseline = Claude without rules (not zero-prompt).
507
- > Opus is inherently disciplined — gains on more verbose models would likely be larger.
105
+ **[Read the Configuration Guide](docs/CONFIGURATION.md)**
508
106
 
509
107
  ---
510
108
 
511
- ## Migration from v4.x
512
-
513
- v5.0 is a breaking change. The per-project system (`.agent-context/`, bridge files, project scaffolding) is replaced by the universal plugin system.
109
+ ## Commands & CLI
514
110
 
515
- Clean up v4 artifacts from any project:
516
- ```bash
517
- # Preview what will be removed
518
- asc clean --dry-run
519
-
520
- # Remove v4 files (.agent-context/, AGENTS.md, CLAUDE.md, GEMINI.md, etc.)
521
- asc clean
522
- ```
111
+ ASC provides powerful commands to steer your agents (e.g. `/asc-refactor`, `/asc-audit`).
112
+ It also provides a CLI to manage your local setup (e.g. `asc adapter --all`, `asc global --all`).
523
113
 
524
- This removes `.agent-context/`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, and other v4 bridge files from the current project directory. The global plugin replaces all of them.
114
+ **[See all available CLI Options and Agent Commands](docs/INSTALLATION.md#commands--cli)**
525
115
 
526
116
  ---
527
117
 
528
- ## Token Budget
529
-
530
- | Component | Tokens | When loaded |
531
- |-----------|--------|------------|
532
- | Rules (`AGENTS.md`) | ~1,200 | Every session + every subagent |
533
- | Each skill | ~500-800 | On user invocation only |
534
- | Commands | 0 | Metadata only |
118
+ ## Documentation Index
535
119
 
536
- Total always-on cost: ~1,200 tokens per session.
120
+ - **[Installation & Supported Hosts](docs/INSTALLATION.md)** - Setup instructions for Claude Code, Copilot, Antigravity, Cursor, Windsurf, Zed, Aider, and more.
121
+ - **[Configuration Overrides](docs/CONFIGURATION.md)** - How to use `.asc/dedup-config.json` and `.asc/dependency-allowlist.json`.
122
+ - **[Architecture & Philosophy](docs/ARCHITECTURE.md)** - How the hooks work, our engineering principles, and Migration guide from v4.x.
123
+ - **[Benchmarks](benchmarks/RESULTS.md)** - ASC produces **18% less code**, uses **30% fewer tokens**, costs **42% less**, and finishes **18% faster**.
537
124
 
538
125
  ---
539
126
 
540
- ## Grounded In
541
-
542
- Every rule and skill workflow is derived from established engineering standards, not invented conventions.
543
-
544
- | Domain | Standards |
545
- |--------|-----------|
546
- | Security & audit | OWASP Top 10, OWASP ASVS v4, CWE classification, CVSS report structure |
547
- | Code review | OWASP Risk Rating Methodology, Google Engineering Practices |
548
- | Architecture | Clean Architecture, Hexagonal Architecture |
549
- | Workflows | RPI & QRSPI (Dex Horthy/HumanLayer), SDD (GitHub Spec Kit) |
550
- | Refactoring | Fowler's Refactoring, Rule of Three, YAGNI (XP/Kent Beck) |
551
- | Database | Fowler's Money Pattern, UTC timestamp convention, migration versioning |
552
- | Accessibility | WCAG 2.2 AA |
553
- | Resilience | Nygard's Release It!, AWS Well-Architected Reliability Pillar |
554
- | Technical debt | Cunningham's debt metaphor (1992) |
555
- | Instruction design | Low instruction density for higher LLM compliance — supported by IFScale (arXiv:2507.11538) and RECAST (arXiv:2505.19030) |
127
+ ## Works With Other Plugins
556
128
 
557
- The decision ladder (check before building) and debt ledger format are ASC-specific implementations grounded in these principles.
129
+ ASC covers security, architecture, testing, API design, database safety, accessibility, infrastructure, and resilience domains that code-reduction and minimalism plugins explicitly leave out of scope. They reduce volume; ASC enforces safety on what remains. Use them together. No conflicts — ASC is designed to be complementary.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-senior-core",
3
- "version": "5.9.0",
3
+ "version": "6.0.0",
4
4
  "description": "Universal AI coding rules. Write code like a staff engineer.",
5
5
  "author": "fatidaprilian",
6
6
  "license": "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryuenn3123/agentic-senior-core",
3
- "version": "5.9.0",
3
+ "version": "6.0.0",
4
4
  "type": "module",
5
5
  "description": "Agentic Senior Core: Universal AI coding rules and workflows. Write code like a staff engineer, not a junior.",
6
6
  "bin": {
@@ -9,6 +9,7 @@
9
9
  "ascx": "bin/ascx.js"
10
10
  },
11
11
  "files": [
12
+ ".asc/",
12
13
  "bin/",
13
14
  "lib/cli/commands/adapter.mjs",
14
15
  "lib/cli/commands/global.mjs",
package/plugin.yaml CHANGED
@@ -1,5 +1,5 @@
1
1
  name: agentic-senior-core
2
- version: 5.9.0
2
+ version: 6.0.0
3
3
  description: Universal AI coding rules. Write code like a staff engineer.
4
4
  author: fatidaprilian
5
5
  provides_hooks:
@@ -18,6 +18,7 @@ provides_skills:
18
18
  - asc-add-feature
19
19
  - asc-audit
20
20
  - asc-debt
21
+ - asc-dedup
21
22
  - asc-new-project
22
23
  - asc-refactor
23
24
  - asc-reference