Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Changelog

All notable changes to agent-core are documented here.

Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]

## [0.4.0] - 2026-03-22

### Changed

- Bumped `ANALYZER_MIN_VERSION` to `v0.3.0` in `lib/binary/version.js`. v0.3.0 adds Phase 2-4 of agent-analyzer: AST symbol extraction (6 languages), project metadata, and doc-code cross-references. New query subcommands available: `symbols`, `dependents`, `stale-docs`, `project-info`.

## [0.3.0] - 2026-03-16

### Fixed

- Removed misleading `AUTO-GENERATED - do not edit directly` comment from `templates/CLAUDE.md.tmpl`. Plugin repos are expected to edit the generated file; the comment was incorrect.
- Removed redundant `Be concise` clause from rule 8 in the template (flagged by agnix as redundant).

## [0.2.0] - 2026-03-15

### Added

- `lib/binary/` - Binary resolver for the `agent-analyzer` Rust binary. Handles lazy download from GitHub releases at runtime (no postinstall hook). Supports 5 platform targets, `tar.gz`/`zip` extraction, version checking, and auto-upgrade. Uses only Node.js built-ins; zero external npm dependencies. Exports `ensureBinary`, `runAnalyzer`, and related utilities.
- `lib/collectors/git.js` - Git history collector that runs `agent-analyzer repo-intel init` and extracts health metrics: hotspots, contributors, AI ratio, bus factor, conventions, and release info. Registered in the `collect()` dispatch in `lib/collectors/index.js`.

### Changed

- Updated `lib/collectors/git.js` for the `RepoIntelData` schema: added `recentChanges` to hotspot output and `confidence` field to `aiAttribution`.

## [0.1.1] - 2026-03-06

### Added

- Added `agent-knowledge` as a git submodule, centralizing the knowledge base in [agent-sh/agent-knowledge](https://github.com/agent-sh/agent-knowledge) and sharing it across all plugin repos.

## [0.1.0] - 2026-02-22

### Added

- CI workflow calling the reusable workflow from `agent-sh/.github`.
- Automated Claude Code PR review (restricted to owner/member/collaborator, max 3 runs per PR).
- Claude Code `@mentions` support in PR comments.
- Pre-push hook that runs tests before push.
- agnix validation step in the CI pipeline.
- CLAUDE.md sync: template (`templates/CLAUDE.md.tmpl`) and generator script (`scripts/generate-claudemd.js`) that produce a consistent `CLAUDE.md` for each consumer plugin repo during the sync workflow.
- Extended sync matrix to all 12 graduated plugin repos.

## [0.0.1] - 2026-02-21

### Added

- Initial seed: `lib/` directory ported from agentsys, covering platform detection, pattern matching, workflow state, collectors, adapters, and utilities.
- Sync workflow that triggers `lib/` propagation to consumer repos on push to `main`.

[Unreleased]: https://github.com/agent-sh/agent-core/compare/v0.4.0...HEAD
[0.4.0]: https://github.com/agent-sh/agent-core/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/agent-sh/agent-core/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/agent-sh/agent-core/compare/v0.1.1...v0.2.0
[0.1.1]: https://github.com/agent-sh/agent-core/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/agent-sh/agent-core/compare/v0.0.1...v0.1.0
[0.0.1]: https://github.com/agent-sh/agent-core/releases/tag/v0.0.1
29 changes: 0 additions & 29 deletions lib/repo-map/concurrency.js

This file was deleted.

130 changes: 130 additions & 0 deletions lib/repo-map/converter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
'use strict';

/**
* Convert agent-analyzer repo-intel.json format to repo-map.json format.
*
* agent-analyzer outputs: { symbols: { [filePath]: { exports, imports, definitions } } }
* repo-map expects: { files: { [filePath]: { language, symbols, imports } } }
*
* @module lib/repo-map/converter
*/

const path = require('path');

const LANGUAGE_BY_EXTENSION = {
'.js': 'javascript', '.jsx': 'javascript', '.mjs': 'javascript', '.cjs': 'javascript',
'.ts': 'typescript', '.tsx': 'typescript', '.mts': 'typescript', '.cts': 'typescript',
'.py': 'python', '.pyw': 'python',
'.rs': 'rust',
'.go': 'go',
'.java': 'java'
};

// SymbolKind values from agent-analyzer (kebab-case serialized)
const CLASS_KINDS = new Set(['class', 'struct', 'interface', 'enum', 'impl']);
const TYPE_KINDS = new Set(['trait', 'type-alias']);
const FUNCTION_LIKE_KINDS = new Set(['method', 'arrow', 'closure']);
const CONSTANT_KINDS = new Set(['constant', 'variable', 'const', 'field', 'property']);

function detectLanguage(filePath) {
return LANGUAGE_BY_EXTENSION[path.extname(filePath).toLowerCase()] || 'unknown';
}

function detectLanguagesFromFiles(filePaths) {
const langs = new Set();
for (const fp of filePaths) {
const lang = detectLanguage(fp);
if (lang !== 'unknown') langs.add(lang);
}
return Array.from(langs);
}

/**
* Convert a single file's symbols from repo-intel format to repo-map format.
* @param {string} filePath
* @param {Object} fileSym - { exports, imports, definitions }
* @returns {Object} repo-map file entry
*/
function convertFile(filePath, fileSym) {
const exportNames = new Set((fileSym.exports || []).map(e => e.name));

const exports = (fileSym.exports || []).map(e => ({
name: e.name,
kind: e.kind,
line: e.line
}));

const functions = [];
const classes = [];
const types = [];
const constants = [];

for (const def of fileSym.definitions || []) {
const entry = {
name: def.name,
kind: def.kind,
line: def.line,
exported: exportNames.has(def.name)
};
if (def.kind === 'function' || FUNCTION_LIKE_KINDS.has(def.kind)) {
functions.push(entry);
} else if (CLASS_KINDS.has(def.kind)) {
classes.push(entry);
} else if (TYPE_KINDS.has(def.kind)) {
types.push(entry);
} else if (CONSTANT_KINDS.has(def.kind)) {
constants.push(entry);
} else {
// Unknown kind - default to constants for backward compat
constants.push(entry);
}
}

// agent-analyzer imports: [{ from, names }] → repo-map imports: [{ source, kind, names }]
const imports = (fileSym.imports || []).map(imp => ({
source: imp.from,
kind: 'import',
names: imp.names || []
}));

return {
language: detectLanguage(filePath),
symbols: { exports, functions, classes, types, constants },
imports
};
}

/**
* Convert a full repo-intel data object to repo-map format.
* @param {Object} intel - RepoIntelData from agent-analyzer
* @returns {Object} repo-map.json compatible object
*/
function convertIntelToRepoMap(intel) {
const files = {};
let totalSymbols = 0;
let totalImports = 0;

for (const [filePath, fileSym] of Object.entries(intel.symbols || {})) {
files[filePath] = convertFile(filePath, fileSym);
const s = files[filePath].symbols;
totalSymbols += s.functions.length + s.classes.length +
s.types.length + s.constants.length;
totalImports += files[filePath].imports.length;
}

return {
version: '2.0',
generated: intel.generated || new Date().toISOString(),
git: intel.git ? { commit: intel.git.analyzedUpTo } : undefined,
project: { languages: detectLanguagesFromFiles(Object.keys(files)) },
stats: {
totalFiles: Object.keys(files).length,
totalSymbols,
totalImports,
errors: []
},
files
};
}

module.exports = { convertIntelToRepoMap, convertFile, detectLanguage };
Loading
Loading