You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
3.0 KiB
78 lines
3.0 KiB
'use strict'; |
|
// state-dir.js — единая служебная папка моста в workspace. |
|
// Создаётся лениво: при старте моста и при первом tool-вызове. |
|
// Структура: .dsh-memory/logs/, outputs/, notes/. |
|
// В git — .gitignore в корне workspace (пользователь добавляет сам). |
|
|
|
const fs = require('fs'); |
|
const path = require('path'); |
|
|
|
const STATE_DIR_NAME = '.dsh-memory'; |
|
const LOGS = 'logs'; |
|
const OUTPUTS = 'outputs'; |
|
const NOTES = 'notes'; |
|
|
|
const LOG_REL_PATH = STATE_DIR_NAME + '/' + LOGS + '/execution-log.jsonl'; |
|
const NOTES_README = 'README.md'; |
|
|
|
const NOTES_TEMPLATE = [ |
|
'# .dsh-memory/notes — рабочие заметки', |
|
'', |
|
'Эта папка создана мостом dsh-memory автоматически. Служебная, в git', |
|
'не попадает (добавь .dsh-memory/ в .gitignore своего проекта).', |
|
'', |
|
'Что здесь хранить:', |
|
'- Чекпоинты сессий (CHAT_YYYY-MM-DD_PARTN.md)', |
|
'- Протоколы, шпаргалки, инструкции для модели', |
|
'- Планы этапов, заметки по архитектуре', |
|
'- Архив устаревших документов (подпапка archive/)', |
|
'', |
|
'Что здесь НЕ хранить:', |
|
'- Исходники проекта (они в основных папках workspace)', |
|
'- Секреты, токены, ключи', |
|
'- Временные файлы (для них outputs/)', |
|
'', |
|
'Как попасть сюда модели: dsh_read/dsh_write с путём .dsh-memory/notes/...', |
|
'Инъекция протокола в первый ход идёт из памяти (/memory/inject), эта', |
|
'папка для объёмного и исторического, что не влезает в память.', |
|
'' |
|
].join('\n'); |
|
|
|
function stateDirAbs(workspaceAbs) { return path.join(workspaceAbs, STATE_DIR_NAME); } |
|
|
|
function ensureStateDir(workspaceAbs) { |
|
if (!workspaceAbs) return null; |
|
const sd = stateDirAbs(workspaceAbs); |
|
try { |
|
fs.mkdirSync(path.join(sd, LOGS), { recursive: true }); |
|
fs.mkdirSync(path.join(sd, OUTPUTS), { recursive: true }); |
|
fs.mkdirSync(path.join(sd, NOTES), { recursive: true }); |
|
const readme = path.join(sd, NOTES, NOTES_README); |
|
if (!fs.existsSync(readme)) fs.writeFileSync(readme, NOTES_TEMPLATE, 'utf8'); |
|
return sd; |
|
} catch (e) { |
|
return null; |
|
} |
|
} |
|
|
|
function logPath(workspaceAbs) { |
|
return path.join(workspaceAbs, LOG_REL_PATH); |
|
} |
|
|
|
function outputsDir(workspaceAbs) { |
|
return path.join(workspaceAbs, STATE_DIR_NAME, OUTPUTS); |
|
} |
|
|
|
function plansDir(workspaceAbs) { |
|
return path.join(workspaceAbs, STATE_DIR_NAME, 'plans'); |
|
} |
|
|
|
function runsDir(workspaceAbs) { |
|
return path.join(workspaceAbs, STATE_DIR_NAME, 'runs'); |
|
} |
|
|
|
module.exports = { |
|
STATE_DIR_NAME, LOGS, OUTPUTS, NOTES, |
|
LOG_REL_PATH, NOTES_README, NOTES_TEMPLATE, |
|
stateDirAbs, ensureStateDir, logPath, outputsDir, plansDir, runsDir |
|
};
|
|
|