feat: proje secimi ve otomatik ekip akisini ekle

This commit is contained in:
2026-03-17 00:40:50 +03:00
parent 3641190a77
commit c312b83604
6 changed files with 130 additions and 5 deletions

View File

@@ -1,5 +1,8 @@
import fs from "fs";
import path from "path";
import stripAnsi from "strip-ansi";
import { buildBootstrapPrompt } from "./bootstrapPrompt.js";
import { buildProjectSelectionPrompt } from "./bootstrapPrompt.js";
import { LogService } from "./logService.js";
import { PtyService } from "./ptyService.js";
import { getClaudeEnv, getPublicRuntimeConfig } from "./config.js";
@@ -26,7 +29,14 @@ function buildRoutedPrompt(prompt, lastDirectedMember = null) {
if (!targetMember) {
return {
targetMember: null,
routedPrompt: `Not: Bu genel mesajdir. Once Mazlum cevap versin ve konusan herkes ad etiketi kullansin. Kullanici mesaji: ${prompt}`
routedPrompt: `Not: Bu genel mesajdir. Once Mazlum cevap versin ve konusan herkes ad etiketi kullansin. Irgatov teknik gorev almaz; sadece kahve ve lojistik destek verir. Kullanici mesaji: ${prompt}`
};
}
if (targetMember.name === "Irgatov") {
return {
targetMember,
routedPrompt: `Not: Bu mesaj Irgatov icindir. Irgatov sadece kahve, icecek, servis ve basit lojistik destek konularinda cevap versin. Teknik plan, kod, mimari veya dosya yapisi onermesin. Cevap \`Irgatov:\` ile baslasin. Kullanici mesaji: ${prompt}`
};
}
@@ -44,11 +54,13 @@ export class SessionManager {
this.ptyService = null;
this.chatOutput = "";
this.lastDirectedMember = null;
this.currentProjectPath = null;
this.state = {
status: "idle",
startedAt: null,
teamActivated: false,
lastError: null,
currentProjectPath: null,
runtime: getPublicRuntimeConfig(config)
};
}
@@ -56,6 +68,7 @@ export class SessionManager {
getState() {
return {
...this.state,
currentProjectPath: this.currentProjectPath,
runtime: getPublicRuntimeConfig(this.config)
};
}
@@ -94,6 +107,39 @@ export class SessionManager {
this.emitState();
}
getActiveWorkspaceDir() {
return this.currentProjectPath ?? this.config.workspaceDir;
}
async setProjectPath(projectPath) {
const resolved = projectPath ? path.resolve(projectPath) : null;
const wasRunning = this.ptyService?.isRunning() ?? false;
if (resolved && (!fs.existsSync(resolved) || !fs.statSync(resolved).isDirectory())) {
throw new Error(`Selected project path is invalid: ${resolved}`);
}
if (wasRunning) {
await this.stop();
}
this.currentProjectPath = resolved;
this.lastDirectedMember = null;
this.setState({ currentProjectPath: resolved });
this.addLog("system", `Current project set to ${resolved ?? "None"}`);
if (wasRunning) {
await this.start();
if (resolved) {
await this.activateTeam();
} else {
const prompt = buildProjectSelectionPrompt(this.getActiveWorkspaceDir());
await this.sendRawPrompt(prompt, { label: `[project] Switched active project to ${this.getActiveWorkspaceDir()}` });
}
}
}
async start() {
if (this.ptyService?.isRunning()) {
throw new Error("Session is already running");
@@ -105,7 +151,7 @@ export class SessionManager {
this.io.emit("chat:reset");
this.ptyService = new PtyService({
cwd: this.config.workspaceDir,
cwd: this.getActiveWorkspaceDir(),
env: getClaudeEnv(this.config)
});
@@ -116,7 +162,7 @@ export class SessionManager {
lastError: null
});
this.addLog("lifecycle", `Starting Claude session in ${this.config.workspaceDir}`);
this.addLog("lifecycle", `Starting Claude session in ${this.getActiveWorkspaceDir()}`);
try {
await this.ptyService.start({
@@ -174,7 +220,7 @@ export class SessionManager {
}
async activateTeam() {
const prompt = buildBootstrapPrompt();
const prompt = buildBootstrapPrompt(this.currentProjectPath);
this.lastDirectedMember = null;
await this.sendRawPrompt(prompt, { label: "[bootstrap] Team activation prompt sent" });
this.setState({ teamActivated: true });