fix(build): bundle @libsql native modules + rebrand to Aperant (#1946)
* fix(build): unpack @libsql/client native modules from asar @libsql/client has platform-specific native bindings (@libsql/darwin-arm64, @libsql/linux-x64, etc.) containing .node files that cannot be loaded from inside app.asar. This causes ERR_MODULE_NOT_FOUND on app startup after updating to 2.8.0-beta.4. Add @libsql/client to rollupOptions.external so Vite keeps it as a runtime require, and add node_modules/@libsql/** to asarUnpack so electron-builder extracts the native modules to app.asar.unpacked/. Follows the same pattern used for @lydell/node-pty. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix bundled and update name + icon * fix: complete Aperant rebrand and harden native module loading - Add try/catch + type validation to loadCreateClient() in db.ts to prevent silent failures when @libsql/client native module is missing or exports are wrong (was a blocking issue) - Add path.resolve() and JSON type guard to ensureOnboardingComplete() for safer config file handling - Replace require('fs').cpSync with static import; fix console.log in production code (index.ts) - Complete "Auto Claude" → "Aperant" brand rename across ~30 remaining source files: renderer components, GitHub/GitLab PR comment bodies, User-Agent headers, MCP registry, and test assertions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(deps): sync package-lock.json with aperant rename package.json was renamed from auto-claude-ui to aperant but package-lock.json wasn't regenerated, causing npm ci to fail in all CI jobs with "Missing: aperant@2.8.0-beta.1 from lock file". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(security): resolve CodeQL file-system race in ensureOnboardingComplete Replace existsSync + readFileSync pattern with direct readFileSync wrapped in try/catch for ENOENT. Eliminates the TOCTOU race condition flagged by CodeQL (js/file-system-race). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
@@ -78,7 +78,9 @@ export default defineConfig({
|
||||
// spawned via `new Worker(path)` from WorkerBridge
|
||||
'ai/agent/worker': resolve(__dirname, 'src/main/ai/agent/worker.ts'),
|
||||
},
|
||||
// Only node-pty needs to be external (native module rebuilt by electron-builder)
|
||||
// Native modules that must remain external (loaded from disk, not bundled).
|
||||
// @libsql/client is loaded lazily via globalThis.require() and resolved
|
||||
// from extraResources/node_modules via Module.globalPaths (see index.ts).
|
||||
external: ['@lydell/node-pty']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"name": "auto-claude-ui",
|
||||
"name": "aperant",
|
||||
"version": "2.8.0-beta.1",
|
||||
"type": "module",
|
||||
"description": "Desktop UI for Auto Claude autonomous coding framework",
|
||||
"homepage": "https://github.com/AndyMik90/Auto-Claude",
|
||||
"description": "Autonomous multi-agent coding framework",
|
||||
"homepage": "https://github.com/AndyMik90/Aperant",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/AndyMik90/Auto-Claude.git"
|
||||
"url": "https://github.com/AndyMik90/Aperant.git"
|
||||
},
|
||||
"main": "./out/main/index.js",
|
||||
"author": {
|
||||
"name": "Auto Claude Team",
|
||||
"name": "Aperant Team",
|
||||
"email": "119136210+AndyMik90@users.noreply.github.com"
|
||||
},
|
||||
"license": "AGPL-3.0",
|
||||
@@ -35,9 +35,9 @@
|
||||
"package:flatpak": "electron-builder --linux flatpak",
|
||||
"verify:linux": "node scripts/verify-linux-packages.cjs dist",
|
||||
"test:verify-linux": "node --test scripts/verify-linux-packages.test.mjs",
|
||||
"start:packaged:mac": "open dist/mac-arm64/Auto-Claude.app || open dist/mac/Auto-Claude.app",
|
||||
"start:packaged:win": "start \"\" \"dist\\win-unpacked\\Auto-Claude.exe\"",
|
||||
"start:packaged:linux": "./dist/linux-unpacked/auto-claude",
|
||||
"start:packaged:mac": "open dist/mac-arm64/Aperant.app || open dist/mac/Aperant.app",
|
||||
"start:packaged:win": "start \"\" \"dist\\win-unpacked\\Aperant.exe\"",
|
||||
"start:packaged:linux": "./dist/linux-unpacked/aperant",
|
||||
"test": "vitest run",
|
||||
"test:unit": "vitest run --exclude src/__tests__/integration/ --exclude src/__tests__/e2e/",
|
||||
"test:integration": "vitest run src/__tests__/integration/",
|
||||
@@ -158,15 +158,15 @@
|
||||
"@electron/rebuild": "4.0.2"
|
||||
},
|
||||
"build": {
|
||||
"appId": "com.autoclaude.ui",
|
||||
"productName": "Auto-Claude",
|
||||
"appId": "com.aperant.app",
|
||||
"productName": "Aperant",
|
||||
"npmRebuild": false,
|
||||
"artifactName": "${productName}-${version}-${platform}-${arch}.${ext}",
|
||||
"publish": [
|
||||
{
|
||||
"provider": "github",
|
||||
"owner": "AndyMik90",
|
||||
"repo": "Auto-Claude"
|
||||
"repo": "Aperant"
|
||||
}
|
||||
],
|
||||
"directories": {
|
||||
@@ -188,6 +188,22 @@
|
||||
{
|
||||
"from": "prompts",
|
||||
"to": "prompts"
|
||||
},
|
||||
{
|
||||
"from": "../../node_modules/@libsql",
|
||||
"to": "node_modules/@libsql"
|
||||
},
|
||||
{
|
||||
"from": "../../node_modules/libsql",
|
||||
"to": "node_modules/libsql"
|
||||
},
|
||||
{
|
||||
"from": "../../node_modules/@neon-rs",
|
||||
"to": "node_modules/@neon-rs"
|
||||
},
|
||||
{
|
||||
"from": "../../node_modules/detect-libc",
|
||||
"to": "node_modules/detect-libc"
|
||||
}
|
||||
],
|
||||
"mac": {
|
||||
|
||||
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 275 KiB |
|
Before Width: | Height: | Size: 20 MiB After Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 921 B After Width: | Height: | Size: 455 B |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 290 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 2.5 KiB |
@@ -302,7 +302,7 @@ describe('Application Logger', () => {
|
||||
const { generateDebugReport } = await import('../app-logger');
|
||||
const report = generateDebugReport();
|
||||
|
||||
expect(report).toContain('=== Auto Claude Debug Report ===');
|
||||
expect(report).toContain('=== Aperant Debug Report ===');
|
||||
expect(report).toContain('--- System Information ---');
|
||||
expect(report).toContain('--- Recent Errors ---');
|
||||
expect(report).toContain('=== End Debug Report ===');
|
||||
|
||||
@@ -40,8 +40,8 @@ const __dirname = path.dirname(__filename);
|
||||
*/
|
||||
function resolveWorkerPath(): string {
|
||||
if (app.isPackaged) {
|
||||
// Production: worker is bundled alongside other main-process code
|
||||
return path.join(process.resourcesPath, 'app', 'main', 'ai', 'agent', 'worker.js');
|
||||
// Production: worker is inside app.asar at out/main/ai/agent/worker.js
|
||||
return path.join(process.resourcesPath, 'app.asar', 'out', 'main', 'ai', 'agent', 'worker.js');
|
||||
}
|
||||
// Dev: electron-vite outputs worker at out/main/ai/agent/worker.js
|
||||
// because the Rollup input key is 'ai/agent/worker'.
|
||||
|
||||
@@ -253,7 +253,7 @@ export async function startCodexOAuthFlow(): Promise<CodexAuthResult> {
|
||||
<body style="font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; background: #1a1a1a; color: #e0e0e0;">
|
||||
<div style="text-align: center;">
|
||||
<h2 style="color: #4ade80;">Authentication successful!</h2>
|
||||
<p>You can close this tab and return to Auto Claude.</p>
|
||||
<p>You can close this tab and return to Aperant.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
@@ -106,7 +106,7 @@ const PUPPETEER_SERVER: McpServerConfig = {
|
||||
function createAutoClaudeServer(specDir: string): McpServerConfig {
|
||||
return {
|
||||
id: 'auto-claude',
|
||||
name: 'Auto-Claude',
|
||||
name: 'Aperant',
|
||||
description: 'Build management tools (progress tracking, session context)',
|
||||
enabledByDefault: true,
|
||||
transport: {
|
||||
|
||||
@@ -7,11 +7,51 @@
|
||||
* 3. Web app (Next.js SaaS) — pure cloud libSQL
|
||||
*/
|
||||
|
||||
import { createClient } from '@libsql/client';
|
||||
import type { Client } from '@libsql/client';
|
||||
import type { Client, Config } from '@libsql/client/sqlite3';
|
||||
import { createRequire } from 'module';
|
||||
import { join } from 'path';
|
||||
import { MEMORY_SCHEMA_SQL, MEMORY_PRAGMA_SQL } from './schema';
|
||||
|
||||
/**
|
||||
* Lazy-load @libsql/client via CJS require().
|
||||
*
|
||||
* @libsql/client depends on native platform-specific modules (@libsql/darwin-arm64,
|
||||
* @libsql/linux-x64-gnu, etc.). In packaged Electron apps these live in
|
||||
* Resources/node_modules/ (via extraResources). ESM import() can't resolve them
|
||||
* from within app.asar, but CJS require() works because Module.globalPaths is
|
||||
* patched at startup in index.ts to include Resources/node_modules/.
|
||||
*
|
||||
* Using a lazy getter avoids a static import that would crash at startup before
|
||||
* the globalPaths patch runs.
|
||||
*/
|
||||
let _createClient: ((config: Config) => Client) | null = null;
|
||||
|
||||
function loadCreateClient(): (config: Config) => Client {
|
||||
if (!_createClient) {
|
||||
// In Electron: globalThis.require is set up in index.ts with Module.globalPaths
|
||||
// patched to include Resources/node_modules/ for extraResources packages.
|
||||
// In tests/dev: fall back to createRequire (deps are in normal node_modules).
|
||||
const req = globalThis.require ?? createRequire(import.meta.url);
|
||||
let mod: Record<string, unknown>;
|
||||
try {
|
||||
mod = req('@libsql/client/sqlite3');
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Failed to load @libsql/client/sqlite3: ${(err as Error).message}. ` +
|
||||
`Ensure native modules are available in Resources/node_modules/`
|
||||
);
|
||||
}
|
||||
if (typeof mod.createClient !== 'function') {
|
||||
throw new Error(
|
||||
`@libsql/client/sqlite3 did not export createClient (got ${typeof mod.createClient}). ` +
|
||||
`Check that native modules are available in Resources/node_modules/`
|
||||
);
|
||||
}
|
||||
_createClient = mod.createClient as (config: Config) => Client;
|
||||
}
|
||||
return _createClient!;
|
||||
}
|
||||
|
||||
let _client: Client | null = null;
|
||||
|
||||
/**
|
||||
@@ -31,7 +71,7 @@ export async function getMemoryClient(
|
||||
const { app } = await import('electron');
|
||||
const localPath = join(app.getPath('userData'), 'memory.db');
|
||||
|
||||
_client = createClient({
|
||||
_client = loadCreateClient()({
|
||||
url: `file:${localPath}`,
|
||||
...(tursoSyncUrl && authToken
|
||||
? { syncUrl: tursoSyncUrl, authToken, syncInterval: 60 }
|
||||
@@ -78,7 +118,7 @@ export async function getWebMemoryClient(
|
||||
tursoUrl: string,
|
||||
authToken: string,
|
||||
): Promise<Client> {
|
||||
const client = createClient({ url: tursoUrl, authToken });
|
||||
const client = loadCreateClient()({ url: tursoUrl, authToken });
|
||||
|
||||
// Apply PRAGMAs
|
||||
for (const pragma of MEMORY_PRAGMA_SQL.split('\n').filter(l => l.trim())) {
|
||||
@@ -97,7 +137,7 @@ export async function getWebMemoryClient(
|
||||
* Create an in-memory client (for tests — no Electron dependency).
|
||||
*/
|
||||
export async function getInMemoryClient(): Promise<Client> {
|
||||
const client = createClient({ url: ':memory:' });
|
||||
const client = loadCreateClient()({ url: ':memory:' });
|
||||
await client.executeMultiple(MEMORY_SCHEMA_SQL);
|
||||
return client;
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ export interface MemoryMethodologyPlugin {
|
||||
|
||||
export const nativePlugin: MemoryMethodologyPlugin = {
|
||||
id: 'native',
|
||||
displayName: 'Auto Claude (Subtasks)',
|
||||
displayName: 'Aperant (Subtasks)',
|
||||
mapPhase: (p: string): UniversalPhase => {
|
||||
const map: Record<string, UniversalPhase> = {
|
||||
planning: 'define',
|
||||
|
||||
@@ -382,7 +382,7 @@ ${diffContent}
|
||||
}
|
||||
|
||||
lines.push('---');
|
||||
lines.push('_Generated by Auto Claude MR Review_');
|
||||
lines.push('_Generated by Aperant MR Review_');
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ const BLOCKED_PROCESS_NAMES = new Set([
|
||||
'electron',
|
||||
'Electron',
|
||||
'auto-claude',
|
||||
'Auto Claude',
|
||||
'Aperant',
|
||||
]);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -149,7 +149,7 @@ export function generateDebugReport(): string {
|
||||
const recentErrors = getRecentErrors(10);
|
||||
|
||||
const lines = [
|
||||
'=== Auto Claude Debug Report ===',
|
||||
'=== Aperant Debug Report ===',
|
||||
`Generated: ${new Date().toISOString()}`,
|
||||
'',
|
||||
'--- System Information ---',
|
||||
|
||||
@@ -30,7 +30,7 @@ import { isMacOS } from './platform';
|
||||
|
||||
// GitHub repo info for API calls
|
||||
const GITHUB_OWNER = 'AndyMik90';
|
||||
const GITHUB_REPO = 'Auto-Claude';
|
||||
const GITHUB_REPO = 'Aperant';
|
||||
|
||||
// Debug mode - DEBUG_UPDATER=true or development mode
|
||||
const DEBUG_UPDATER = process.env.DEBUG_UPDATER === 'true' || process.env.NODE_ENV === 'development';
|
||||
@@ -488,7 +488,7 @@ async function fetchLatestStableRelease(): Promise<AppUpdateInfo | null> {
|
||||
});
|
||||
|
||||
request.setHeader('Accept', 'application/vnd.github.v3+json');
|
||||
request.setHeader('User-Agent', `Auto-Claude/${getCurrentVersion()}`);
|
||||
request.setHeader('User-Agent', `Aperant/${getCurrentVersion()}`);
|
||||
|
||||
let data = '';
|
||||
|
||||
|
||||
@@ -3,11 +3,24 @@
|
||||
// require-in-the-middle hooks. Sentry's hooks expect require.cache to exist,
|
||||
// which is only available in CommonJS. Without this, node-pty native module
|
||||
// loading fails with "ReferenceError: require is not defined".
|
||||
import { createRequire } from 'module';
|
||||
import Module, { createRequire } from 'module';
|
||||
const require = createRequire(import.meta.url);
|
||||
// Make require globally available for Sentry's require-in-the-middle hooks
|
||||
globalThis.require = require;
|
||||
|
||||
// In packaged Electron apps, native modules (e.g. @libsql/client) are placed in
|
||||
// Resources/node_modules/ via extraResources. Add that path to CJS resolution so
|
||||
// globalThis.require() can find them at runtime.
|
||||
if (process.resourcesPath) {
|
||||
const nativeModulesPath = require('path').join(process.resourcesPath, 'node_modules');
|
||||
// Module.globalPaths is an undocumented but stable Node.js internal used for
|
||||
// CJS module resolution. It's not in @types/node, hence the cast.
|
||||
const globalPaths = (Module as unknown as { globalPaths: string[] }).globalPaths;
|
||||
if (!globalPaths.includes(nativeModulesPath)) {
|
||||
globalPaths.push(nativeModulesPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Load .env file FIRST before any other imports that might use process.env
|
||||
import { config } from 'dotenv';
|
||||
import { resolve, dirname } from 'path';
|
||||
@@ -37,7 +50,7 @@ for (const envPath of possibleEnvPaths) {
|
||||
|
||||
import { app, BrowserWindow, shell, nativeImage, session, screen, Menu, MenuItem } from 'electron';
|
||||
import { join } from 'path';
|
||||
import { accessSync, readFileSync, writeFileSync, rmSync } from 'fs';
|
||||
import { accessSync, readFileSync, writeFileSync, rmSync, cpSync } from 'fs';
|
||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils';
|
||||
import { setupIpcHandlers } from './ipc-setup';
|
||||
import { AgentManager } from './agent';
|
||||
@@ -58,6 +71,26 @@ import { isMacOS, isWindows } from './platform';
|
||||
import { ptyDaemonClient } from './terminal/pty-daemon-client';
|
||||
import type { AppSettings, AuthFailureInfo } from '../shared/types';
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Migrate userData from old app name (auto-claude-ui → aperant)
|
||||
// Must run before any code accesses app.getPath('userData')
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
{
|
||||
const newUserData = app.getPath('userData');
|
||||
const oldUserData = join(dirname(newUserData), 'auto-claude-ui');
|
||||
if (existsSync(oldUserData) && !existsSync(join(newUserData, '.migrated'))) {
|
||||
try {
|
||||
// Copy all files from old location to new (don't move — keeps old as backup)
|
||||
cpSync(oldUserData, newUserData, { recursive: true, force: false, errorOnExist: false });
|
||||
// Mark as migrated so we don't repeat
|
||||
writeFileSync(join(newUserData, '.migrated'), new Date().toISOString());
|
||||
console.warn('[main] Migrated userData from auto-claude-ui to aperant');
|
||||
} catch (err) {
|
||||
console.warn('[main] userData migration failed (non-fatal):', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Window sizing constants
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -373,7 +406,7 @@ if (isWindows()) {
|
||||
// Initialize the application
|
||||
app.whenReady().then(() => {
|
||||
// Set app user model id for Windows
|
||||
electronApp.setAppUserModelId('com.autoclaude.ui');
|
||||
electronApp.setAppUserModelId('com.aperant.app');
|
||||
|
||||
// Clear cache on Windows to prevent permission errors from stale cache
|
||||
if (isWindows()) {
|
||||
|
||||
@@ -129,7 +129,7 @@ async function githubGraphQL<T>(
|
||||
headers: {
|
||||
"Authorization": `Bearer ${safeToken}`,
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "Auto-Claude-UI",
|
||||
"User-Agent": "Aperant",
|
||||
},
|
||||
body: JSON.stringify({ query, variables }),
|
||||
});
|
||||
@@ -2275,7 +2275,7 @@ export function registerPRHandlers(getMainWindow: () => BrowserWindow | null): v
|
||||
|
||||
if (options?.forceApprove) {
|
||||
// Auto-approve format: clean approval message with optional suggestions
|
||||
body = `## ✅ Auto Claude Review - APPROVED\n\n`;
|
||||
body = `## ✅ Aperant Review - APPROVED\n\n`;
|
||||
body += `**Status:** Ready to Merge\n\n`;
|
||||
body += `**Summary:** ${result.summary}\n\n`;
|
||||
|
||||
@@ -2298,10 +2298,10 @@ export function registerPRHandlers(getMainWindow: () => BrowserWindow | null): v
|
||||
}
|
||||
|
||||
body += `---\n*This automated review found no blocking issues. The PR can be safely merged.*\n\n`;
|
||||
body += `*Generated by Auto Claude*`;
|
||||
body += `*Generated by Aperant*`;
|
||||
} else {
|
||||
// Standard review format
|
||||
body = `## 🤖 Auto Claude PR Review\n\n${result.summary}\n\n`;
|
||||
body = `## 🤖 Aperant PR Review\n\n${result.summary}\n\n`;
|
||||
|
||||
if (findings.length > 0) {
|
||||
// Show selected count vs total if filtered
|
||||
@@ -2326,7 +2326,7 @@ export function registerPRHandlers(getMainWindow: () => BrowserWindow | null): v
|
||||
body += `*No findings selected for this review.*\n\n`;
|
||||
}
|
||||
|
||||
body += `---\n*This review was generated by Auto Claude.*`;
|
||||
body += `---\n*This review was generated by Aperant.*`;
|
||||
}
|
||||
|
||||
// Determine review status based on selected findings (or force approve)
|
||||
|
||||
@@ -267,7 +267,7 @@ export async function githubFetch(
|
||||
headers: {
|
||||
'Accept': 'application/vnd.github+json',
|
||||
'Authorization': `Bearer ${safeToken}`,
|
||||
'User-Agent': 'Auto-Claude-UI',
|
||||
'User-Agent': 'Aperant',
|
||||
...options.headers
|
||||
}
|
||||
});
|
||||
@@ -298,7 +298,7 @@ export async function githubFetchWithETag(
|
||||
const headers: Record<string, string> = {
|
||||
'Accept': 'application/vnd.github+json',
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'User-Agent': 'Auto-Claude-UI'
|
||||
'User-Agent': 'Aperant'
|
||||
};
|
||||
|
||||
// Add If-None-Match header if we have a cached ETag
|
||||
|
||||
@@ -108,7 +108,7 @@ function formatReviewBody(result: MRReviewResult, selectedFindingIds?: string[])
|
||||
? result.findings.filter(f => selectedSet.has(f.id))
|
||||
: result.findings;
|
||||
|
||||
let body = `## Auto Claude MR Review\n\n${result.summary}\n\n`;
|
||||
let body = `## Aperant MR Review\n\n${result.summary}\n\n`;
|
||||
|
||||
if (findings.length > 0) {
|
||||
const countText = selectedSet
|
||||
@@ -130,7 +130,7 @@ function formatReviewBody(result: MRReviewResult, selectedFindingIds?: string[])
|
||||
body += `*No findings selected for this review.*\n\n`;
|
||||
}
|
||||
|
||||
body += `---\n*This review was generated by Auto Claude.*`;
|
||||
body += `---\n*This review was generated by Aperant.*`;
|
||||
|
||||
return body;
|
||||
}
|
||||
@@ -335,7 +335,7 @@ describe('GitLab MR Review Handlers', () => {
|
||||
it('should format review header', () => {
|
||||
const body = formatReviewBody(baseResult);
|
||||
|
||||
expect(body).toContain('## Auto Claude MR Review');
|
||||
expect(body).toContain('## Aperant MR Review');
|
||||
expect(body).toContain('Found 2 issues that need attention');
|
||||
});
|
||||
|
||||
@@ -410,7 +410,7 @@ describe('GitLab MR Review Handlers', () => {
|
||||
const body = formatReviewBody(baseResult);
|
||||
|
||||
expect(body).toContain('---');
|
||||
expect(body).toContain('*This review was generated by Auto Claude.*');
|
||||
expect(body).toContain('*This review was generated by Aperant.*');
|
||||
});
|
||||
|
||||
it('should format finding descriptions', () => {
|
||||
|
||||
@@ -520,7 +520,7 @@ export function registerMRReviewHandlers(
|
||||
debugLog('Posting findings', { total: result.findings.length, selected: findings.length });
|
||||
|
||||
// Build note body
|
||||
let body = `## Auto Claude MR Review\n\n${result.summary}\n\n`;
|
||||
let body = `## Aperant MR Review\n\n${result.summary}\n\n`;
|
||||
|
||||
if (findings.length > 0) {
|
||||
const countText = selectedSet
|
||||
@@ -542,7 +542,7 @@ export function registerMRReviewHandlers(
|
||||
body += `*No findings selected for this review.*\n\n`;
|
||||
}
|
||||
|
||||
body += `---\n*This review was generated by Auto Claude.*`;
|
||||
body += `---\n*This review was generated by Aperant.*`;
|
||||
|
||||
const encodedProject = encodeProjectPath(config.project);
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ export function registerInsightsHandlers(getMainWindow: () => BrowserWindow | nu
|
||||
}
|
||||
|
||||
if (!project.autoBuildPath) {
|
||||
return { success: false, error: "Auto Claude not initialized for this project" };
|
||||
return { success: false, error: "Aperant not initialized for this project" };
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -264,7 +264,7 @@ const detectAutoBuildSourcePath = (): string | null => {
|
||||
}
|
||||
}
|
||||
|
||||
console.warn('[detectAutoBuildSourcePath] Could not auto-detect Auto Claude prompts path. Please configure manually in settings.');
|
||||
console.warn('[detectAutoBuildSourcePath] Could not auto-detect Aperant prompts path. Please configure manually in settings.');
|
||||
console.warn('[detectAutoBuildSourcePath] Set DEBUG=1 environment variable for detailed path checking.');
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -177,7 +177,7 @@ export function registerTaskExecutionHandlers(
|
||||
mainWindow.webContents.send(
|
||||
IPC_CHANNELS.TASK_ERROR,
|
||||
taskId,
|
||||
'Git repository required. Please run "git init" in your project directory. Auto Claude uses git worktrees for isolated builds.'
|
||||
'Git repository required. Please run "git init" in your project directory. Aperant uses git worktrees for isolated builds.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -205,14 +205,14 @@ function ensureGitignoreEntries(projectPath: string, entries: string[]): void {
|
||||
appendContent += '\n';
|
||||
}
|
||||
|
||||
appendContent += '\n# Auto Claude data directory\n';
|
||||
appendContent += '\n# Aperant data directory\n';
|
||||
for (const entry of entriesToAdd) {
|
||||
appendContent += entry + '\n';
|
||||
}
|
||||
|
||||
appendFileSync(gitignorePath, appendContent);
|
||||
} else {
|
||||
writeFileSync(gitignorePath, '# Auto Claude data directory\n' + entriesToAdd.join('\n') + '\n', 'utf-8');
|
||||
writeFileSync(gitignorePath, '# Aperant data directory\n' + entriesToAdd.join('\n') + '\n', 'utf-8');
|
||||
}
|
||||
|
||||
debug('Added entries to .gitignore', { entries: entriesToAdd });
|
||||
@@ -288,13 +288,13 @@ export function initializeProject(projectPath: string): InitializationResult {
|
||||
};
|
||||
}
|
||||
|
||||
// Check git status - Auto Claude requires git for worktree-based builds
|
||||
// Check git status - Aperant requires git for worktree-based builds
|
||||
const gitStatus = checkGitStatus(projectPath);
|
||||
if (!gitStatus.isGitRepo || !gitStatus.hasCommits) {
|
||||
debug('Git check failed', { gitStatus });
|
||||
return {
|
||||
success: false,
|
||||
error: gitStatus.error || 'Git repository required. Auto Claude uses git worktrees for isolated builds.'
|
||||
error: gitStatus.error || 'Git repository required. Aperant uses git worktrees for isolated builds.'
|
||||
};
|
||||
}
|
||||
|
||||
@@ -375,7 +375,7 @@ export function ensureDataDirectories(projectPath: string): InitializationResult
|
||||
*
|
||||
* IMPORTANT: Only .auto-claude/ is considered a valid "installed" auto-claude.
|
||||
* The auto-claude/ folder (if it exists) is the SOURCE CODE being developed,
|
||||
* not an installation. This allows Auto Claude to be used to develop itself.
|
||||
* not an installation. This allows Aperant to be used to develop itself.
|
||||
*/
|
||||
export function getAutoBuildPath(projectPath: string): string | null {
|
||||
const dotAutoBuildPath = path.join(projectPath, '.auto-claude');
|
||||
|
||||
@@ -802,6 +802,11 @@ export function handleOnboardingComplete(
|
||||
}
|
||||
}
|
||||
|
||||
// Persist onboarding completion so future invocations skip the wizard
|
||||
if (profile?.configDir) {
|
||||
ensureOnboardingComplete(profile.configDir);
|
||||
}
|
||||
|
||||
safeSendToRenderer(getWindow, IPC_CHANNELS.TERMINAL_ONBOARDING_COMPLETE, {
|
||||
terminalId: terminal.id,
|
||||
profileId,
|
||||
@@ -893,6 +898,48 @@ export function handleClaudeExit(
|
||||
safeSendToRenderer(getWindow, IPC_CHANNELS.TERMINAL_CLAUDE_EXIT, terminal.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure hasCompletedOnboarding is set in profile's .claude.json.
|
||||
* When CLAUDE_CONFIG_DIR is set, Claude Code reads .claude.json from that directory.
|
||||
* Without this flag, it triggers the onboarding wizard even for authenticated profiles.
|
||||
*/
|
||||
function ensureOnboardingComplete(configDir: string): void {
|
||||
try {
|
||||
const expandedDir = path.resolve(
|
||||
configDir.startsWith('~') ? configDir.replace(/^~/, os.homedir()) : configDir
|
||||
);
|
||||
const claudeJsonPath = path.join(expandedDir, '.claude.json');
|
||||
|
||||
// Read directly instead of existsSync + readFileSync to avoid TOCTOU race (CodeQL js/file-system-race)
|
||||
let content: string;
|
||||
try {
|
||||
content = fs.readFileSync(claudeJsonPath, 'utf-8');
|
||||
} catch (readErr) {
|
||||
if ((readErr as NodeJS.ErrnoException).code === 'ENOENT') {
|
||||
return; // No .claude.json yet — Claude Code will create it during auth
|
||||
}
|
||||
throw readErr;
|
||||
}
|
||||
|
||||
const config = JSON.parse(content);
|
||||
|
||||
if (typeof config !== 'object' || config === null || Array.isArray(config)) {
|
||||
return; // Not a valid config object
|
||||
}
|
||||
|
||||
if (config.hasCompletedOnboarding === true) {
|
||||
return; // Already set
|
||||
}
|
||||
|
||||
config.hasCompletedOnboarding = true;
|
||||
fs.writeFileSync(claudeJsonPath, JSON.stringify(config, null, 2), { encoding: 'utf-8' });
|
||||
debugLog(`[ClaudeIntegration] Set hasCompletedOnboarding in ${claudeJsonPath}`);
|
||||
} catch (error) {
|
||||
// Non-fatal — worst case the user sees onboarding once
|
||||
debugError('[ClaudeIntegration] Failed to set hasCompletedOnboarding:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared command execution logic for profile-based invocation
|
||||
* Returns true if command was executed via configDir or temp-file method
|
||||
@@ -938,6 +985,9 @@ function executeProfileCommand(options: ExecuteProfileCommandOptions): boolean {
|
||||
// read full Keychain credentials including subscriptionType ("max") and rateLimitTier.
|
||||
// Using CLAUDE_CODE_OAUTH_TOKEN alone lacks tier info, causing "Claude API" display.
|
||||
if (activeProfile.configDir) {
|
||||
// Ensure Claude Code skips onboarding for authenticated profiles
|
||||
ensureOnboardingComplete(activeProfile.configDir);
|
||||
|
||||
const command = buildClaudeShellCommand(
|
||||
cwdCommand,
|
||||
pathPrefix,
|
||||
@@ -1016,6 +1066,9 @@ async function executeProfileCommandAsync(options: ExecuteProfileCommandOptions)
|
||||
// read full Keychain credentials including subscriptionType ("max") and rateLimitTier.
|
||||
// Using CLAUDE_CODE_OAUTH_TOKEN alone lacks tier info, causing "Claude API" display.
|
||||
if (activeProfile.configDir) {
|
||||
// Ensure Claude Code skips onboarding for authenticated profiles
|
||||
ensureOnboardingComplete(activeProfile.configDir);
|
||||
|
||||
const command = buildClaudeShellCommand(
|
||||
cwdCommand,
|
||||
pathPrefix,
|
||||
|
||||
@@ -747,7 +747,7 @@ export function App() {
|
||||
} else {
|
||||
// Initialization failed - show error but keep dialog open
|
||||
console.warn('[InitDialog] Initialization failed, showing error');
|
||||
const errorMessage = result?.error || 'Failed to initialize Auto Claude. Please try again.';
|
||||
const errorMessage = result?.error || 'Failed to initialize Aperant. Please try again.';
|
||||
setInitError(errorMessage);
|
||||
setIsInitializing(false);
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ const MCP_SERVERS: Record<string, { name: string; description: string; icon: Rea
|
||||
],
|
||||
},
|
||||
'auto-claude': {
|
||||
name: 'Auto-Claude Tools',
|
||||
name: 'Aperant Tools',
|
||||
description: 'Build progress tracking, session context, discoveries & gotchas recording',
|
||||
icon: ListChecks,
|
||||
tools: [
|
||||
|
||||
@@ -180,7 +180,7 @@ export function AppUpdateNotification() {
|
||||
<DialogDescription>
|
||||
{t(
|
||||
"dialogs:appUpdate.description",
|
||||
"A new version of Auto Claude is ready to download"
|
||||
"A new version of Aperant is ready to download"
|
||||
)}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
@@ -277,7 +277,7 @@ export function AppUpdateNotification() {
|
||||
{t("dialogs:appUpdate.readOnlyVolumeTitle", "Cannot install from disk image")}
|
||||
</p>
|
||||
<p className="text-muted-foreground">
|
||||
{t("dialogs:appUpdate.readOnlyVolumeDescription", "Please move Auto Claude to your Applications folder before updating.")}
|
||||
{t("dialogs:appUpdate.readOnlyVolumeDescription", "Please move Aperant to your Applications folder before updating.")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -76,7 +76,7 @@ export function AuthFailureModal({ onOpenSettings }: AuthFailureModalProps) {
|
||||
{failureMessage}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t('auth.failure.description', 'Please re-authenticate your Claude profile to continue using Auto Claude.')}
|
||||
{t('auth.failure.description', 'Please re-authenticate your Claude profile to continue using Aperant.')}
|
||||
</p>
|
||||
|
||||
{authFailureInfo.taskId && (
|
||||
|
||||
@@ -744,7 +744,7 @@ export function GitHubSetupModal({
|
||||
Select Base Branch
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
Choose which branch Auto Claude should use as the base for creating task branches.
|
||||
Choose which branch Aperant should use as the base for creating task branches.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
@@ -811,7 +811,7 @@ export function GitHubSetupModal({
|
||||
<div className="text-xs text-muted-foreground">
|
||||
<p className="font-medium text-foreground">Why select a branch?</p>
|
||||
<p className="mt-1">
|
||||
Auto Claude creates isolated workspaces for each task. Selecting the right base branch ensures
|
||||
Aperant creates isolated workspaces for each task. Selecting the right base branch ensures
|
||||
your tasks start with the latest code from your main development line.
|
||||
</p>
|
||||
</div>
|
||||
@@ -857,7 +857,7 @@ export function GitHubSetupModal({
|
||||
<CheckCircle2 className="h-8 w-8 text-success" />
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground text-center">
|
||||
Auto Claude is ready to use! You can now create tasks that will be
|
||||
Aperant is ready to use! You can now create tasks that will be
|
||||
automatically based on <code className="px-1 bg-muted rounded">{selectedBranch}</code>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -480,7 +480,7 @@ export function Worktrees({ projectId }: WorktreesProps) {
|
||||
Worktrees
|
||||
</h2>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
Manage isolated workspaces for your Auto Claude tasks
|
||||
Manage isolated workspaces for your Aperant tasks
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -569,7 +569,7 @@ export function Worktrees({ projectId }: WorktreesProps) {
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-foreground">No Worktrees</h3>
|
||||
<p className="text-sm text-muted-foreground mt-2 max-w-md">
|
||||
Worktrees are created automatically when Auto Claude builds features.
|
||||
Worktrees are created automatically when Aperant builds features.
|
||||
You can also create terminal worktrees from the Agent Terminals tab.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -921,7 +921,7 @@ export function PRDetail({
|
||||
try {
|
||||
// Auto-assign current user (you can get from GitHub config)
|
||||
// For now, we'll just post the comment
|
||||
const approvalMessage = `## ✅ Auto Claude PR Review - APPROVED\n\n${reviewResult.summary}\n\n---\n*This approval was generated by Auto Claude.*`;
|
||||
const approvalMessage = `## ✅ Aperant PR Review - APPROVED\n\n${reviewResult.summary}\n\n---\n*This approval was generated by Aperant.*`;
|
||||
await Promise.resolve(onPostComment(approvalMessage));
|
||||
} finally {
|
||||
// Clear loading state if PR hasn't changed
|
||||
|
||||
@@ -395,7 +395,7 @@ describe('PRDetail Clean Review Functionality', () => {
|
||||
summary: 'All code passes review. No issues found.'
|
||||
});
|
||||
|
||||
const cleanReviewMessage = `## ✅ Auto Claude PR Review - PASSED
|
||||
const cleanReviewMessage = `## ✅ Aperant PR Review - PASSED
|
||||
|
||||
**Status:** All code is good
|
||||
|
||||
@@ -403,12 +403,12 @@ ${reviewResult.summary}
|
||||
|
||||
---
|
||||
|
||||
*This automated review found no issues. Generated by Auto Claude.*`;
|
||||
*This automated review found no issues. Generated by Aperant.*`;
|
||||
|
||||
expect(cleanReviewMessage).toContain('## ✅ Auto Claude PR Review - PASSED');
|
||||
expect(cleanReviewMessage).toContain('## ✅ Aperant PR Review - PASSED');
|
||||
expect(cleanReviewMessage).toContain('**Status:** All code is good');
|
||||
expect(cleanReviewMessage).toContain(reviewResult.summary);
|
||||
expect(cleanReviewMessage).toContain('*This automated review found no issues. Generated by Auto Claude.*');
|
||||
expect(cleanReviewMessage).toContain('*This automated review found no issues. Generated by Aperant.*');
|
||||
});
|
||||
|
||||
it('should include custom summary in clean review comment', () => {
|
||||
@@ -417,7 +417,7 @@ ${reviewResult.summary}
|
||||
summary: customSummary
|
||||
});
|
||||
|
||||
const cleanReviewMessage = `## ✅ Auto Claude PR Review - PASSED
|
||||
const cleanReviewMessage = `## ✅ Aperant PR Review - PASSED
|
||||
|
||||
**Status:** All code is good
|
||||
|
||||
@@ -425,7 +425,7 @@ ${reviewResult.summary}
|
||||
|
||||
---
|
||||
|
||||
*This automated review found no issues. Generated by Auto Claude.*`;
|
||||
*This automated review found no issues. Generated by Aperant.*`;
|
||||
|
||||
expect(cleanReviewMessage).toContain(customSummary);
|
||||
});
|
||||
@@ -435,7 +435,7 @@ ${reviewResult.summary}
|
||||
summary: ''
|
||||
});
|
||||
|
||||
const cleanReviewMessage = `## ✅ Auto Claude PR Review - PASSED
|
||||
const cleanReviewMessage = `## ✅ Aperant PR Review - PASSED
|
||||
|
||||
**Status:** All code is good
|
||||
|
||||
@@ -443,7 +443,7 @@ ${reviewResult.summary}
|
||||
|
||||
---
|
||||
|
||||
*This automated review found no issues. Generated by Auto Claude.*`;
|
||||
*This automated review found no issues. Generated by Aperant.*`;
|
||||
|
||||
expect(cleanReviewMessage).toBeDefined();
|
||||
expect(cleanReviewMessage).toContain('All code is good');
|
||||
|
||||
@@ -174,7 +174,7 @@ export function ClaudeCodeStep({ onNext, onBack, onSkip }: ClaudeCodeStepProps)
|
||||
{t('claudeCode.info.title', 'What is Claude Code?')}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t('claudeCode.info.description', "Claude Code is Anthropic's official CLI that powers Auto Claude's AI features. It provides secure authentication and direct access to Claude models.")}
|
||||
{t('claudeCode.info.description', "Claude Code is Anthropic's official CLI that powers Aperant's AI features. It provides secure authentication and direct access to Claude models.")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -97,7 +97,7 @@ export function FirstSpecStep({ onNext, onBack, onSkip, onOpenTaskCreator }: Fir
|
||||
Create Your First Task
|
||||
</h1>
|
||||
<p className="mt-2 text-muted-foreground">
|
||||
Describe what you want to build and let Auto Claude handle the rest
|
||||
Describe what you want to build and let Aperant handle the rest
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -757,7 +757,7 @@ export function GraphitiStep({ onNext, onBack, onSkip }: GraphitiStepProps) {
|
||||
Graphiti configured successfully
|
||||
</h3>
|
||||
<p className="mt-1 text-sm text-success/80">
|
||||
Memory features are enabled. Auto Claude will maintain context
|
||||
Memory features are enabled. Aperant will maintain context
|
||||
across sessions for improved code understanding.
|
||||
</p>
|
||||
</div>
|
||||
@@ -823,7 +823,7 @@ export function GraphitiStep({ onNext, onBack, onSkip }: GraphitiStepProps) {
|
||||
What is Graphiti?
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Graphiti is an intelligent memory layer that helps Auto Claude remember
|
||||
Graphiti is an intelligent memory layer that helps Aperant remember
|
||||
context across sessions. It uses a knowledge graph to store discoveries,
|
||||
patterns, and insights about your codebase.
|
||||
</p>
|
||||
|
||||
@@ -21,11 +21,11 @@ vi.mock('react-i18next', () => ({
|
||||
// Return the key itself or provide specific translations
|
||||
// Keys are without namespace since component uses useTranslation('namespace')
|
||||
const translations: Record<string, string> = {
|
||||
'welcome.title': 'Welcome to Auto Claude',
|
||||
'welcome.title': 'Welcome to Aperant',
|
||||
'welcome.subtitle': 'AI-powered autonomous coding assistant',
|
||||
'welcome.getStarted': 'Get Started',
|
||||
'welcome.skip': 'Skip Setup',
|
||||
'wizard.helpText': 'Let us help you get started with Auto Claude',
|
||||
'wizard.helpText': 'Let us help you get started with Aperant',
|
||||
'welcome.features.aiPowered.title': 'AI-Powered',
|
||||
'welcome.features.aiPowered.description': 'Powered by Claude',
|
||||
'welcome.features.specDriven.title': 'Spec-Driven',
|
||||
@@ -107,7 +107,7 @@ describe('OnboardingWizard Integration Tests', () => {
|
||||
render(<OnboardingWizard {...defaultProps} />);
|
||||
|
||||
// Start at welcome step
|
||||
expect(screen.getByText(/Welcome to Auto Claude/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Welcome to Aperant/)).toBeInTheDocument();
|
||||
|
||||
// Click "Get Started" to go to accounts
|
||||
const getStartedButton = screen.getByRole('button', { name: /Get Started/ });
|
||||
@@ -147,7 +147,7 @@ describe('OnboardingWizard Integration Tests', () => {
|
||||
|
||||
// Should be back at welcome
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/Welcome to Auto Claude/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Welcome to Aperant/)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -157,25 +157,25 @@ describe('OnboardingWizard Integration Tests', () => {
|
||||
render(<OnboardingWizard {...defaultProps} open={true} />);
|
||||
|
||||
// Wizard should be visible
|
||||
expect(screen.getByText(/Welcome to Auto Claude/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Welcome to Aperant/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not show wizard when open is false', () => {
|
||||
const { rerender } = render(<OnboardingWizard {...defaultProps} open={true} />);
|
||||
|
||||
expect(screen.getByText(/Welcome to Auto Claude/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Welcome to Aperant/)).toBeInTheDocument();
|
||||
|
||||
// Close wizard
|
||||
rerender(<OnboardingWizard {...defaultProps} open={false} />);
|
||||
|
||||
// Wizard content should not be visible
|
||||
expect(screen.queryByText(/Welcome to Auto Claude/)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(/Welcome to Aperant/)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not show wizard for users with existing auth', () => {
|
||||
render(<OnboardingWizard {...defaultProps} open={false} />);
|
||||
|
||||
expect(screen.queryByText(/Welcome to Auto Claude/)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText(/Welcome to Aperant/)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ export function DebugSettings() {
|
||||
{t('debug.errorReporting.label', 'Anonymous Error Reporting')}
|
||||
</Label>
|
||||
<p className="text-xs text-muted-foreground mt-0.5">
|
||||
{t('debug.errorReporting.description', 'Send crash reports to help improve Auto Claude. No personal data or code is collected.')}
|
||||
{t('debug.errorReporting.description', 'Send crash reports to help improve Aperant. No personal data or code is collected.')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -320,7 +320,7 @@ export function DevToolsSettings({ settings, onSettingsChange }: DevToolsSetting
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t('devtools.ide.description', 'Auto Claude will open worktrees in this editor')}
|
||||
{t('devtools.ide.description', 'Aperant will open worktrees in this editor')}
|
||||
</p>
|
||||
|
||||
{/* Custom IDE Path */}
|
||||
@@ -382,7 +382,7 @@ export function DevToolsSettings({ settings, onSettingsChange }: DevToolsSetting
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t('devtools.terminal.description', 'Auto Claude will open terminal sessions here')}
|
||||
{t('devtools.terminal.description', 'Aperant will open terminal sessions here')}
|
||||
</p>
|
||||
|
||||
{/* Custom Terminal Path */}
|
||||
|
||||
@@ -402,17 +402,17 @@
|
||||
"postCleanReview": "Post Clean Review",
|
||||
"postingCleanReview": "Posting...",
|
||||
"cleanReviewPosted": "Clean review posted",
|
||||
"cleanReviewMessageTitle": "## ✅ Auto Claude PR Review - PASSED",
|
||||
"cleanReviewMessageTitle": "## ✅ Aperant PR Review - PASSED",
|
||||
"cleanReviewMessageStatus": "**Status:** All code is good",
|
||||
"cleanReviewMessageFooter": "*This automated review found no issues. Generated by Auto Claude.*",
|
||||
"cleanReviewMessageFooter": "*This automated review found no issues. Generated by Aperant.*",
|
||||
"failedPostCleanReview": "Failed to post clean review",
|
||||
"viewErrorDetails": "View details",
|
||||
"hideErrorDetails": "Hide details",
|
||||
"postBlockedStatus": "Post Status",
|
||||
"postingBlockedStatus": "Posting...",
|
||||
"blockedStatusPosted": "Status posted to PR",
|
||||
"blockedStatusMessageTitle": "## 🤖 Auto Claude PR Review",
|
||||
"blockedStatusMessageFooter": "*This review identified blockers that must be resolved before merge. Generated by Auto Claude.*",
|
||||
"blockedStatusMessageTitle": "## 🤖 Aperant PR Review",
|
||||
"blockedStatusMessageFooter": "*This review identified blockers that must be resolved before merge. Generated by Aperant.*",
|
||||
"failedPostBlockedStatus": "Failed to post status",
|
||||
"branchSynced": "Branch synced ({{count}} commit from base)",
|
||||
"branchSynced_plural": "Branch synced ({{count}} commits from base)",
|
||||
@@ -606,7 +606,7 @@
|
||||
"codeSubmitFailed": "Failed to Submit Code",
|
||||
"codeSubmitFailedDescription": "Please try again or copy the code manually to the terminal.",
|
||||
"authenticateTitle": "Authenticate with Claude",
|
||||
"authenticateDescription": "Auto Claude requires Claude AI authentication for AI-powered features like Roadmap generation, Task automation, and Ideation.",
|
||||
"authenticateDescription": "Aperant requires Claude AI authentication for AI-powered features like Roadmap generation, Task automation, and Ideation.",
|
||||
"authenticateTerminalInfo": "This will open a terminal with Claude CLI where you can authenticate. Your credentials are stored securely and are valid for 1 year.",
|
||||
"completeAuthTitle": "Complete Authentication",
|
||||
"terminalOpened": "A terminal window has opened with Claude CLI.",
|
||||
@@ -621,7 +621,7 @@
|
||||
"successTitle": "Successfully Authenticated!",
|
||||
"connectedAs": "Connected as {{email}}",
|
||||
"credentialsSaved": "Your Claude credentials have been saved",
|
||||
"canUseFeatures": "You can now use all Auto Claude AI features",
|
||||
"canUseFeatures": "You can now use all Aperant AI features",
|
||||
"authFailed": "Authentication Failed",
|
||||
"skipForNow": "Skip for now",
|
||||
"manualTokenEntry": "Manual Token Entry",
|
||||
@@ -749,7 +749,7 @@
|
||||
"tokenInvalid": "Your authentication token is invalid.",
|
||||
"tokenMissing": "No authentication token found.",
|
||||
"authFailed": "Authentication failed.",
|
||||
"description": "Please re-authenticate your Claude profile to continue using Auto Claude.",
|
||||
"description": "Please re-authenticate your Claude profile to continue using Aperant.",
|
||||
"taskAffected": "Task affected",
|
||||
"technicalDetails": "Technical details",
|
||||
"goToSettings": "Go to Settings"
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"initialize": {
|
||||
"title": "Initialize Auto Claude",
|
||||
"description": "This project doesn't have Auto Claude initialized. Would you like to set it up now?",
|
||||
"title": "Initialize Aperant",
|
||||
"description": "This project doesn't have Aperant initialized. Would you like to set it up now?",
|
||||
"willDo": "This will:",
|
||||
"createFolder": "Create a .auto-claude folder in your project",
|
||||
"copyFramework": "Copy the Auto Claude framework files",
|
||||
"copyFramework": "Copy the Aperant framework files",
|
||||
"setupSpecs": "Set up the specs directory for your tasks",
|
||||
"sourcePathNotConfigured": "Source path not configured",
|
||||
"sourcePathNotConfiguredDescription": "Please set the Auto Claude source path in App Settings before initializing.",
|
||||
"sourcePathNotConfiguredDescription": "Please set the Aperant source path in App Settings before initializing.",
|
||||
"initFailed": "Initialization Failed",
|
||||
"initFailedDescription": "Failed to initialize Auto Claude. Please try again."
|
||||
"initFailedDescription": "Failed to initialize Aperant. Please try again."
|
||||
},
|
||||
"gitSetup": {
|
||||
"title": "Git Repository Required",
|
||||
"description": "Auto Claude uses git to safely build features in isolated workspaces",
|
||||
"description": "Aperant uses git to safely build features in isolated workspaces",
|
||||
"notGitRepo": "This folder is not a git repository",
|
||||
"noCommits": "Git repository has no commits",
|
||||
"needsInit": "Git needs to be initialized before Auto Claude can manage your code.",
|
||||
"needsCommit": "At least one commit is required for Auto Claude to create worktrees.",
|
||||
"needsInit": "Git needs to be initialized before Aperant can manage your code.",
|
||||
"needsCommit": "At least one commit is required for Aperant to create worktrees.",
|
||||
"willSetup": "We'll set up git for you:",
|
||||
"initRepo": "Initialize a new git repository",
|
||||
"createCommit": "Create an initial commit with your current files",
|
||||
@@ -25,25 +25,25 @@
|
||||
"settingUp": "Setting up Git",
|
||||
"initializingRepo": "Initializing git repository and creating initial commit...",
|
||||
"success": "Git Initialized",
|
||||
"readyToUse": "Your project is now ready to use with Auto Claude!"
|
||||
"readyToUse": "Your project is now ready to use with Aperant!"
|
||||
},
|
||||
"githubSetup": {
|
||||
"connectTitle": "Connect to GitHub",
|
||||
"connectDescription": "Auto Claude requires GitHub to manage your code branches and keep tasks up to date.",
|
||||
"connectDescription": "Aperant requires GitHub to manage your code branches and keep tasks up to date.",
|
||||
"claudeTitle": "Connect to Claude AI",
|
||||
"claudeDescription": "Auto Claude uses Claude AI for intelligent features like Roadmap generation, Task automation, and Ideation.",
|
||||
"claudeDescription": "Aperant uses Claude AI for intelligent features like Roadmap generation, Task automation, and Ideation.",
|
||||
"aiProviderTitle": "Connect to AI",
|
||||
"aiProviderDescription": "Add an AI provider account to power features like Roadmap generation, Task automation, and Ideation.",
|
||||
"aiProviderReady": "You have at least one AI provider configured. You can continue to the next step.",
|
||||
"skipForNow": "Skip for now",
|
||||
"continue": "Continue",
|
||||
"selectRepo": "Select Repository",
|
||||
"repoDescription": "Auto Claude will use this repository for managing task branches and keeping your code up to date.",
|
||||
"repoDescription": "Aperant will use this repository for managing task branches and keeping your code up to date.",
|
||||
"selectBranch": "Select Base Branch",
|
||||
"branchDescription": "Choose which branch Auto Claude should use as the base for creating task branches.",
|
||||
"branchDescription": "Choose which branch Aperant should use as the base for creating task branches.",
|
||||
"whyBranch": "Why select a branch?",
|
||||
"branchExplanation": "Auto Claude creates isolated workspaces for each task. Selecting the right base branch ensures your tasks start with the latest code from your main development line.",
|
||||
"ready": "Auto Claude is ready to use! You can now create tasks that will be automatically based on the {{branchName}} branch.",
|
||||
"branchExplanation": "Aperant creates isolated workspaces for each task. Selecting the right base branch ensures your tasks start with the latest code from your main development line.",
|
||||
"ready": "Aperant is ready to use! You can now create tasks that will be automatically based on the {{branchName}} branch.",
|
||||
"createRepoAriaLabel": "Create new repository on GitHub",
|
||||
"linkRepoAriaLabel": "Link to existing repository",
|
||||
"goBackAriaLabel": "Go back to repository selection",
|
||||
@@ -53,9 +53,9 @@
|
||||
},
|
||||
"worktrees": {
|
||||
"title": "Worktrees",
|
||||
"description": "Manage isolated workspaces for your Auto Claude tasks",
|
||||
"description": "Manage isolated workspaces for your Aperant tasks",
|
||||
"empty": "No Worktrees",
|
||||
"emptyDescription": "Worktrees are created automatically when Auto Claude builds features. They provide isolated workspaces for each task.",
|
||||
"emptyDescription": "Worktrees are created automatically when Aperant builds features. They provide isolated workspaces for each task.",
|
||||
"merge": "Merge Worktree",
|
||||
"mergeDescription": "Merge changes from this worktree into the base branch.",
|
||||
"delete": "Delete Worktree?",
|
||||
@@ -77,7 +77,7 @@
|
||||
"errorDescription": "Failed to cleanup worktree. Please try again."
|
||||
},
|
||||
"update": {
|
||||
"title": "Auto Claude",
|
||||
"title": "Aperant",
|
||||
"projectInitialized": "Project is initialized."
|
||||
},
|
||||
"addFeature": {
|
||||
@@ -156,7 +156,7 @@
|
||||
},
|
||||
"appUpdate": {
|
||||
"title": "App Update Available",
|
||||
"description": "A new version of Auto Claude is ready to download",
|
||||
"description": "A new version of Aperant is ready to download",
|
||||
"newVersion": "New Version",
|
||||
"released": "Released",
|
||||
"downloading": "Downloading...",
|
||||
@@ -169,7 +169,7 @@
|
||||
"claudeCodeChangelog": "View Claude Code Changelog",
|
||||
"claudeCodeChangelogAriaLabel": "View Claude Code Changelog (opens in new window)",
|
||||
"readOnlyVolumeTitle": "Cannot install from disk image",
|
||||
"readOnlyVolumeDescription": "Please move Auto Claude to your Applications folder before updating."
|
||||
"readOnlyVolumeDescription": "Please move Aperant to your Applications folder before updating."
|
||||
},
|
||||
"addCompetitor": {
|
||||
"title": "Add Competitor",
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"help": "Help & Feedback"
|
||||
},
|
||||
"messages": {
|
||||
"initializeToCreateTasks": "Initialize Auto Claude to create tasks"
|
||||
"initializeToCreateTasks": "Initialize Aperant to create tasks"
|
||||
},
|
||||
"updateBanner": {
|
||||
"title": "Update Available",
|
||||
|
||||
@@ -918,7 +918,7 @@
|
||||
"description": "Web browser automation for testing"
|
||||
},
|
||||
"autoClaude": {
|
||||
"name": "Auto-Claude Tools",
|
||||
"name": "Aperant Tools",
|
||||
"description": "Build progress tracking"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"hero": {
|
||||
"title": "Welcome to Auto Claude",
|
||||
"title": "Welcome to Aperant",
|
||||
"subtitle": "Build software autonomously with AI-powered agents"
|
||||
},
|
||||
"actions": {
|
||||
|
||||
@@ -411,17 +411,17 @@
|
||||
"postCleanReview": "Publier révision propre",
|
||||
"postingCleanReview": "Publication...",
|
||||
"cleanReviewPosted": "Révision propre publiée",
|
||||
"cleanReviewMessageTitle": "## ✅ Auto Claude PR Review - PASSED",
|
||||
"cleanReviewMessageTitle": "## ✅ Aperant PR Review - PASSED",
|
||||
"cleanReviewMessageStatus": "**Status:** All code is good",
|
||||
"cleanReviewMessageFooter": "*This automated review found no issues. Generated by Auto Claude.*",
|
||||
"cleanReviewMessageFooter": "*This automated review found no issues. Generated by Aperant.*",
|
||||
"failedPostCleanReview": "Échec de la publication de la révision",
|
||||
"viewErrorDetails": "Voir les détails",
|
||||
"hideErrorDetails": "Masquer les détails",
|
||||
"postBlockedStatus": "Publier le statut",
|
||||
"postingBlockedStatus": "Publication...",
|
||||
"blockedStatusPosted": "Statut publié sur la PR",
|
||||
"blockedStatusMessageTitle": "## 🤖 Auto Claude PR Review",
|
||||
"blockedStatusMessageFooter": "*This review identified blockers that must be resolved before merge. Generated by Auto Claude.*",
|
||||
"blockedStatusMessageTitle": "## 🤖 Aperant PR Review",
|
||||
"blockedStatusMessageFooter": "*This review identified blockers that must be resolved before merge. Generated by Aperant.*",
|
||||
"failedPostBlockedStatus": "Échec de la publication du statut",
|
||||
"disputed": "Contesté",
|
||||
"disputedByValidator": "Contesté par le validateur ({{count}})",
|
||||
@@ -606,7 +606,7 @@
|
||||
"codeSubmitFailed": "Échec de la soumission du code",
|
||||
"codeSubmitFailedDescription": "Veuillez réessayer ou copier le code manuellement dans le terminal.",
|
||||
"authenticateTitle": "S'authentifier avec Claude",
|
||||
"authenticateDescription": "Auto Claude nécessite l'authentification Claude AI pour les fonctionnalités basées sur l'IA comme la génération de feuille de route, l'automatisation des tâches et l'idéation.",
|
||||
"authenticateDescription": "Aperant nécessite l'authentification Claude AI pour les fonctionnalités basées sur l'IA comme la génération de feuille de route, l'automatisation des tâches et l'idéation.",
|
||||
"authenticateTerminalInfo": "Cela ouvrira un terminal avec Claude CLI où vous pourrez vous authentifier. Vos identifiants sont stockés de manière sécurisée et sont valides pendant 1 an.",
|
||||
"completeAuthTitle": "Terminer l'authentification",
|
||||
"terminalOpened": "Une fenêtre de terminal s'est ouverte avec Claude CLI.",
|
||||
@@ -621,7 +621,7 @@
|
||||
"successTitle": "Authentification réussie !",
|
||||
"connectedAs": "Connecté en tant que {{email}}",
|
||||
"credentialsSaved": "Vos identifiants Claude ont été sauvegardés",
|
||||
"canUseFeatures": "Vous pouvez maintenant utiliser toutes les fonctionnalités IA d'Auto Claude",
|
||||
"canUseFeatures": "Vous pouvez maintenant utiliser toutes les fonctionnalités IA d'Aperant",
|
||||
"authFailed": "Échec de l'authentification",
|
||||
"skipForNow": "Passer pour l'instant",
|
||||
"manualTokenEntry": "Saisie manuelle du jeton",
|
||||
@@ -749,7 +749,7 @@
|
||||
"tokenInvalid": "Votre jeton d'authentification est invalide.",
|
||||
"tokenMissing": "Aucun jeton d'authentification trouvé.",
|
||||
"authFailed": "Échec de l'authentification.",
|
||||
"description": "Veuillez vous ré-authentifier pour continuer à utiliser Auto Claude.",
|
||||
"description": "Veuillez vous ré-authentifier pour continuer à utiliser Aperant.",
|
||||
"taskAffected": "Tâche affectée",
|
||||
"technicalDetails": "Détails techniques",
|
||||
"goToSettings": "Aller aux paramètres"
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"initialize": {
|
||||
"title": "Initialiser Auto Claude",
|
||||
"description": "Ce projet n'a pas Auto Claude initialisé. Voulez-vous le configurer maintenant ?",
|
||||
"title": "Initialiser Aperant",
|
||||
"description": "Ce projet n'a pas Aperant initialisé. Voulez-vous le configurer maintenant ?",
|
||||
"willDo": "Ceci va :",
|
||||
"createFolder": "Créer un dossier .auto-claude dans votre projet",
|
||||
"copyFramework": "Copier les fichiers du framework Auto Claude",
|
||||
"copyFramework": "Copier les fichiers du framework Aperant",
|
||||
"setupSpecs": "Configurer le répertoire des spécifications pour vos tâches",
|
||||
"sourcePathNotConfigured": "Chemin source non configuré",
|
||||
"sourcePathNotConfiguredDescription": "Veuillez définir le chemin source Auto Claude dans les paramètres de l'application avant d'initialiser.",
|
||||
"sourcePathNotConfiguredDescription": "Veuillez définir le chemin source Aperant dans les paramètres de l'application avant d'initialiser.",
|
||||
"initFailed": "Échec de l'initialisation",
|
||||
"initFailedDescription": "Échec de l'initialisation de Auto Claude. Veuillez réessayer."
|
||||
"initFailedDescription": "Échec de l'initialisation de Aperant. Veuillez réessayer."
|
||||
},
|
||||
"gitSetup": {
|
||||
"title": "Dépôt Git requis",
|
||||
"description": "Auto Claude utilise git pour construire des fonctionnalités en toute sécurité dans des espaces de travail isolés",
|
||||
"description": "Aperant utilise git pour construire des fonctionnalités en toute sécurité dans des espaces de travail isolés",
|
||||
"notGitRepo": "Ce dossier n'est pas un dépôt git",
|
||||
"noCommits": "Le dépôt git n'a pas de commits",
|
||||
"needsInit": "Git doit être initialisé avant que Auto Claude puisse gérer votre code.",
|
||||
"needsCommit": "Au moins un commit est requis pour que Auto Claude puisse créer des worktrees.",
|
||||
"needsInit": "Git doit être initialisé avant que Aperant puisse gérer votre code.",
|
||||
"needsCommit": "Au moins un commit est requis pour que Aperant puisse créer des worktrees.",
|
||||
"willSetup": "Nous allons configurer git pour vous :",
|
||||
"initRepo": "Initialiser un nouveau dépôt git",
|
||||
"createCommit": "Créer un commit initial avec vos fichiers actuels",
|
||||
@@ -25,25 +25,25 @@
|
||||
"settingUp": "Configuration de Git",
|
||||
"initializingRepo": "Initialisation du dépôt git et création du commit initial...",
|
||||
"success": "Git initialisé",
|
||||
"readyToUse": "Votre projet est maintenant prêt à être utilisé avec Auto Claude !"
|
||||
"readyToUse": "Votre projet est maintenant prêt à être utilisé avec Aperant !"
|
||||
},
|
||||
"githubSetup": {
|
||||
"connectTitle": "Connecter à GitHub",
|
||||
"connectDescription": "Auto Claude nécessite GitHub pour gérer vos branches de code et maintenir les tâches à jour.",
|
||||
"connectDescription": "Aperant nécessite GitHub pour gérer vos branches de code et maintenir les tâches à jour.",
|
||||
"claudeTitle": "Connecter à Claude AI",
|
||||
"claudeDescription": "Auto Claude utilise Claude AI pour des fonctionnalités intelligentes comme la génération de feuille de route, l'automatisation des tâches et l'idéation.",
|
||||
"claudeDescription": "Aperant utilise Claude AI pour des fonctionnalités intelligentes comme la génération de feuille de route, l'automatisation des tâches et l'idéation.",
|
||||
"aiProviderTitle": "Connecter à l'IA",
|
||||
"aiProviderDescription": "Ajoutez un compte fournisseur IA pour activer des fonctionnalités comme la génération de feuille de route, l'automatisation des tâches et l'idéation.",
|
||||
"aiProviderReady": "Vous avez au moins un fournisseur IA configuré. Vous pouvez passer à l'étape suivante.",
|
||||
"skipForNow": "Passer pour l'instant",
|
||||
"continue": "Continuer",
|
||||
"selectRepo": "Sélectionner le dépôt",
|
||||
"repoDescription": "Auto Claude utilisera ce dépôt pour gérer les branches de tâches et maintenir votre code à jour.",
|
||||
"repoDescription": "Aperant utilisera ce dépôt pour gérer les branches de tâches et maintenir votre code à jour.",
|
||||
"selectBranch": "Sélectionner la branche de base",
|
||||
"branchDescription": "Choisissez quelle branche Auto Claude doit utiliser comme base pour créer les branches de tâches.",
|
||||
"branchDescription": "Choisissez quelle branche Aperant doit utiliser comme base pour créer les branches de tâches.",
|
||||
"whyBranch": "Pourquoi sélectionner une branche ?",
|
||||
"branchExplanation": "Auto Claude crée des espaces de travail isolés pour chaque tâche. Sélectionner la bonne branche de base garantit que vos tâches démarrent avec le code le plus récent de votre ligne de développement principale.",
|
||||
"ready": "Auto Claude est prêt à l'emploi ! Vous pouvez maintenant créer des tâches qui seront automatiquement basées sur la branche {{branchName}}.",
|
||||
"branchExplanation": "Aperant crée des espaces de travail isolés pour chaque tâche. Sélectionner la bonne branche de base garantit que vos tâches démarrent avec le code le plus récent de votre ligne de développement principale.",
|
||||
"ready": "Aperant est prêt à l'emploi ! Vous pouvez maintenant créer des tâches qui seront automatiquement basées sur la branche {{branchName}}.",
|
||||
"createRepoAriaLabel": "Créer un nouveau dépôt sur GitHub",
|
||||
"linkRepoAriaLabel": "Lier à un dépôt existant",
|
||||
"goBackAriaLabel": "Retourner à la sélection du dépôt",
|
||||
@@ -53,9 +53,9 @@
|
||||
},
|
||||
"worktrees": {
|
||||
"title": "Worktrees",
|
||||
"description": "Gérez les espaces de travail isolés pour vos tâches Auto Claude",
|
||||
"description": "Gérez les espaces de travail isolés pour vos tâches Aperant",
|
||||
"empty": "Aucun worktree",
|
||||
"emptyDescription": "Les worktrees sont créés automatiquement quand Auto Claude construit des fonctionnalités. Ils fournissent des espaces de travail isolés pour chaque tâche.",
|
||||
"emptyDescription": "Les worktrees sont créés automatiquement quand Aperant construit des fonctionnalités. Ils fournissent des espaces de travail isolés pour chaque tâche.",
|
||||
"merge": "Fusionner le worktree",
|
||||
"mergeDescription": "Fusionner les modifications de ce worktree dans la branche de base.",
|
||||
"delete": "Supprimer le worktree ?",
|
||||
@@ -77,7 +77,7 @@
|
||||
"errorDescription": "Échec du nettoyage du worktree. Veuillez réessayer."
|
||||
},
|
||||
"update": {
|
||||
"title": "Auto Claude",
|
||||
"title": "Aperant",
|
||||
"projectInitialized": "Le projet est initialisé."
|
||||
},
|
||||
"addFeature": {
|
||||
@@ -156,7 +156,7 @@
|
||||
},
|
||||
"appUpdate": {
|
||||
"title": "Mise à jour de l'application disponible",
|
||||
"description": "Une nouvelle version d'Auto Claude est prête à être téléchargée",
|
||||
"description": "Une nouvelle version d'Aperant est prête à être téléchargée",
|
||||
"newVersion": "Nouvelle version",
|
||||
"released": "Publiée",
|
||||
"downloading": "Téléchargement...",
|
||||
@@ -169,7 +169,7 @@
|
||||
"claudeCodeChangelog": "Voir le journal des modifications Claude Code",
|
||||
"claudeCodeChangelogAriaLabel": "Voir le journal des modifications Claude Code (s'ouvre dans une nouvelle fenêtre)",
|
||||
"readOnlyVolumeTitle": "Impossible d'installer depuis une image disque",
|
||||
"readOnlyVolumeDescription": "Veuillez déplacer Auto Claude dans votre dossier Applications avant de mettre à jour."
|
||||
"readOnlyVolumeDescription": "Veuillez déplacer Aperant dans votre dossier Applications avant de mettre à jour."
|
||||
},
|
||||
"addCompetitor": {
|
||||
"title": "Ajouter un concurrent",
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"help": "Aide & Feedback"
|
||||
},
|
||||
"messages": {
|
||||
"initializeToCreateTasks": "Initialisez Auto Claude pour créer des tâches"
|
||||
"initializeToCreateTasks": "Initialisez Aperant pour créer des tâches"
|
||||
},
|
||||
"updateBanner": {
|
||||
"title": "Mise à jour disponible",
|
||||
|
||||
@@ -918,7 +918,7 @@
|
||||
"description": "Automatisation du navigateur web pour les tests"
|
||||
},
|
||||
"autoClaude": {
|
||||
"name": "Outils Auto-Claude",
|
||||
"name": "Outils Aperant",
|
||||
"description": "Suivi de la progression du build"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"hero": {
|
||||
"title": "Bienvenue sur Auto Claude",
|
||||
"title": "Bienvenue sur Aperant",
|
||||
"subtitle": "Construisez des logiciels de manière autonome avec des agents IA"
|
||||
},
|
||||
"actions": {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
}
|
||||
},
|
||||
"apps/desktop": {
|
||||
"name": "auto-claude-ui",
|
||||
"name": "aperant",
|
||||
"version": "2.8.0-beta.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "AGPL-3.0",
|
||||
@@ -6377,6 +6377,10 @@
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/aperant": {
|
||||
"resolved": "apps/desktop",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/app-builder-bin": {
|
||||
"version": "5.0.0-alpha.12",
|
||||
"resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz",
|
||||
@@ -6639,10 +6643,6 @@
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/auto-claude-ui": {
|
||||
"resolved": "apps/desktop",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.4.23",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz",
|
||||
|
||||