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
2 changes: 1 addition & 1 deletion .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Validate commit message with commitlint
# npx --no -- commitlint --edit $1
pnpm exec commitlint --edit $1
23 changes: 9 additions & 14 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,32 @@
## [0.10.1](https://github.com/drivecore/mycoder/compare/v0.10.0...v0.10.1) (2025-03-11)


### Bug Fixes

* token caching ([5972e59](https://github.com/drivecore/mycoder/commit/5972e59ab572040e564d1756ab8a5625215e14dc))
- token caching ([5972e59](https://github.com/drivecore/mycoder/commit/5972e59ab572040e564d1756ab8a5625215e14dc))

# [0.10.0](https://github.com/drivecore/mycoder/compare/v0.9.0...v0.10.0) (2025-03-11)


### Bug Fixes

* add deepmerge to cli package.json ([ab66377](https://github.com/drivecore/mycoder/commit/ab66377342c9f23fa874d2776e73d365141e8801))
* update hierarchical configuration system to fix failing tests ([93d949c](https://github.com/drivecore/mycoder/commit/93d949c03b7ebe96bad36713f6476c38d2a35224))

- add deepmerge to cli package.json ([ab66377](https://github.com/drivecore/mycoder/commit/ab66377342c9f23fa874d2776e73d365141e8801))
- update hierarchical configuration system to fix failing tests ([93d949c](https://github.com/drivecore/mycoder/commit/93d949c03b7ebe96bad36713f6476c38d2a35224))

### Features

* add back token tracking, system prompt caching. ([ddc04ab](https://github.com/drivecore/mycoder/commit/ddc04ab0778eb2f571897e825c8d8ba17651db09))
* add showStdIn and showStdout options to shellMessage and shellStart ([aed1b9f](https://github.com/drivecore/mycoder/commit/aed1b9f6ba489da19f2170c136861a7c80ad6e33)), closes [#167](https://github.com/drivecore/mycoder/issues/167)
* add token caching. issue 145 ([d78723b](https://github.com/drivecore/mycoder/commit/d78723bb6d0514110088caf7009e196e3f79769e))
* implement hierarchical configuration system ([84d73d1](https://github.com/drivecore/mycoder/commit/84d73d1e6324670890a203f455fe257aeb6ed07a)), closes [#153](https://github.com/drivecore/mycoder/issues/153)
- add back token tracking, system prompt caching. ([ddc04ab](https://github.com/drivecore/mycoder/commit/ddc04ab0778eb2f571897e825c8d8ba17651db09))
- add showStdIn and showStdout options to shellMessage and shellStart ([aed1b9f](https://github.com/drivecore/mycoder/commit/aed1b9f6ba489da19f2170c136861a7c80ad6e33)), closes [#167](https://github.com/drivecore/mycoder/issues/167)
- add token caching. issue 145 ([d78723b](https://github.com/drivecore/mycoder/commit/d78723bb6d0514110088caf7009e196e3f79769e))
- implement hierarchical configuration system ([84d73d1](https://github.com/drivecore/mycoder/commit/84d73d1e6324670890a203f455fe257aeb6ed07a)), closes [#153](https://github.com/drivecore/mycoder/issues/153)

# [0.9.0](https://github.com/drivecore/mycoder/compare/v0.8.0...v0.9.0) (2025-03-11)


### Bug Fixes

* don't save consent when using --userWarning=false ([41cf69d](https://github.com/drivecore/mycoder/commit/41cf69dee22acc31cd0f2aa9f80e36cd867fb20b))

- don't save consent when using --userWarning=false ([41cf69d](https://github.com/drivecore/mycoder/commit/41cf69dee22acc31cd0f2aa9f80e36cd867fb20b))

### Features

* add CLI options for automated usage scenarios ([00419bc](https://github.com/drivecore/mycoder/commit/00419bc3e060db6d0c18fc72e2d7b6957791c875))
- add CLI options for automated usage scenarios ([00419bc](https://github.com/drivecore/mycoder/commit/00419bc3e060db6d0c18fc72e2d7b6957791c875))

# [0.8.0](https://github.com/drivecore/mycoder/compare/v0.7.0...v0.8.0) (2025-03-11)

Expand Down
2 changes: 1 addition & 1 deletion docs/release-process.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# Release Process with semantic-release-monorepo\n\n## Overview\n\nThis project uses `semantic-release-monorepo` to automate the versioning and release process across all packages in the monorepo. This ensures that each package is versioned independently based on its own changes, while maintaining a consistent release process.\n\n## How It Works\n\n1. When code is pushed to the `release` branch, the GitHub Actions workflow is triggered.\n2. The workflow builds and tests all packages.\n3. `semantic-release-monorepo` analyzes the commit history for each package to determine the next version.\n4. New versions are published to npm, and release notes are generated based on conventional commits.\n5. Git tags are created for each package release.\n\n## Commit Message Format\n\nThis project follows the [Conventional Commits](https://www.conventionalcommits.org/) specification. Your commit messages should be structured as follows:\n\n```\n<type>[optional scope]: <description>\n\n[optional body]\n\n[optional footer(s)]\n```\n\nExamples:\n\n```\nfeat(cli): add new command for project initialization\nfix(agent): resolve issue with async tool execution\ndocs: update installation instructions\n```\n\n### Types\n\n- `feat`: A new feature (triggers a minor version bump)\n- `fix`: A bug fix (triggers a patch version bump)\n- `docs`: Documentation changes\n- `style`: Changes that don't affect the code's meaning (formatting, etc.)\n- `refactor`: Code changes that neither fix a bug nor add a feature\n- `perf`: Performance improvements\n- `test`: Adding or correcting tests\n- `chore`: Changes to the build process, tooling, etc.\n\n### Breaking Changes\n\nIf your commit introduces a breaking change, add `BREAKING CHANGE:` in the footer followed by a description of the change. This will trigger a major version bump.\n\nExample:\n\n```\nfeat(agent): change API for tool execution\n\nBREAKING CHANGE: The tool execution API now requires an options object instead of individual parameters.\n```\n\n## Troubleshooting\n\nIf you encounter issues with the release process:\n\n1. Run `pnpm verify-release-config` to check if your semantic-release configuration is correct.\n2. Ensure your commit messages follow the conventional commits format.\n3. Check if the package has a `.releaserc.json` file that extends `semantic-release-monorepo`.\n4. Verify that each package has a `semantic-release` script in its `package.json`.\n\n## Manual Release\n\nIn rare cases, you might need to trigger a release manually. You can do this by:\n\n```bash\n# Release all packages\npnpm release\n\n# Release a specific package\ncd packages/cli\npnpm semantic-release\n```\n
# Release Process with semantic-release-monorepo\n\n## Overview\n\nThis project uses `semantic-release-monorepo` to automate the versioning and release process across all packages in the monorepo. This ensures that each package is versioned independently based on its own changes, while maintaining a consistent release process.\n\n## How It Works\n\n1. When code is pushed to the `release` branch, the GitHub Actions workflow is triggered.\n2. The workflow builds and tests all packages.\n3. `semantic-release-monorepo` analyzes the commit history for each package to determine the next version.\n4. New versions are published to npm, and release notes are generated based on conventional commits.\n5. Git tags are created for each package release.\n\n## Commit Message Format\n\nThis project follows the [Conventional Commits](https://www.conventionalcommits.org/) specification. Your commit messages should be structured as follows:\n\n`\n<type>[optional scope]: <description>\n\n[optional body]\n\n[optional footer(s)]\n`\n\nExamples:\n\n`\nfeat(cli): add new command for project initialization\nfix(agent): resolve issue with async tool execution\ndocs: update installation instructions\n`\n\n### Types\n\n- `feat`: A new feature (triggers a minor version bump)\n- `fix`: A bug fix (triggers a patch version bump)\n- `docs`: Documentation changes\n- `style`: Changes that don't affect the code's meaning (formatting, etc.)\n- `refactor`: Code changes that neither fix a bug nor add a feature\n- `perf`: Performance improvements\n- `test`: Adding or correcting tests\n- `chore`: Changes to the build process, tooling, etc.\n\n### Breaking Changes\n\nIf your commit introduces a breaking change, add `BREAKING CHANGE:` in the footer followed by a description of the change. This will trigger a major version bump.\n\nExample:\n\n`\nfeat(agent): change API for tool execution\n\nBREAKING CHANGE: The tool execution API now requires an options object instead of individual parameters.\n`\n\n## Troubleshooting\n\nIf you encounter issues with the release process:\n\n1. Run `pnpm verify-release-config` to check if your semantic-release configuration is correct.\n2. Ensure your commit messages follow the conventional commits format.\n3. Check if the package has a `.releaserc.json` file that extends `semantic-release-monorepo`.\n4. Verify that each package has a `semantic-release` script in its `package.json`.\n\n## Manual Release\n\nIn rare cases, you might need to trigger a release manually. You can do this by:\n\n`bash\n# Release all packages\npnpm release\n\n# Release a specific package\ncd packages/cli\npnpm semantic-release\n`\n
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export default ts.config(
'**/.output',
'**/pnpm-lock.yaml',
'**/routeTree.gen.ts',
'scripts/verify-release-config.js',
],
},
);
12 changes: 11 additions & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
{\n \"version\": \"independent\",\n \"npmClient\": \"pnpm\",\n \"command\": {\n \"publish\": {\n \"conventionalCommits\": true,\n \"message\": \"chore(release): publish\"\n }\n },\n \"packages\": [\"packages/*\"]\n}
{
"version": "independent",
"npmClient": "pnpm",
"command": {
"publish": {
"conventionalCommits": true,
"message": "chore(release): publish"
}
},
"packages": ["packages/*"]
}
1 change: 1 addition & 0 deletions lerna.json.bak
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{\n \"version\": \"independent\",\n \"npmClient\": \"pnpm\",\n \"command\": {\n \"publish\": {\n \"conventionalCommits\": true,\n \"message\": \"chore(release): publish\"\n }\n },\n \"packages\": [\"packages/*\"]\n}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
"format": "prettier . --write",
"clean": "pnpm -r clean",
"clean:all": "pnpm -r clean:all && rimraf node_modules",
"cloc": "npx cloc * --exclude-dir=node_modules,dist,.vinxi,.output",
"cloc": "pnpm exec cloc * --exclude-dir=node_modules,dist,.vinxi,.output",
"gcloud-setup": "gcloud auth application-default login && gcloud config set account \"ben@drivecore.ai\" && gcloud config set project drivecore-primary && gcloud config set run/region us-central1",
"cli": "cd packages/cli && node --no-deprecation bin/cli.js",
"prepare": "husky",
"semantic-release": "semantic-release",
"verify-release-config": "node scripts/verify-release-config.js",
"release": "pnpm verify-release-config && npx lerna exec --concurrency 1 -- npx --no-install semantic-release -e semantic-release-monorepo"
"release": "pnpm verify-release-config && pnpm exec lerna exec --concurrency 1 -- pnpm exec semantic-release -e semantic-release-monorepo"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
Expand Down
14 changes: 0 additions & 14 deletions packages/agent/src/core/toolAgent/index.ts

This file was deleted.

8 changes: 7 additions & 1 deletion packages/agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ export * from './tools/interaction/userPrompt.js';
// Core
export * from './core/executeToolCall.js';
export * from './core/types.js';
export * from './core/toolAgent/index.js';
// Tool Agent Core
export { toolAgent } from './core/toolAgent/toolAgentCore.js';
export * from './core/toolAgent/config.js';
export * from './core/toolAgent/messageUtils.js';
export * from './core/toolAgent/toolExecutor.js';
export * from './core/toolAgent/tokenTracking.js';
export * from './core/toolAgent/types.js';

// Utils
export * from './tools/getTools.js';
Expand Down
4 changes: 2 additions & 2 deletions packages/agent/src/tools/interaction/subAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { zodToJsonSchema } from 'zod-to-json-schema';
import {
getDefaultSystemPrompt,
getModel,
toolAgent,
} from '../../core/toolAgent/index.js';
} from '../../core/toolAgent/config.js';
import { toolAgent } from '../../core/toolAgent/toolAgentCore.js';
import { Tool, ToolContext } from '../../core/types.js';
import { getTools } from '../getTools.js';

Expand Down
2 changes: 1 addition & 1 deletion packages/agent/src/utils/logger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe('Logger', () => {
// Setup console spies before each test
consoleSpy = {
log: vi.spyOn(console, 'log').mockImplementation(() => {}),
info: vi.spyOn(console, 'log').mockImplementation(() => {}),
info: vi.spyOn(console, 'info').mockImplementation(() => {}),
warn: vi.spyOn(console, 'warn').mockImplementation(() => {}),
error: vi.spyOn(console, 'error').mockImplementation(() => {}),
};
Expand Down
42 changes: 25 additions & 17 deletions packages/agent/src/utils/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ export const BasicLoggerStyler = {
): string =>
level === LogLevel.debug || level === LogLevel.verbose
? chalk.dim(prefix)
: '',
: prefix,
showPrefix: (_level: LogLevel): boolean => {
// Show prefix for all log levels
return true;
},
};

const loggerStyle = BasicLoggerStyler;
Expand Down Expand Up @@ -93,17 +97,21 @@ export class Logger {
private formatMessages(level: LogLevel, messages: unknown[]): string {
const formatted = this.toStrings(messages);
const messageColor = loggerStyle.getColor(level, this.nesting);
const prefix = loggerStyle.formatPrefix(
`[${this.name}]`,
level,
this.nesting,
);

let combinedPrefix = `${this.prefix}${prefix}`;
if (this.customPrefix) {
combinedPrefix = `${this.prefix}${this.customPrefix} `;
} else if (combinedPrefix.length > 0) {
combinedPrefix += ' ';

let combinedPrefix = this.prefix;

if (loggerStyle.showPrefix(level)) {
const prefix = loggerStyle.formatPrefix(
`[${this.name}]`,
level,
this.nesting,
);

if (this.customPrefix) {
combinedPrefix = `${this.prefix}${this.customPrefix} `;
} else {
combinedPrefix = `${this.prefix}${prefix} `;
}
}

return formatted
Expand All @@ -113,27 +121,27 @@ export class Logger {
}

log(level: LogLevel, ...messages: unknown[]): void {
if (this.logLevelIndex > level) return;
if (level < this.logLevelIndex) return;
console.log(this.formatMessages(level, messages));
}

debug(...messages: unknown[]): void {
if (this.logLevelIndex > LogLevel.debug) return;
if (LogLevel.debug < this.logLevelIndex) return;
console.log(this.formatMessages(LogLevel.debug, messages));
}

verbose(...messages: unknown[]): void {
if (this.logLevelIndex > LogLevel.verbose) return;
if (LogLevel.verbose < this.logLevelIndex) return;
console.log(this.formatMessages(LogLevel.verbose, messages));
}

info(...messages: unknown[]): void {
if (this.logLevelIndex > LogLevel.info) return;
if (LogLevel.info < this.logLevelIndex) return;
console.log(this.formatMessages(LogLevel.info, messages));
}

warn(...messages: unknown[]): void {
if (this.logLevelIndex > LogLevel.warn) return;
if (LogLevel.warn < this.logLevelIndex) return;
console.warn(this.formatMessages(LogLevel.warn, messages));
}

Expand Down
55 changes: 0 additions & 55 deletions packages/cli/src/commands/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { createInterface } from 'readline/promises';

import chalk from 'chalk';
import { Logger } from 'mycoder-agent';

Expand All @@ -14,25 +12,6 @@ import {
} from '../settings/config.js';
import { nameToLogIndex } from '../utils/nameToLogIndex.js';

/**
* Prompts the user for confirmation with a yes/no question
* @param question The question to ask the user
* @returns True if the user confirmed, false otherwise
*/
async function confirm(question: string): Promise<boolean> {
const rl = createInterface({
input: process.stdin,
output: process.stdout,
});

try {
const answer = await rl.question(`${question} (y/N): `);
return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
} finally {
rl.close();
}
}

import type { CommandModule, ArgumentsCamelCase } from 'yargs';

export interface ConfigOptions extends SharedOptions {
Expand Down Expand Up @@ -200,30 +179,6 @@ export const command: CommandModule<SharedOptions, ConfigOptions> = {
// Continue with the operation instead of returning
}

// Check if this is an API key and add a warning
if (argv.key.includes('API_KEY')) {
logger.warn(
chalk.yellow(
'Warning: Storing API keys in configuration is less secure than using environment variables.',
),
);
logger.warn(
chalk.yellow(
'Your API key will be stored in plaintext in the configuration file.',
),
);

// Ask for confirmation
const isConfirmed = await confirm(
'Do you want to continue storing your API key in the configuration?',
);

if (!isConfirmed) {
logger.info('Operation cancelled.');
return;
}
}

// Parse the value based on current type or infer boolean/number
let parsedValue: string | boolean | number = argv.value;

Expand Down Expand Up @@ -277,16 +232,6 @@ export const command: CommandModule<SharedOptions, ConfigOptions> = {
if (argv.command === 'clear') {
// Check if --all flag is provided
if (argv.all) {
// Confirm with the user before clearing all settings
const isConfirmed = await confirm(
'Are you sure you want to clear all configuration settings? This action cannot be undone.',
);

if (!isConfirmed) {
logger.info('Operation cancelled.');
return;
}

try {
// Clear settings at the specified level
clearConfigAtLevel(configLevel);
Expand Down
11 changes: 7 additions & 4 deletions packages/cli/src/settings/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@ export const getSettingsDir = (): string => {
export const getProjectSettingsDir = (): string => {
// Start with the current directory
let currentDir = process.cwd();

// Traverse up the directory tree until we find a .mycoder directory or reach the root
while (currentDir !== path.parse(currentDir).root) {
const projectSettingsDir = path.join(currentDir, '.mycoder');
if (fs.existsSync(projectSettingsDir) && fs.statSync(projectSettingsDir).isDirectory()) {
if (
fs.existsSync(projectSettingsDir) &&
fs.statSync(projectSettingsDir).isDirectory()
) {
return projectSettingsDir;
}
// Move up one directory
currentDir = path.dirname(currentDir);
}

// If we're creating a new project config, use the current directory
return path.join(process.cwd(), '.mycoder');
};
Expand All @@ -39,7 +42,7 @@ export const getProjectSettingsDir = (): string => {
*/
export const isProjectSettingsDirWritable = (): boolean => {
const projectDir = getProjectSettingsDir();

// Check if directory exists
if (fs.existsSync(projectDir)) {
try {
Expand Down
Loading
Loading