Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
0156fe3
Merge branch 'master' into develop
BOTOOM Apr 8, 2026
67b250f
ci: run tests on develop branch but restrict releases to master only
BOTOOM Apr 8, 2026
49acd2e
fix(extension): build hook to copy public assets to correct output di…
BOTOOM Apr 10, 2026
9b99ff7
fix(e2e): use node: prefixed imports for lint compliance
BOTOOM Apr 10, 2026
0c1178b
test(e2e): stabilize session management tests with robust selectors a…
BOTOOM Apr 10, 2026
c0b1686
test(e2e): stabilize chat tests with robust selectors and real UI beh…
BOTOOM Apr 10, 2026
c4a02c0
feat(e2e): add playwright runner script for automated extension rebuild
BOTOOM Apr 10, 2026
dada838
feat(shared): add tone and reasoning effort types to session
BOTOOM Apr 10, 2026
182e161
deps: update dependencies across all packages
BOTOOM Apr 10, 2026
1e610b9
feat(backend): add reasoning effort support and improve session model…
BOTOOM Apr 10, 2026
94bc171
feat(extension): add model switch modal and reasoning effort selector
BOTOOM Apr 10, 2026
0424e9b
refactor(extension): reorganize imports and update components for new…
BOTOOM Apr 10, 2026
2bc16cb
feat(backend): update CLI, native host, and services for new features
BOTOOM Apr 10, 2026
a4638c8
feat(website): update components and add changelog support
BOTOOM Apr 10, 2026
4ad189b
chore: add biome configuration and update backend release workflow
BOTOOM Apr 10, 2026
ea8679b
test(backend): update session service tests for new features
BOTOOM Apr 10, 2026
1d03ea0
chore: ignore TypeScript declaration files in gitignore
BOTOOM Apr 10, 2026
1db1431
chore: add filtered lint and typecheck scripts to root package.json
BOTOOM Apr 10, 2026
f9288ae
fix(extension): resolve hook dependency and type errors in React hooks
BOTOOM Apr 10, 2026
7cb83c1
fix(extension): resolve React accessibility and lint errors in compon…
BOTOOM Apr 10, 2026
8ec2ce4
fix(extension): resolve type errors and lint issues in utility libraries
BOTOOM Apr 10, 2026
5274813
fix(extension): resolve type errors and accessibility issues in entry…
BOTOOM Apr 10, 2026
8d27175
fix(backend): resolve type errors in native messaging host
BOTOOM Apr 10, 2026
019fa17
fix(backend): resolve type errors in chat routes
BOTOOM Apr 10, 2026
6d4fc99
fix(backend): resolve type errors and lint issues in services
BOTOOM Apr 10, 2026
039da0e
fix(backend): resolve lint issues in devops tools
BOTOOM Apr 10, 2026
38af949
chore: apply Biome formatting to configuration files
BOTOOM Apr 10, 2026
6228e7c
test(backend): apply Biome formatting to test files
BOTOOM Apr 10, 2026
f94c8ad
test(extension): apply Biome formatting to test files
BOTOOM Apr 10, 2026
d98bc41
fix(backend): apply Biome formatting to CLI and service files
BOTOOM Apr 10, 2026
444e0e7
style(website): apply Biome formatting to website files
BOTOOM Apr 10, 2026
4e0b44f
chore(shared): apply Biome formatting to shared package files
BOTOOM Apr 10, 2026
6315fd7
chore: apply Biome formatting to scripts
BOTOOM Apr 10, 2026
f099920
test(e2e): apply Biome formatting to E2E test files
BOTOOM Apr 10, 2026
42d4f1f
style(extension): apply Biome formatting to ImageLightbox component
BOTOOM Apr 10, 2026
d83534f
Merge pull request #39 from BOTOOM/feat/dependenciesupdates
BOTOOM Apr 10, 2026
dcca0e4
deps: update vitest to v4.1.4 and @semantic-release/github to v12.0.6
BOTOOM Apr 10, 2026
13db45d
fix: update pnpm-lock.yaml to match package.json changes
BOTOOM Apr 10, 2026
dfe7725
Merge pull request #40 from BOTOOM/feat/dependenciesupdates
BOTOOM Apr 10, 2026
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
17 changes: 9 additions & 8 deletions .github/workflows/backend-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Backend Release

on:
push:
branches: [master]
branches: [master, develop]
paths:
- 'apps/backend/**'
- 'packages/shared/**'
Expand All @@ -18,17 +18,13 @@ on:
type: boolean
default: false

permissions:
contents: write
issues: write
pull-requests: write
id-token: write

jobs:
test:
name: Test & Build
runs-on: ubuntu-latest
if: ${{ !inputs.skip_tests }}
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down Expand Up @@ -60,8 +56,13 @@ jobs:
release:
name: Release & Publish
needs: test
if: ${{ github.event_name != 'pull_request' && (always() && (needs.test.result == 'success' || inputs.skip_tests)) }}
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && (always() && (needs.test.result == 'success' || inputs.skip_tests)) }}
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/extension-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Extension Release

on:
push:
branches: [master]
branches: [master, develop]
paths:
- 'apps/extension/**'
- 'packages/shared/**'
Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:
release:
name: Release
needs: test
if: ${{ github.event_name != 'pull_request' && (always() && (needs.test.result == 'success' || inputs.skip_tests)) }}
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && (always() && (needs.test.result == 'success' || inputs.skip_tests)) }}
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ dist/
.output/
*.tsbuildinfo

# TypeScript declaration files
*.d.ts
*.d.ts.map

# WXT
.wxt/

Expand Down
18 changes: 9 additions & 9 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,41 +43,41 @@
"test": "vitest",
"test:coverage": "vitest --coverage",
"typecheck": "tsc --noEmit",
"lint": "eslint src/",
"lint": "biome check src/",
"clean": "rm -rf dist",
"prepublishOnly": "pnpm run build",
"release": "semantic-release"
},
"dependencies": {
"@fastify/cors": "^10.0.2",
"@github/copilot": "^1.0.7",
"@github/copilot-sdk": "^0.1.32",
"@github/copilot": "^1.0.20",
"@github/copilot-sdk": "^0.2.1",
"better-sqlite3": "^11.7.0",
"drizzle-orm": "^0.38.4",
"fastify": "^5.8.1",
"drizzle-orm": "^0.41.0",
"fastify": "^5.8.4",
"pino": "^9.6.0",
"pino-pretty": "^13.0.0",
"sharp": "^0.34.5",
"zod": "^3.24.1"
"zod": "^3.25.0"
},
"devDependencies": {
"@devmentorai/shared": "workspace:*",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/commit-analyzer": "^13.0.1",
"@semantic-release/exec": "^7.1.0",
"@semantic-release/git": "^10.0.1",
"@semantic-release/github": "^12.0.5",
"@semantic-release/github": "^12.0.6",
"@semantic-release/npm": "^13.1.4",
"@semantic-release/release-notes-generator": "^14.1.0",
"@types/better-sqlite3": "^7.6.12",
"@types/node": "^22.10.5",
"@types/sharp": "^0.32.0",
"conventional-changelog-conventionalcommits": "^9.1.0",
"drizzle-kit": "^0.30.2",
"drizzle-kit": "^0.31.0",
"semantic-release": "^25.0.3",
"tsup": "^8.5.1",
"tsx": "^4.19.2",
"typescript": "^5.7.3",
"vitest": "^2.1.8"
"vitest": "^4.1.4"
}
}
24 changes: 17 additions & 7 deletions apps/backend/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
* doctor Check system requirements
*/

import { doctorCommand } from './cli/doctor.js';
import { logsCommand } from './cli/logs.js';
import { startCommand } from './cli/start.js';
import { stopCommand } from './cli/stop.js';
import { statusCommand } from './cli/status.js';
import { logsCommand } from './cli/logs.js';
import { doctorCommand } from './cli/doctor.js';
import { stopCommand } from './cli/stop.js';

const VERSION = '1.0.0';

Expand Down Expand Up @@ -60,7 +60,17 @@ async function main(): Promise<void> {
process.exit(0);
}

const options = parseOptions(args.slice(command === 'start' || command === 'stop' || command === 'status' || command === 'logs' || command === 'doctor' ? 1 : 0));
const options = parseOptions(
args.slice(
command === 'start' ||
command === 'stop' ||
command === 'status' ||
command === 'logs' ||
command === 'doctor'
? 1
: 0
)
);

try {
switch (command) {
Expand Down Expand Up @@ -102,8 +112,8 @@ function parseOptions(args: string[]): CliOptions {
for (let i = 0; i < args.length; i++) {
switch (args[i]) {
case '--port':
options.port = parseInt(args[++i], 10);
if (isNaN(options.port)) {
options.port = Number.parseInt(args[++i], 10);
if (Number.isNaN(options.port)) {
console.error('Error: --port requires a valid number');
process.exit(1);
}
Expand All @@ -114,7 +124,7 @@ function parseOptions(args: string[]): CliOptions {
break;
case '--lines':
case '-n':
options.lines = parseInt(args[++i], 10);
options.lines = Number.parseInt(args[++i], 10);
break;
}
}
Expand Down
31 changes: 23 additions & 8 deletions apps/backend/src/cli/doctor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import { execSync } from 'node:child_process';
import fs from 'node:fs';
import net from 'node:net';
import { DATA_DIR, LOG_DIR, IMAGES_DIR } from '../lib/paths.js';
import { DEFAULT_CONFIG } from '@devmentorai/shared';
import { DATA_DIR, IMAGES_DIR, LOG_DIR } from '../lib/paths.js';

const DEFAULT_PORT = DEFAULT_CONFIG.DEFAULT_PORT;

Expand Down Expand Up @@ -90,9 +90,17 @@ function checkPort(port: number): Promise<CheckResult> {
const server = net.createServer();
server.once('error', (err: NodeJS.ErrnoException) => {
if (err.code === 'EADDRINUSE') {
resolve({ name: `Port ${port}`, status: 'warn', message: `Port ${port} is in use (server may already be running)` });
resolve({
name: `Port ${port}`,
status: 'warn',
message: `Port ${port} is in use (server may already be running)`,
});
} else {
resolve({ name: `Port ${port}`, status: 'fail', message: `Cannot bind port ${port}: ${err.message}` });
resolve({
name: `Port ${port}`,
status: 'fail',
message: `Cannot bind port ${port}: ${err.message}`,
});
}
});
server.once('listening', () => {
Expand All @@ -106,12 +114,19 @@ function checkPort(port: number): Promise<CheckResult> {

function checkCopilotCli(): CheckResult {
try {
const version = execSync('github-copilot --version 2>/dev/null || copilot --version 2>/dev/null', {
encoding: 'utf-8',
timeout: 5000,
}).trim();
const version = execSync(
'github-copilot --version 2>/dev/null || copilot --version 2>/dev/null',
{
encoding: 'utf-8',
timeout: 5000,
}
).trim();
return { name: 'Copilot CLI', status: 'pass', message: version || 'installed' };
} catch {
return { name: 'Copilot CLI', status: 'warn', message: 'Not found — server will run in mock mode' };
return {
name: 'Copilot CLI',
status: 'warn',
message: 'Not found — server will run in mock mode',
};
}
}
2 changes: 1 addition & 1 deletion apps/backend/src/cli/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
*/

import fs from 'node:fs';
import { LOG_FILE } from '../lib/paths.js';
import type { CliOptions } from '../cli.js';
import { LOG_FILE } from '../lib/paths.js';

export async function logsCommand(options: CliOptions): Promise<void> {
const lines = options.lines || 50;
Expand Down
12 changes: 6 additions & 6 deletions apps/backend/src/cli/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
* Starts the DevMentorAI server in background or foreground mode.
*/

import { DEFAULT_CONFIG, checkForUpdate } from '@devmentorai/shared';
import type { CliOptions } from '../cli.js';
import { isServerRunning, spawnServer, waitForHealthy } from '../lib/daemon.js';
import { LOG_FILE } from '../lib/paths.js';
import { DEFAULT_CONFIG, checkForUpdate } from '@devmentorai/shared';
import { BACKEND_VERSION } from '../version.js';

const DEFAULT_PORT = DEFAULT_CONFIG.DEFAULT_PORT;
Expand All @@ -16,8 +16,8 @@ async function showUpdateNotice(): Promise<void> {
const info = await checkForUpdate('backend', BACKEND_VERSION);
if (info.hasUpdate) {
console.log(`\n ⚠ Update available: ${BACKEND_VERSION} → ${info.latestVersion}`);
console.log(` Run: npx devmentorai-server@latest`);
console.log(` Or: npm install -g devmentorai-server@latest`);
console.log(' Run: npx devmentorai-server@latest');
console.log(' Or: npm install -g devmentorai-server@latest');
console.log(` ${info.releaseUrl}\n`);
}
} catch {
Expand All @@ -30,7 +30,7 @@ async function showAuthNotice(port: number): Promise<void> {
const response = await fetch(`http://127.0.0.1:${port}/api/account/auth`);
if (!response.ok) return;

const payload = await response.json() as {
const payload = (await response.json()) as {
success?: boolean;
data?: { isAuthenticated?: boolean; login?: string | null };
};
Expand Down Expand Up @@ -85,13 +85,13 @@ export async function startCommand(options: CliOptions): Promise<void> {
const healthy = await waitForHealthy(port);

if (healthy) {
console.log(`✓ Server started successfully`);
console.log('✓ Server started successfully');
console.log(` → http://127.0.0.1:${port}`);
console.log(` Logs: ${LOG_FILE}\n`);
await showAuthNotice(port);
await showUpdateNotice();
} else {
console.error(`✗ Server started but healthcheck failed`);
console.error('✗ Server started but healthcheck failed');
console.error(` Check logs: ${LOG_FILE}\n`);
process.exit(1);
}
Expand Down
10 changes: 6 additions & 4 deletions apps/backend/src/cli/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
* Shows the current status of the DevMentorAI server.
*/

import { isServerRunning, readPid, healthcheck } from '../lib/daemon.js';
import { PID_FILE, LOG_FILE, DATA_DIR } from '../lib/paths.js';
import { DEFAULT_CONFIG } from '@devmentorai/shared';
import { healthcheck, isServerRunning, readPid } from '../lib/daemon.js';
import { DATA_DIR, LOG_FILE, PID_FILE } from '../lib/paths.js';

const DEFAULT_PORT = DEFAULT_CONFIG.DEFAULT_PORT;

Expand All @@ -26,7 +26,7 @@ export async function statusCommand(): Promise<void> {
const pid = readPid();
const health = await healthcheck(DEFAULT_PORT);

console.log(` Status: ✓ running`);
console.log(' Status: ✓ running');
console.log(` PID: ${pid || 'unknown'}`);
console.log(` Port: ${DEFAULT_PORT}`);
console.log(` URL: http://127.0.0.1:${DEFAULT_PORT}`);
Expand All @@ -38,7 +38,9 @@ export async function statusCommand(): Promise<void> {
console.log(` Uptime: ${formatUptime(data.uptime as number)}`);
}
if (data.copilotConnected !== undefined) {
console.log(` Copilot: ${data.copilotConnected ? '✓ connected' : '⊘ disconnected (mock mode)'}`);
console.log(
` Copilot: ${data.copilotConnected ? '✓ connected' : '⊘ disconnected (mock mode)'}`
);
}
}

Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/cli/stop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* Stops the running DevMentorAI server.
*/

import { isServerRunning, stopServer, readPid } from '../lib/daemon.js';
import { DEFAULT_CONFIG } from '@devmentorai/shared';
import { isServerRunning, readPid, stopServer } from '../lib/daemon.js';

const DEFAULT_PORT = DEFAULT_CONFIG.DEFAULT_PORT;

Expand Down
38 changes: 33 additions & 5 deletions apps/backend/src/db/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import Database from 'better-sqlite3';
import path from 'path';
import os from 'os';
import fs from 'fs';

const DB_DIR = path.join(os.homedir(), '.devmentorai');
const DB_PATH = path.join(DB_DIR, 'devmentorai.db');
Expand All @@ -15,10 +15,10 @@ export function initDatabase(): Database.Database {
}

const db = new Database(DB_PATH);

// Enable WAL mode for better performance
db.pragma('journal_mode = WAL');

// Create tables
db.exec(`
CREATE TABLE IF NOT EXISTS sessions (
Expand Down Expand Up @@ -64,6 +64,34 @@ export function initDatabase(): Database.Database {
CREATE INDEX IF NOT EXISTS idx_session_contexts_extracted_at ON session_contexts(extracted_at);
`);

// Migration: Add tone, explain_tradeoffs, reasoning_effort columns if they don't exist
try {
db.exec(`
ALTER TABLE sessions ADD COLUMN tone TEXT DEFAULT 'balanced';
`);
console.log('[DB] Migration: Added tone column');
} catch {
// Column already exists
}

try {
db.exec(`
ALTER TABLE sessions ADD COLUMN explain_tradeoffs INTEGER DEFAULT 0;
`);
console.log('[DB] Migration: Added explain_tradeoffs column');
} catch {
// Column already exists
}

try {
db.exec(`
ALTER TABLE sessions ADD COLUMN reasoning_effort TEXT;
`);
console.log('[DB] Migration: Added reasoning_effort column');
} catch {
// Column already exists
}

return db;
}

Expand Down
Loading
Loading