feat(secretary): fluffy flag also reads runtime sentinel file

This commit is contained in:
Дмитрий
2026-06-25 14:20:03 +03:00
parent 60de623094
commit 9eaca057ca
2 changed files with 24 additions and 5 deletions
+11 -4
View File
@@ -1,3 +1,7 @@
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import { homedir } from 'node:os';
// Детект команды секретаря в тексте промпта. Кавычки/код снимаются до сопоставления,
// чтобы цитирование не срабатывало (приём как в существующих детекторах).
function stripQuoted(text) {
@@ -55,8 +59,11 @@ export function resolveCaseActivation(requested, existing = []) {
return { action: 'activate', work: String(requested || '').trim() };
}
// Флаг нового конвейера «пушистое дерево». ВЫКЛ по умолчанию — подпроект A кладётся «тёмным»,
// включается только когда воркер (подпроект B) вживит конвейер.
export function fluffyPipelineOn(env = process.env) {
return env.SECRETARY_FLUFFY === '1' || env.SECRETARY_FLUFFY === 'true';
function defaultFluffyFile() { return join(homedir(), '.claude', 'runtime', 'secretary-fluffy'); }
/** Флаг конвейера «пушистое дерево». ВКЛ если env SECRETARY_FLUFFY=1|true ИЛИ есть рантайм-файл-сентинел.
* Рантайм-файл позволяет тогглить без правки settings.json. */
export function fluffyPipelineOn(env = process.env, file = defaultFluffyFile()) {
if (env.SECRETARY_FLUFFY === '1' || env.SECRETARY_FLUFFY === 'true') return true;
try { return existsSync(file); } catch { return false; }
}
+13 -1
View File
@@ -1,4 +1,7 @@
import { describe, it, expect } from 'vitest';
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { detectSecretaryCommand, secretaryModeFileName, resolveCaseActivation, fluffyPipelineOn } from './secretary-flag.mjs';
describe('detectSecretaryCommand', () => {
@@ -61,3 +64,12 @@ describe('fluffyPipelineOn', () => {
expect(fluffyPipelineOn({ SECRETARY_FLUFFY: 'true' })).toBe(true);
});
});
describe('fluffyPipelineOn runtime file', () => {
let dir, file;
beforeEach(() => { dir = mkdtempSync(join(tmpdir(), 'secflag-')); file = join(dir, 'secretary-fluffy'); });
afterEach(() => { rmSync(dir, { recursive: true, force: true }); });
it('env wins when set', () => { expect(fluffyPipelineOn({ SECRETARY_FLUFFY: '1' }, file)).toBe(true); });
it('runtime file present → on, even without env', () => { writeFileSync(file, ''); expect(fluffyPipelineOn({}, file)).toBe(true); });
it('neither → off', () => { expect(fluffyPipelineOn({}, file)).toBe(false); });
});