Version 2.53.0 Release: Thinking Partner Protocol and Context-Aware Chronicle

This commit is contained in:
g1nation
2026-05-03 20:25:37 +09:00
parent f230eb4663
commit 9c242a5b8d
4 changed files with 58 additions and 5 deletions
+48 -4
View File
@@ -1483,12 +1483,12 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
}
private async _autoWriteChronicleAfterPrompt() {
const profile = this._getActiveChronicleProject();
if (!profile) return;
const history = this._agent.getHistory();
const latestUser = [...history].reverse().find(message => message.role === 'user')?.content || '';
const latestAssistant = [...history].reverse().find(message => message.role === 'assistant')?.content || '';
const profile = this._getChronicleProjectForConversation(latestUser) || this._getActiveChronicleProject();
if (!profile) return;
const recordType = this._inferAutoChronicleRecordType(latestUser, latestAssistant);
if (!recordType) return;
@@ -1573,12 +1573,56 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
this._chronicle.appendTimeline(profile, [`Auto ${recordType} record created: ${result.relativePath}`], createdAt);
await this._context.globalState.update(SidebarChatProvider.lastAutoChronicleSignatureStateKey, signature);
await this._sendChronicleRecords();
this.injectSystemMessage(`**[Chronicle Auto Saved]** ${recordType} · \`${result.filePath}\``);
vscode.window.setStatusBarMessage(`G1nation: Chronicle auto-saved ${recordType}`, 3500);
} catch (err: any) {
logError('Automatic Chronicle record write failed.', { error: err?.message || String(err), recordType });
}
}
private _getChronicleProjectForConversation(text: string): ProjectProfile | null {
const projectPath = this._extractLocalProjectPath(text);
if (!projectPath) return null;
const projects = this._getChronicleProjects();
const resolvedPath = path.resolve(projectPath);
const existing = projects.find(project => {
const root = project.projectRoot ? path.resolve(project.projectRoot) : '';
const recordRoot = path.resolve(project.recordRoot);
return root === resolvedPath || recordRoot.startsWith(`${resolvedPath}${path.sep}`);
});
if (existing) return existing;
const projectName = path.basename(resolvedPath) || 'Current Project';
const now = new Date().toISOString();
return {
projectId: this._slugify(projectName),
projectName,
projectRoot: resolvedPath,
recordRoot: path.join(resolvedPath, 'docs', 'records', projectName),
description: 'Auto-detected from the local project path in the conversation.',
corePurpose: 'Capture project direction, architecture discussion, decisions, and development notes as Markdown.',
targetUsers: ['Project developer'],
avoidDirections: ['Do not mix records across projects.'],
detailLevel: 'standard',
createdAt: now,
updatedAt: now
};
}
private _extractLocalProjectPath(text: string): string | null {
const match = text.match(/\/Volumes\/Data\/project\/Antigravity\/[^\s`"'<>]+/i);
if (!match) return null;
const candidate = match[0].replace(/[.,;:)\]]+$/, '');
try {
if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
return candidate;
}
} catch {
return null;
}
return null;
}
private _inferAutoChronicleRecordType(userText: string, assistantText: string): 'planning' | 'discussion' | 'decision' | 'development' | 'bug' | null {
const combined = `${userText}\n${assistantText}`;
if (!combined.trim()) return null;