@ryuenn3123/agentic-senior-core 6.10.0 → 6.11.1

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 (24) hide show
  1. package/.agents/plugins/agentic-senior-core/.codex-plugin/plugin.json +1 -1
  2. package/.agents/plugins/agentic-senior-core/hooks/lib/known-stub-patterns.json +29 -0
  3. package/.agents/plugins/agentic-senior-core/hooks/lib/known-ui-slop-patterns.json +15 -0
  4. package/.agents/plugins/agentic-senior-core/hooks/post-edit-enforce.js +201 -32
  5. package/.agents/plugins/agentic-senior-core/hooks.json +23 -22
  6. package/.agents/plugins/agentic-senior-core/plugin.json +1 -1
  7. package/.agents/plugins/agentic-senior-core/rules/agentic-senior-core.md +5 -1
  8. package/.agents/plugins/agentic-senior-core/skills/asc-add-feature/SKILL.md +6 -6
  9. package/.agents/plugins/agentic-senior-core/skills/asc-audit/SKILL.md +6 -0
  10. package/.agents/plugins/agentic-senior-core/skills/asc-bootstrap/SKILL.md +3 -0
  11. package/.agents/plugins/agentic-senior-core/skills/asc-debt/SKILL.md +15 -5
  12. package/.agents/plugins/agentic-senior-core/skills/asc-refactor/SKILL.md +7 -8
  13. package/.agents/plugins/agentic-senior-core/skills/asc-reference/SKILL.md +4 -10
  14. package/.agents/plugins/agentic-senior-core/skills/asc-review/SKILL.md +6 -5
  15. package/bin/agentic-senior-core.js +0 -8
  16. package/gemini-extension.json +1 -1
  17. package/lib/cli/commands/git-hook-generator.mjs +40 -2
  18. package/package.json +1 -3
  19. package/plugin.yaml +1 -1
  20. package/lib/cli/commands/mcp.mjs +0 -3
  21. package/scripts/mcp-server/constants.mjs +0 -57
  22. package/scripts/mcp-server/tool-registry.mjs +0 -204
  23. package/scripts/mcp-server/tools.mjs +0 -592
  24. package/scripts/mcp-server.mjs +0 -202
@@ -10,6 +10,12 @@ Security and architecture audit. Deeper than review, focused on finding vulnerab
10
10
 
11
11
  Grounded in: OWASP Top 10 (2025), OWASP ASVS v5.0, OWASP Top 10 for Agentic Applications (ASI01-ASI10, v2.01), CVSS vulnerability report structure, CWE classification.
12
12
 
13
+ ## Audit Procedure (Empirical First)
14
+
15
+ 1. **Dependency Vulnerability Scan**: Run the project's native security auditor (`npm audit`, `cargo audit`, or `pip-audit`). Report known CVEs immediately.
16
+ 2. **Lexical Sink & Secret Scan**: Search for hardcoded credentials, unvalidated redirects (`location.href`), dangerous functions (`eval`, `pickle.load`, `shell=True`), and unverified stubs (`// ASC-STUB:`).
17
+ 3. **Trust Boundary Mapping**: Trace all points where untrusted external input (HTTP body/query, CLI args, environment, external files) enters the system.
18
+
13
19
  ## Audit Scope
14
20
 
15
21
  1. **Trust boundaries**: Every point where external input enters the system. Validate that inputs are sanitized, normalized, and rejected when invalid.
@@ -19,6 +19,9 @@ Grounded in: Cold-start preference elicitation literature (Deezer/Netflix) & Khr
19
19
  - `ui-colored-left-border` (Colored left-border strip alert/card)
20
20
  - `ui-glassmorphism` (Generic glassmorphism backdrop blur)
21
21
  - `ui-pill-badge-generic` (Generic rounded pill tag badge)
22
+ - `ui-gradient-text-cliche` (Overused gradient headline text)
23
+ - `ui-transition-all-layout-cost` (Overused transition-all layout repaint cost)
24
+ - `ui-stripped-focus-ring` (Stripped focus ring WCAG 2.4.7 violation)
22
25
  2. Prompt user to select which slop patterns to ban for their brand/repo.
23
26
  3. Call `bootstrapPreferences()` in `lib/core/bootstrap-wizard.mjs` to seed selected rules into project preferences.
24
27
  4. Auto-compile Track A rules into `.git/hooks/pre-commit` and `ascx validate`.
@@ -12,13 +12,23 @@ Grounded in: Cunningham's technical debt metaphor (1992). Entry format (ladder s
12
12
 
13
13
  ## Storage
14
14
 
15
- Entries persist in `.agent-context/state/debt-ledger.json` via MCP `state_read`/`state_write`. The ledger is a JSON array of entry objects.
15
+ Entries persist in `.agent-context/state/debt-ledger.json` (or `.asc/debt-ledger.json`) via standard file read/write operations. The ledger is a JSON array of entry objects.
16
+
17
+ ## Stub Convention
18
+
19
+ When introducing a temporary stub during development, mark it explicitly:
20
+ ```typescript
21
+ // ASC-STUB: [reason for temporary code] [ASC-DEBT-001]
22
+ ```
23
+ (or `# ASC-STUB: [reason] [ASC-DEBT-001]` in Python/Ruby).
24
+
25
+ Every stub marker in source code MUST reference an open debt ID. Unregistered stubs will be blocked by the Git pre-commit runner.
16
26
 
17
27
  ## Entry Format
18
28
 
19
29
  ```json
20
30
  {
21
- "id": "sequential integer",
31
+ "id": "sequential integer (or ASC-DEBT-xxx)",
22
32
  "file": "path/to/file.ts",
23
33
  "ladderStep": "3",
24
34
  "violation": "Added axios — stdlib fetch covers this",
@@ -34,14 +44,14 @@ Entries persist in `.agent-context/state/debt-ledger.json` via MCP `state_read`/
34
44
 
35
45
  When an enforcement nudge fires and the violation is deferred:
36
46
 
37
- 1. Read the current ledger via `state_read` (path: `debt-ledger.json`). If missing, start with `[]`.
47
+ 1. Read the current ledger from `.agent-context/state/debt-ledger.json`. If missing, start with `[]`.
38
48
  2. Append a new entry with the next sequential `id`, the file path, ladder step, and a one-line violation summary.
39
- 3. Write the updated ledger via `state_write` (path: `debt-ledger.json`, mode: `overwrite`).
49
+ 3. Write the updated ledger back to disk.
40
50
  4. Confirm: "Logged to debt ledger: [violation summary]"
41
51
 
42
52
  ### List Open Debt
43
53
 
44
- 1. Read the ledger via `state_read`.
54
+ 1. Read the ledger.
45
55
  2. Filter to entries where `status` is `"open"`.
46
56
  3. Display as a table: ID, file, ladder step, violation, age.
47
57
  4. If no open entries, say so explicitly.
@@ -24,17 +24,16 @@ Removing speculative code is the highest-value, lowest-risk refactor type.
24
24
  After reading the target code, classify the refactor:
25
25
 
26
26
  - **Low-level** (rename, extract method, type safety, dead code removal): proceed after explaining the change. No approval gate needed.
27
- - **High-level** (move module, change architecture, redesign abstractions, multi-file structural changes): output a plan with specific files and rationale, then **stop and wait for user approval** before implementing.
28
-
29
- **Known limitation:** The high-level refactor gate is a skill-text instruction — the agent self-classifies and self-stops. Unlike `/asc-add-feature` and `/asc-new-project`, this gate is not backed by the PostToolUse hook or workflow-gate.json. If the agent bypasses the gate, there is no automated nudge.
27
+ - **High-level** (move module, change architecture, redesign abstractions, multi-file structural changes): write `workflow-gate.json` with `{"workflow": "asc-refactor", "phase": "plan"}`, output a plan with specific files and rationale, then **stop and wait for user approval** before implementing.
30
28
 
31
29
  ## Before Editing
32
30
 
33
- 1. Read the target code and understand existing patterns.
34
- 2. Identify the smallest relevant scope for the refactor.
35
- 3. Classify the refactor (see above). If high-level, stop and present a plan.
36
- 4. If the change touches UI, check accessibility and responsive behavior.
37
- 5. If the change touches dependencies, verify current official docs.
31
+ 1. **Verify Baseline**: Run project test runner (`ascx test`, `npm test`, or equivalent). Do not refactor on failing tests.
32
+ 2. Read the target code and understand existing patterns.
33
+ 3. Identify the smallest relevant scope for the refactor.
34
+ 4. Classify the refactor (see above). For high-level refactors, update `workflow-gate.json` to phase `implement` only after user approval.
35
+ 5. If the change touches UI, check accessibility and responsive behavior.
36
+ 6. If the change touches dependencies, verify current official docs.
38
37
 
39
38
  ## Refactor Rules
40
39
 
@@ -40,9 +40,10 @@ Grounded in: WCAG 2.2 AA (accessibility), Fowler's Money Pattern (monetary types
40
40
  ## Frontend
41
41
 
42
42
  - Match the project's existing styling paradigm (Tailwind, CSS Modules, Vanilla CSS, styled-components, etc.). Do not introduce a new CSS framework or build tool without explicit user confirmation.
43
- - Semantic HTML before custom components.
44
- - WCAG 2.2 AA is the accessibility floor.
45
- - Responsive by default. Handle empty, loading, error, and offline states.
43
+ - UI Component Reusability: Primitive UI elements (buttons, inputs, cards, dialogs, badges) must have a single source of truth in the shared component directory (`components/` or `ui/`). Never recreate ad-hoc variants or duplicate JSX structures across individual pages. Extend existing components with props or variants instead of cloning.
44
+ - Design Consistency: Consume shared design tokens, CSS variables, or theme configuration for colors, spacing, and border-radius. Do not hardcode arbitrary raw color hexes or inconsistent spacing that causes visual design drift between pages.
45
+ - Data-fetching components must explicitly handle 3 states: loading, error (with user-facing toast/notification and retry option), and data. Never leave an unhandled error state.
46
+ - WCAG 2.2 AA accessibility floor. Responsive by default.
46
47
  - No placeholder, lorem, or TODO content in production UI.
47
48
 
48
49
  ## Infrastructure
@@ -59,10 +60,3 @@ Grounded in: WCAG 2.2 AA (accessibility), Fowler's Money Pattern (monetary types
59
60
  - Circuit breakers for unhealthy dependencies.
60
61
  - Graceful degradation on non-critical dependency failure.
61
62
 
62
- ## Naming
63
-
64
- - Variables and properties are nouns: `userList`, `pageCount`, not `getUser`.
65
- - Functions and methods are verbs: `calculateTotal`, `fetchUsers`, not `total`.
66
- - Booleans prefixed with `is`/`has`/`can`: `isValid`, `hasPermission`.
67
- - Constants in UPPER_SNAKE_CASE: `MAX_RETRIES`, `API_BASE_URL`.
68
- - Follow the casing convention of the language and existing codebase. When starting fresh, use the community default for that language.
@@ -10,12 +10,13 @@ Production-risk code review. Prioritize findings by severity.
10
10
 
11
11
  Grounded in: OWASP Risk Rating Methodology, Google Engineering Practices (code review guide), Clean Architecture (transport vs business layer separation).
12
12
 
13
- ## Before Reviewing
13
+ ## Review Procedure (Empirical First)
14
14
 
15
- 1. Read the changed files and understand the scope.
16
- 2. For UI changes, check accessibility and design consistency.
17
- 3. For API changes, check contract stability and documentation sync.
18
- 4. Walk the decision ladder for each new file or dependency: does this need to exist, could the stdlib or an existing dependency handle it?
15
+ 1. **Establish Scope**: Run `git diff --stat` (or `git status`) to inspect the exact set of changed files and line deltas.
16
+ 2. **Test-Change Correlation**: For every modified application source file, check if a corresponding test file was updated. If application logic changed without test updates, flag as Severity 3 ("Missing tests for changed behavior").
17
+ 3. **Run Deterministic Checks**: Run the project linter and test suite (`ascx test` / `npm test`). Do not evaluate architectural quality on a failing test suite.
18
+ 4. **Security & Invariants Scan**: Check for unverified `ASC-STUB:`, hardcoded credentials, or empty catch blocks in the diff.
19
+ 5. **Contract & Hierarchy**: Walk the decision ladder for each new file or dependency: does this need to exist, could the stdlib or an existing dependency handle it?
19
20
 
20
21
  ## Finding Priority Order
21
22
 
@@ -8,7 +8,6 @@
8
8
  * uninstall Remove ASC adapter files from the current project
9
9
  * clean Remove v4 per-project artifacts (.agent-context/, bridge files)
10
10
  * status Show detected IDEs and install hints
11
- * mcp Start MCP stdio server
12
11
  */
13
12
  import { exit } from 'node:process';
14
13
  import { readFileSync } from 'node:fs';
@@ -37,7 +36,6 @@ function printUsage() {
37
36
  console.log(' uninstall Remove ASC adapter files and git hooks from this project');
38
37
  console.log(' clean Remove v4 per-project artifacts');
39
38
  console.log(' status Show detected IDEs and install hints');
40
- console.log(' mcp Start MCP stdio server');
41
39
  console.log(' --version Show version');
42
40
  console.log(' --help Show this help');
43
41
  }
@@ -92,12 +90,6 @@ async function main() {
92
90
  return;
93
91
  }
94
92
 
95
- if (commandArgument === 'mcp') {
96
- const { runMcpServerCommand } = await import('../lib/cli/commands/mcp.mjs');
97
- await runMcpServerCommand();
98
- return;
99
- }
100
-
101
93
  console.error(`Unknown command: ${commandArgument}`);
102
94
  printUsage();
103
95
  exit(1);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-senior-core",
3
- "version": "6.10.0",
3
+ "version": "6.11.1",
4
4
  "description": "Universal AI coding rules. Write code like a staff engineer.",
5
5
  "author": "fatidaprilian",
6
6
  "license": "MIT",
@@ -202,6 +202,33 @@ function checkLargeFiles(stagedFiles, cwd, maxSizeKB) {
202
202
  }
203
203
  }
204
204
 
205
+ function checkStubsAndTodos(stagedFiles, cwd) {
206
+ var STUB_REGEX = /(?:\\/\\/|#|\\/\\*)\\s*ASC-STUB:(?!.*\\b(ASC-DEBT|#\\d+|[A-Z]+-\\d+)\\b)/i;
207
+ var MOCK_SUCCESS_REGEX = /(?:return\\s*\\{\\s*success:\\s*true\\s*\\}|return\\s*True|return\\s*true|return\\s*nil)\\s*;?\\s*(?:\\/\\/|#).*?(mock|fake|stub|placeholder)/i;
208
+
209
+ for (var i = 0; i < stagedFiles.length; i++) {
210
+ var ext = path.extname(stagedFiles[i]).slice(1).toLowerCase();
211
+ if (!SOURCE_EXTENSIONS.has(ext)) continue;
212
+ try {
213
+ var content = fs.readFileSync(path.resolve(cwd, stagedFiles[i]), 'utf8');
214
+ var lines = content.split('\\n');
215
+ for (var l = 0; l < lines.length; l++) {
216
+ var line = lines[l];
217
+ if (STUB_REGEX.test(line)) {
218
+ console.error('\\x1b[31m[ASC Stub Gate]\\x1b[0m Unverified stub detected in ' + stagedFiles[i] + ' line ' + (l + 1) + ': ' + line.trim());
219
+ console.error('\\x1b[33mCommit blocked. Stubs must carry a tracked debt ID: // ASC-STUB: [reason] [ASC-DEBT-xxx]. Use git commit --no-verify to bypass.\\x1b[0m');
220
+ process.exit(1);
221
+ }
222
+ if (MOCK_SUCCESS_REGEX.test(line)) {
223
+ console.error('\\x1b[31m[ASC Fake-Done Gate]\\x1b[0m Simulated success return detected in ' + stagedFiles[i] + ' line ' + (l + 1) + ': ' + line.trim());
224
+ console.error('\\x1b[33mCommit blocked. Never commit hardcoded mock success returns mimicking live integration. Use git commit --no-verify to bypass.\\x1b[0m');
225
+ process.exit(1);
226
+ }
227
+ }
228
+ } catch (_) {}
229
+ }
230
+ }
231
+
205
232
  function runJscpdScan(scanCmd, cwd, tmpDir) {
206
233
  const binaries = ['bunx jscpd', 'npx jscpd@5', 'npx jscpd'];
207
234
  for (let i = 0; i < binaries.length; i++) {
@@ -318,6 +345,7 @@ function runPreCommitGate() {
318
345
  checkSecrets(stagedFiles, cwd);
319
346
  checkMergeConflictMarkers(stagedFiles, cwd);
320
347
  checkLargeFiles(stagedFiles, cwd, config.maxFileSizeKB);
348
+ checkStubsAndTodos(stagedFiles, cwd);
321
349
 
322
350
  // 2. Filter staged files by SOURCE_EXTENSIONS for dedup scan
323
351
  const stagedSourceFiles = stagedFiles.filter(f => {
@@ -442,6 +470,13 @@ export function installGlobalGitPreCommitHook({ homeDir = os.homedir() } = {}) {
442
470
  fs.mkdirSync(globalHooksDir, { recursive: true });
443
471
  }
444
472
 
473
+ // Generate standalone universal runner in global directory for fallback
474
+ const globalRunnerPath = path.join(globalHooksDir, 'pre-commit-runner.cjs');
475
+ const runnerScriptContent = generatePreCommitRunnerScript();
476
+ fs.writeFileSync(globalRunnerPath, runnerScriptContent, { encoding: 'utf8', mode: 0o755 });
477
+
478
+ const globalRunnerPosix = globalRunnerPath.replace(/\\/g, '/');
479
+
445
480
  const hookPath = path.join(globalHooksDir, 'pre-commit');
446
481
  const dispatcherContent = `#!/bin/sh
447
482
  ${ASC_HOOK_HEADER} -- Global Smart Dispatcher
@@ -476,13 +511,16 @@ if [ -n "$LOCAL_HOOK" ]; then
476
511
  fi
477
512
  fi
478
513
 
479
- # 3. Run ASC workspace pre-commit runner if present
514
+ # 3. Run ASC workspace pre-commit runner if present, or fallback to global runner
480
515
  if [ -n "$GIT_ROOT" ] && [ -f "$GIT_ROOT/.asc/hooks/pre-commit-runner.cjs" ]; then
481
516
  node "$GIT_ROOT/.asc/hooks/pre-commit-runner.cjs" "$@"
482
517
  exit $?
483
518
  elif [ -f ".asc/hooks/pre-commit-runner.cjs" ]; then
484
519
  node .asc/hooks/pre-commit-runner.cjs "$@"
485
520
  exit $?
521
+ elif [ -f "${globalRunnerPosix}" ]; then
522
+ node "${globalRunnerPosix}" "$@"
523
+ exit $?
486
524
  fi
487
525
 
488
526
  exit 0
@@ -497,6 +535,6 @@ exit 0
497
535
  return { installed: false, hookPath, reason: 'Could not set git config --global core.hooksPath' };
498
536
  }
499
537
 
500
- return { installed: true, hookPath, global: true };
538
+ return { installed: true, hookPath, runnerPath: globalRunnerPath, global: true };
501
539
  }
502
540
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryuenn3123/agentic-senior-core",
3
- "version": "6.10.0",
3
+ "version": "6.11.1",
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": {
@@ -16,8 +16,6 @@
16
16
  "gemini-extension.json",
17
17
  "plugin.yaml",
18
18
  "__init__.py",
19
- "scripts/mcp-server.mjs",
20
- "scripts/mcp-server/",
21
19
  "scripts/uninstall.js",
22
20
  "README.md",
23
21
  "LICENSE",
package/plugin.yaml CHANGED
@@ -1,5 +1,5 @@
1
1
  name: agentic-senior-core
2
- version: 6.10.0
2
+ version: 6.11.1
3
3
  description: Universal AI coding rules. Write code like a staff engineer.
4
4
  author: fatidaprilian
5
5
  provides_hooks:
@@ -1,3 +0,0 @@
1
- export async function runMcpServerCommand() {
2
- await import('../../../scripts/mcp-server.mjs');
3
- }
@@ -1,57 +0,0 @@
1
- // @ts-check
2
-
3
- import { existsSync, readFileSync } from 'node:fs';
4
- import { dirname, resolve } from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
-
7
- const SCRIPT_FILE_PATH = fileURLToPath(import.meta.url);
8
- export const REPOSITORY_ROOT = resolve(dirname(SCRIPT_FILE_PATH), '..', '..');
9
- export const STATE_DIRECTORY = resolve(REPOSITORY_ROOT, '.agent-context', 'state');
10
- export const DEFAULT_PROTOCOL_VERSION = '2024-11-05';
11
- export const DEFAULT_FETCH_TIMEOUT_MS = 15000;
12
- export const DEFAULT_FETCH_MAX_CHARS = 6000;
13
- export const MAX_FETCH_MAX_CHARS = 20000;
14
- export const DEFAULT_TREND_WINDOW_DAYS = 90;
15
- export const MAX_TREND_PACKAGES = 10;
16
- export const FALLBACK_PACKAGE_VERSION = '0.0.0-local';
17
-
18
- // IMPORTANT: This version extraction logic is intentionally duplicated from lib/cli/constants.mjs.
19
- // The MCP server is designed to be copied directly into target user workspaces where
20
- // the original package.json may not exist in the parent tree. This try/catch fallback
21
- // ensures the server can still run standalone without crashing if package.json is missing.
22
- function resolvePackageVersion() {
23
- try {
24
- const parsedPackageManifest = JSON.parse(
25
- readFileSync(resolve(REPOSITORY_ROOT, 'package.json'), 'utf8')
26
- );
27
- const rawVersion = typeof parsedPackageManifest?.version === 'string'
28
- ? parsedPackageManifest.version.trim()
29
- : '';
30
-
31
- return rawVersion || FALLBACK_PACKAGE_VERSION;
32
- } catch {
33
- return FALLBACK_PACKAGE_VERSION;
34
- }
35
- }
36
-
37
- export const PACKAGE_VERSION = resolvePackageVersion();
38
-
39
- export const TEST_SUITE_ARGS = {
40
- adapter: ['--test', './tests/adapter.test.mjs'],
41
- };
42
-
43
- export const INTERNAL_SCRIPT_PATHS = {};
44
-
45
- function getAvailableTestSuites() {
46
- return Object.entries(TEST_SUITE_ARGS)
47
- .filter(([, commandArguments]) => (
48
- Array.isArray(commandArguments)
49
- && commandArguments.length > 1
50
- && commandArguments
51
- .slice(1)
52
- .every((relativeTestPath) => existsSync(resolve(REPOSITORY_ROOT, relativeTestPath)))
53
- ))
54
- .map(([suiteName]) => suiteName);
55
- }
56
-
57
- export const AVAILABLE_TEST_SUITES = getAvailableTestSuites();
@@ -1,204 +0,0 @@
1
- // @ts-check
2
-
3
- import { existsSync } from 'node:fs';
4
- import { AVAILABLE_TEST_SUITES, INTERNAL_SCRIPT_PATHS } from './constants.mjs';
5
-
6
- export function buildToolDefinitions() {
7
- const toolDefinitions = [];
8
-
9
- if (existsSync(INTERNAL_SCRIPT_PATHS.validate)) {
10
- toolDefinitions.push({
11
- name: 'validate',
12
- description: 'Run repository validation checks.',
13
- inputSchema: {
14
- type: 'object',
15
- properties: {},
16
- additionalProperties: false,
17
- },
18
- });
19
- }
20
-
21
- if (AVAILABLE_TEST_SUITES.length > 0) {
22
- toolDefinitions.push({
23
- name: 'test',
24
- description: 'Run test suites (full or targeted).',
25
- inputSchema: {
26
- type: 'object',
27
- properties: {
28
- suite: {
29
- type: 'string',
30
- enum: AVAILABLE_TEST_SUITES,
31
- description: 'Target test suite. Defaults to the first available suite.',
32
- },
33
- },
34
- additionalProperties: false,
35
- },
36
- });
37
- }
38
-
39
- if (existsSync(INTERNAL_SCRIPT_PATHS.release_gate)) {
40
- toolDefinitions.push({
41
- name: 'release_gate',
42
- description: 'Run release gate checks.',
43
- inputSchema: {
44
- type: 'object',
45
- properties: {},
46
- additionalProperties: false,
47
- },
48
- });
49
- }
50
-
51
- if (existsSync(INTERNAL_SCRIPT_PATHS.forbidden_content_check)) {
52
- toolDefinitions.push({
53
- name: 'forbidden_content_check',
54
- description: 'Run forbidden content scan used by publish gate.',
55
- inputSchema: {
56
- type: 'object',
57
- properties: {},
58
- additionalProperties: false,
59
- },
60
- });
61
- }
62
-
63
- toolDefinitions.push(
64
- {
65
- name: 'lookup_rule',
66
- description: 'Look up a canonical .agent-context rule section by stable rule ID.',
67
- inputSchema: {
68
- type: 'object',
69
- properties: {
70
- ruleId: {
71
- type: 'string',
72
- description: 'Stable rule section ID, such as ARCH-003 or API-001.',
73
- },
74
- },
75
- required: ['ruleId'],
76
- additionalProperties: false,
77
- },
78
- },
79
- {
80
- name: 'validate_against_rules',
81
- description: 'Validate that cited rule IDs resolve to canonical rule sections.',
82
- inputSchema: {
83
- type: 'object',
84
- properties: {
85
- ruleIds: {
86
- type: 'array',
87
- items: { type: 'string' },
88
- description: 'Rule IDs cited by a response, plan, or review.',
89
- },
90
- summary: {
91
- type: 'string',
92
- description: 'Optional one-line context for the validation request.',
93
- },
94
- },
95
- required: ['ruleIds'],
96
- additionalProperties: false,
97
- },
98
- },
99
- {
100
- name: 'audit_compliance',
101
- description: 'Run a lightweight compliance audit over cited rule IDs and scope labels.',
102
- inputSchema: {
103
- type: 'object',
104
- properties: {
105
- ruleIds: {
106
- type: 'array',
107
- items: { type: 'string' },
108
- description: 'Rule IDs used as the compliance basis.',
109
- },
110
- scope: {
111
- type: 'string',
112
- description: 'Optional changed scope label, such as api, security, testing, architecture, ui, or release.',
113
- },
114
- },
115
- required: ['ruleIds'],
116
- additionalProperties: false,
117
- },
118
- },
119
- {
120
- name: 'research_fetch',
121
- description: 'Fetch external documentation/news content and return query-focused excerpts with citation metadata.',
122
- inputSchema: {
123
- type: 'object',
124
- properties: {
125
- url: {
126
- type: 'string',
127
- description: 'Absolute HTTP/HTTPS URL to fetch.',
128
- },
129
- query: {
130
- type: 'string',
131
- description: 'Optional search query used to extract focused excerpts.',
132
- },
133
- maxChars: {
134
- type: 'integer',
135
- description: 'Maximum characters to return when query is not provided (default 6000, max 20000).',
136
- },
137
- },
138
- required: ['url'],
139
- additionalProperties: false,
140
- },
141
- },
142
- {
143
- name: 'trend_snapshot',
144
- description: 'Generate ecosystem trend snapshot from npm registry metadata with source timestamps.',
145
- inputSchema: {
146
- type: 'object',
147
- properties: {
148
- packages: {
149
- type: 'array',
150
- items: { type: 'string' },
151
- description: 'Package names to inspect (max 10).',
152
- },
153
- windowDays: {
154
- type: 'integer',
155
- description: 'Release activity window in days (default 90).',
156
- },
157
- },
158
- required: ['packages'],
159
- additionalProperties: false,
160
- },
161
- },
162
- {
163
- name: 'state_read',
164
- description: 'Read a file from .agent-context/state for cross-session continuity.',
165
- inputSchema: {
166
- type: 'object',
167
- properties: {
168
- path: {
169
- type: 'string',
170
- description: 'Path relative to .agent-context/state, such as memory-continuity-benchmark.json.',
171
- },
172
- },
173
- required: ['path'],
174
- additionalProperties: false,
175
- },
176
- },
177
- {
178
- name: 'state_write',
179
- description: 'Write a file under .agent-context/state for cross-session continuity updates.',
180
- inputSchema: {
181
- type: 'object',
182
- properties: {
183
- path: {
184
- type: 'string',
185
- description: 'Path relative to .agent-context/state.',
186
- },
187
- content: {
188
- type: 'string',
189
- description: 'UTF-8 content to write.',
190
- },
191
- mode: {
192
- type: 'string',
193
- enum: ['overwrite', 'append'],
194
- description: 'Write mode. Defaults to overwrite.',
195
- },
196
- },
197
- required: ['path', 'content'],
198
- additionalProperties: false,
199
- },
200
- },
201
- );
202
-
203
- return toolDefinitions;
204
- }