@ryuenn3123/agentic-senior-core 6.16.2 → 6.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/agentic-senior-core/.codex-plugin/plugin.json +1 -1
- package/.agents/plugins/agentic-senior-core/commands/asc-pentest.md +2 -0
- package/.agents/plugins/agentic-senior-core/commands/asc-pentest.toml +3 -0
- package/.agents/plugins/agentic-senior-core/hooks/dedup-gate.js +137 -128
- package/.agents/plugins/agentic-senior-core/hooks/hooks.json +97 -0
- package/.agents/plugins/agentic-senior-core/hooks/ladder-pulse.js +53 -36
- package/.agents/plugins/agentic-senior-core/hooks/lib/known-ui-slop-patterns.json +20 -0
- package/.agents/plugins/agentic-senior-core/hooks/path-util.cjs +118 -4
- package/.agents/plugins/agentic-senior-core/hooks/post-edit-enforce.js +98 -81
- package/.agents/plugins/agentic-senior-core/hooks/pre-tool-dependency-gate.js +168 -191
- package/.agents/plugins/agentic-senior-core/hooks/session-pulse.js +48 -35
- package/.agents/plugins/agentic-senior-core/hooks/session-start.js +62 -11
- package/.agents/plugins/agentic-senior-core/hooks.json +4 -94
- package/.agents/plugins/agentic-senior-core/plugin.json +5 -13
- package/.agents/plugins/agentic-senior-core/rules/agentic-senior-core.md +6 -1
- package/.agents/plugins/agentic-senior-core/skills/asc/SKILL.md +5 -2
- package/.agents/plugins/agentic-senior-core/skills/asc-develop/SKILL.md +3 -3
- package/.agents/plugins/agentic-senior-core/skills/asc-pentest/SKILL.md +97 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-pentest/references/api-security-idor.md +105 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-pentest/references/dast-baseline.md +78 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-pentest/references/fuzzing-dsl.md +66 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-pentest/references/pentest-task-tree.md +70 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-review/SKILL.md +2 -2
- package/.agents/plugins/agentic-senior-core/skills/asc-test/SKILL.md +8 -1
- package/.agents/plugins/agentic-senior-core/skills/asc-test/references/mutation-testing.md +55 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-test/references/performance-budgets.md +67 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-test/references/property-testing.md +72 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/SKILL.md +17 -14
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/copy-i18n.md +56 -8
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/craft/color-surfaces.md +25 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/craft/themes-catalog.md +198 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/divergence.md +34 -2
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/modes/genre-calibration.md +89 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/modes/operate.md +26 -0
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/modes/persuade.md +10 -9
- package/.agents/plugins/agentic-senior-core/skills/asc-ui/references/redesign-audit.md +4 -9
- package/bin/agentic-senior-core.js +19 -4
- package/gemini-extension.json +2 -2
- package/lib/cli/ascx/runtime.mjs +5 -27
- package/lib/cli/ascx/windows-spawn.mjs +348 -0
- package/lib/cli/commands/bootstrap.mjs +56 -0
- package/lib/cli/commands/dedup.mjs +500 -0
- package/lib/cli/commands/git-hook-generator.mjs +3 -2
- package/lib/cli/commands/global.mjs +109 -53
- package/lib/cli/commands/preview.mjs +18 -9
- package/package.json +1 -1
- package/plugin.yaml +3 -1
|
@@ -184,7 +184,7 @@ async function ensureCodexConfigEnabled() {
|
|
|
184
184
|
async function installCodexGlobal(target) {
|
|
185
185
|
const rulesSource = path.join(REPOSITORY_ROOT, target.rulesSourcePath);
|
|
186
186
|
const pluginSource = path.join(REPOSITORY_ROOT, target.pluginSourcePath);
|
|
187
|
-
const hooksSource = path.join(REPOSITORY_ROOT, '.agents', 'plugins', 'agentic-senior-core', 'hooks.json');
|
|
187
|
+
const hooksSource = path.join(REPOSITORY_ROOT, '.agents', 'plugins', 'agentic-senior-core', 'hooks', 'hooks.json');
|
|
188
188
|
const singlePluginSource = path.join(REPOSITORY_ROOT, '.agents', 'plugins', 'agentic-senior-core');
|
|
189
189
|
const rulesTarget = target.targetPath(); // ~/.codex/AGENTS.md
|
|
190
190
|
const hooksTarget = path.join(HOME, '.codex', 'hooks.json');
|
|
@@ -372,9 +372,10 @@ async function installAntigravityIde(target) {
|
|
|
372
372
|
'utf8'
|
|
373
373
|
);
|
|
374
374
|
|
|
375
|
-
//
|
|
376
|
-
|
|
377
|
-
|
|
375
|
+
// Remove legacy global hooks.json entries (~/.gemini/config/hooks.json & ~/.gemini/antigravity-cli/hooks.json)
|
|
376
|
+
// because Antigravity executes hooks with cwd set to the directory containing hooks.json, and automatically
|
|
377
|
+
// discovers hooks.json inside ~/.gemini/config/plugins/agentic-senior-core/hooks.json without duplicate firing.
|
|
378
|
+
await cleanupLegacyGlobalAntigravityHooks();
|
|
378
379
|
|
|
379
380
|
// Automatically register the plugin with Antigravity CLI if agy binary is available
|
|
380
381
|
try {
|
|
@@ -389,44 +390,29 @@ async function installAntigravityIde(target) {
|
|
|
389
390
|
return true;
|
|
390
391
|
}
|
|
391
392
|
|
|
392
|
-
async function
|
|
393
|
-
|
|
393
|
+
async function cleanupLegacyGlobalAntigravityHooks() {
|
|
394
|
+
const globalHooksPath = path.join(HOME, '.gemini', 'config', 'hooks.json');
|
|
395
|
+
const legacyCliHooksPath = path.join(HOME, '.gemini', 'antigravity-cli', 'hooks.json');
|
|
394
396
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
SessionStart: masterHooks.SessionStart || null,
|
|
401
|
-
PreInvocation: masterHooks.PreInvocation || null,
|
|
402
|
-
PostInvocation: masterHooks.PostInvocation || null,
|
|
403
|
-
Stop: masterHooks.Stop || null,
|
|
404
|
-
PreToolUse: masterHooks.PreToolUse || null,
|
|
405
|
-
PostToolUse: masterHooks.PostToolUse || null,
|
|
406
|
-
};
|
|
407
|
-
|
|
408
|
-
const targetPaths = [
|
|
409
|
-
path.join(HOME, '.gemini', 'config', 'hooks.json'),
|
|
410
|
-
path.join(HOME, '.gemini', 'antigravity-cli', 'hooks.json'),
|
|
411
|
-
];
|
|
412
|
-
|
|
413
|
-
for (const targetPath of targetPaths) {
|
|
414
|
-
try {
|
|
415
|
-
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
416
|
-
let existingConfig = {};
|
|
417
|
-
if (await pathExists(targetPath)) {
|
|
418
|
-
try {
|
|
419
|
-
existingConfig = JSON.parse(await fs.readFile(targetPath, 'utf8'));
|
|
420
|
-
} catch (_) {}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
// Safely merge "agentic-senior-core" key preserving other user keys (e.g. "well")
|
|
424
|
-
existingConfig['agentic-senior-core'] = formattedAscHooks;
|
|
397
|
+
if (await pathExists(legacyCliHooksPath)) {
|
|
398
|
+
try {
|
|
399
|
+
await fs.rm(legacyCliHooksPath, { force: true });
|
|
400
|
+
} catch (_) {}
|
|
401
|
+
}
|
|
425
402
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
403
|
+
if (await pathExists(globalHooksPath)) {
|
|
404
|
+
try {
|
|
405
|
+
const existingConfig = JSON.parse(await fs.readFile(globalHooksPath, 'utf8'));
|
|
406
|
+
if (existingConfig && typeof existingConfig === 'object' && 'agentic-senior-core' in existingConfig) {
|
|
407
|
+
delete existingConfig['agentic-senior-core'];
|
|
408
|
+
if (Object.keys(existingConfig).length === 0) {
|
|
409
|
+
await fs.rm(globalHooksPath, { force: true });
|
|
410
|
+
} else {
|
|
411
|
+
await fs.writeFile(globalHooksPath, JSON.stringify(existingConfig, null, 2) + '\n', 'utf8');
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
} catch (_) {}
|
|
415
|
+
}
|
|
430
416
|
}
|
|
431
417
|
|
|
432
418
|
async function findAgyBinaryPath() {
|
|
@@ -509,7 +495,78 @@ async function installGlobalTarget(targetKey) {
|
|
|
509
495
|
return true;
|
|
510
496
|
}
|
|
511
497
|
|
|
512
|
-
export async function
|
|
498
|
+
export async function detectInstalledGlobalTargets() {
|
|
499
|
+
const isWin = process.platform === 'win32';
|
|
500
|
+
const { resolveWindowsExecutable } = await import('../ascx/windows-spawn.mjs');
|
|
501
|
+
const { execSync } = await import('node:child_process');
|
|
502
|
+
|
|
503
|
+
const hasBinary = (cmd) => {
|
|
504
|
+
if (isWin) {
|
|
505
|
+
return Boolean(resolveWindowsExecutable(cmd, process.env, process.cwd()));
|
|
506
|
+
}
|
|
507
|
+
try {
|
|
508
|
+
execSync(`command -v ${cmd}`, { stdio: 'ignore' });
|
|
509
|
+
return true;
|
|
510
|
+
} catch {
|
|
511
|
+
return false;
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
const checks = {
|
|
516
|
+
antigravity: async () => (await pathExists(path.join(HOME, '.gemini'))) || hasBinary('agy'),
|
|
517
|
+
codex: async () => (await pathExists(path.join(HOME, '.codex'))) || hasBinary('codex'),
|
|
518
|
+
opencode: async () => (await pathExists(path.join(HOME, '.config', 'opencode')))
|
|
519
|
+
|| (await pathExists(path.join(HOME, '.opencode')))
|
|
520
|
+
|| hasBinary('opencode'),
|
|
521
|
+
roo: async () => await pathExists(path.join(HOME, '.roo')),
|
|
522
|
+
kilocode: async () => (await pathExists(path.join(HOME, '.config', 'kilo')))
|
|
523
|
+
|| (await pathExists(path.join(HOME, '.kilo')))
|
|
524
|
+
|| (await pathExists(path.join(HOME, '.kilocode')))
|
|
525
|
+
|| (process.env.APPDATA ? await pathExists(path.join(process.env.APPDATA, 'kilo')) : false)
|
|
526
|
+
|| hasBinary('kilo'),
|
|
527
|
+
cline: async () => (await pathExists(path.join(HOME, '.cline')))
|
|
528
|
+
|| (await pathExists(path.join(HOME, 'Documents', 'Cline'))),
|
|
529
|
+
kiro: async () => await pathExists(path.join(HOME, '.kiro')),
|
|
530
|
+
openhands: async () => (await pathExists(path.join(HOME, '.openhands'))) || hasBinary('openhands'),
|
|
531
|
+
windsurf: async () => (await pathExists(path.join(HOME, '.windsurf')))
|
|
532
|
+
|| (await pathExists(path.join(HOME, '.codeium')))
|
|
533
|
+
|| (isWin ? await pathExists(path.join(HOME, 'AppData', 'Roaming', 'Windsurf')) : false),
|
|
534
|
+
copilot: async () => (await pathExists(path.join(HOME, '.config', 'github-copilot')))
|
|
535
|
+
|| (isWin ? await pathExists(path.join(HOME, 'AppData', 'Local', 'GitHub Copilot')) : false)
|
|
536
|
+
|| (await pathExists(path.dirname(vscodeUserPromptsDirectory()))),
|
|
537
|
+
};
|
|
538
|
+
|
|
539
|
+
const detected = [];
|
|
540
|
+
for (const [key, check] of Object.entries(checks)) {
|
|
541
|
+
if (GLOBAL_TARGETS[key] && (await check())) {
|
|
542
|
+
detected.push(key);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return detected;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function printGlobalHelp() {
|
|
549
|
+
console.log('Agentic Senior Core -- Global Rules Installer\n');
|
|
550
|
+
console.log('Usage:');
|
|
551
|
+
console.log(' asc global Auto-detect installed AI tools and install globally');
|
|
552
|
+
console.log(' asc global --all Install to all supported global targets');
|
|
553
|
+
console.log(' asc global --<target> Install to specific target(s)\n');
|
|
554
|
+
console.log('Supported automatic global targets:');
|
|
555
|
+
for (const [key, target] of Object.entries(GLOBAL_TARGETS)) {
|
|
556
|
+
console.log(` --${key.padEnd(14)} ${target.label} (${target.note})`);
|
|
557
|
+
}
|
|
558
|
+
console.log('\nManual global setup tools:');
|
|
559
|
+
for (const manual of MANUAL_TARGETS) {
|
|
560
|
+
console.log(` ${manual.label.padEnd(16)} ${manual.hint}`);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
export async function runGlobalCommand(commandArguments = []) {
|
|
565
|
+
if (commandArguments.includes('--help') || commandArguments.includes('-h')) {
|
|
566
|
+
printGlobalHelp();
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
|
|
513
570
|
const requestedTargets = [];
|
|
514
571
|
|
|
515
572
|
for (const argument of commandArguments) {
|
|
@@ -521,7 +578,11 @@ export async function runGlobalCommand(commandArguments) {
|
|
|
521
578
|
const targetKey = argument.replace(/^--/, '');
|
|
522
579
|
if (GLOBAL_TARGETS[targetKey]) {
|
|
523
580
|
requestedTargets.push(targetKey);
|
|
524
|
-
} else if (argument.startsWith('
|
|
581
|
+
} else if (argument.startsWith('-')) {
|
|
582
|
+
console.error(`Unknown global target: ${argument}`);
|
|
583
|
+
console.log(`Available targets: ${Object.keys(GLOBAL_TARGETS).map(k => `--${k}`).join(', ')}, --all`);
|
|
584
|
+
process.exit(1);
|
|
585
|
+
} else {
|
|
525
586
|
console.error(`Unknown global target: ${argument}`);
|
|
526
587
|
console.log(`Available targets: ${Object.keys(GLOBAL_TARGETS).map(k => `--${k}`).join(', ')}, --all`);
|
|
527
588
|
process.exit(1);
|
|
@@ -529,18 +590,13 @@ export async function runGlobalCommand(commandArguments) {
|
|
|
529
590
|
}
|
|
530
591
|
|
|
531
592
|
if (requestedTargets.length === 0) {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
for (const [key, target] of Object.entries(GLOBAL_TARGETS)) {
|
|
537
|
-
console.log(` --${key.padEnd(14)} ${target.label} (${target.note})`);
|
|
538
|
-
}
|
|
539
|
-
console.log('\nManual global setup tools:');
|
|
540
|
-
for (const manual of MANUAL_TARGETS) {
|
|
541
|
-
console.log(` ${manual.label.padEnd(16)} ${manual.hint}`);
|
|
593
|
+
const autoDetected = await detectInstalledGlobalTargets();
|
|
594
|
+
if (autoDetected.length === 0) {
|
|
595
|
+
printGlobalHelp();
|
|
596
|
+
return;
|
|
542
597
|
}
|
|
543
|
-
|
|
598
|
+
console.log(`Auto-detected ${autoDetected.length} installed AI host(s): ${autoDetected.join(', ')}\n`);
|
|
599
|
+
requestedTargets.push(...autoDetected);
|
|
544
600
|
}
|
|
545
601
|
|
|
546
602
|
console.log('Installing global rules...\n');
|
|
@@ -6,8 +6,19 @@
|
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import os from 'node:os';
|
|
9
|
+
import { pathToFileURL } from 'node:url';
|
|
9
10
|
import { execSync } from 'node:child_process';
|
|
10
11
|
|
|
12
|
+
function openInDefaultBrowser(targetPath) {
|
|
13
|
+
if (process.platform === 'win32') {
|
|
14
|
+
execSync(`cmd.exe /d /s /c "start "" "${targetPath}""`, { stdio: 'ignore' });
|
|
15
|
+
} else if (process.platform === 'darwin') {
|
|
16
|
+
execSync(`open "${targetPath}"`, { stdio: 'ignore' });
|
|
17
|
+
} else {
|
|
18
|
+
execSync(`xdg-open "${targetPath}"`, { stdio: 'ignore' });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
11
22
|
export function getBrowserCandidates() {
|
|
12
23
|
const platform = process.platform;
|
|
13
24
|
const candidates = [];
|
|
@@ -161,9 +172,8 @@ export async function runPreviewCommand(args = []) {
|
|
|
161
172
|
|
|
162
173
|
// Open in default OS browser if requested
|
|
163
174
|
if (shouldOpen) {
|
|
164
|
-
const opener = process.platform === 'win32' ? 'start' : process.platform === 'darwin' ? 'open' : 'xdg-open';
|
|
165
175
|
try {
|
|
166
|
-
|
|
176
|
+
openInDefaultBrowser(resolvedHtmlPath);
|
|
167
177
|
console.log(`[asc preview] Opened in default browser: ${resolvedHtmlPath}`);
|
|
168
178
|
return;
|
|
169
179
|
} catch (err) {
|
|
@@ -175,20 +185,20 @@ export async function runPreviewCommand(args = []) {
|
|
|
175
185
|
const browser = findBrowserExecutable();
|
|
176
186
|
if (!browser) {
|
|
177
187
|
console.warn('[asc preview] No supported headless browser detected (Brave, Edge, Chrome, Firefox). Falling back to OS opener.');
|
|
178
|
-
|
|
179
|
-
execSync(`${opener} "" "${resolvedHtmlPath}"`, { stdio: 'ignore' });
|
|
188
|
+
openInDefaultBrowser(resolvedHtmlPath);
|
|
180
189
|
return;
|
|
181
190
|
}
|
|
182
191
|
|
|
183
192
|
try {
|
|
193
|
+
const fileUrl = pathToFileURL(resolvedHtmlPath).href;
|
|
184
194
|
let command;
|
|
185
195
|
if (browser.family === 'chromium') {
|
|
186
|
-
command = `"${browser.path}" --headless --disable-gpu --screenshot="${outputPng}" --window-size=${width},${height} "${
|
|
196
|
+
command = `"${browser.path}" --headless=new --disable-gpu --screenshot="${outputPng}" --window-size=${width},${height} "${fileUrl}"`;
|
|
187
197
|
} else if (browser.family === 'firefox') {
|
|
188
|
-
command = `"${browser.path}" -headless -screenshot "${outputPng}" -window-size ${width},${height} "${
|
|
198
|
+
command = `"${browser.path}" -headless -screenshot "${outputPng}" -window-size ${width},${height} "${fileUrl}"`;
|
|
189
199
|
}
|
|
190
200
|
|
|
191
|
-
execSync(command, { stdio: 'pipe' });
|
|
201
|
+
execSync(command, { stdio: 'pipe', timeout: 15000 });
|
|
192
202
|
|
|
193
203
|
if (fs.existsSync(outputPng)) {
|
|
194
204
|
const stat = fs.statSync(outputPng);
|
|
@@ -199,8 +209,7 @@ export async function runPreviewCommand(args = []) {
|
|
|
199
209
|
}
|
|
200
210
|
} catch (err) {
|
|
201
211
|
console.warn(`[asc preview] Headless snapshot failed: ${err.message}. Falling back to OS opener.`);
|
|
202
|
-
|
|
203
|
-
execSync(`${opener} "" "${resolvedHtmlPath}"`, { stdio: 'ignore' });
|
|
212
|
+
openInDefaultBrowser(resolvedHtmlPath);
|
|
204
213
|
}
|
|
205
214
|
}
|
|
206
215
|
|
package/package.json
CHANGED
package/plugin.yaml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name: agentic-senior-core
|
|
2
|
-
version: 6.16.
|
|
2
|
+
version: 6.16.5
|
|
3
3
|
description: Universal AI coding rules. Write code like a staff engineer.
|
|
4
4
|
author: fatidaprilian
|
|
5
5
|
provides_hooks:
|
|
@@ -11,6 +11,7 @@ provides_commands:
|
|
|
11
11
|
- asc-reference
|
|
12
12
|
- asc-ui
|
|
13
13
|
- asc-test
|
|
14
|
+
- asc-pentest
|
|
14
15
|
provides_skills:
|
|
15
16
|
- asc
|
|
16
17
|
- asc-develop
|
|
@@ -18,3 +19,4 @@ provides_skills:
|
|
|
18
19
|
- asc-review
|
|
19
20
|
- asc-ui
|
|
20
21
|
- asc-test
|
|
22
|
+
- asc-pentest
|