mister-wolf 2.18.4 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.ru.md +16 -14
- package/dist/adapters/cli/cli-entry.d.ts.map +1 -1
- package/dist/adapters/cli/cli-entry.js +10 -1
- package/dist/adapters/cli/cli-entry.js.map +1 -1
- package/dist/adapters/cli/commands/claim.d.ts.map +1 -1
- package/dist/adapters/cli/commands/claim.js +2 -1
- package/dist/adapters/cli/commands/claim.js.map +1 -1
- package/dist/adapters/cli/commands/memory-sync.d.ts.map +1 -1
- package/dist/adapters/cli/commands/memory-sync.js +3 -0
- package/dist/adapters/cli/commands/memory-sync.js.map +1 -1
- package/dist/adapters/cli/commands/memory-upgrade.d.ts +133 -0
- package/dist/adapters/cli/commands/memory-upgrade.d.ts.map +1 -1
- package/dist/adapters/cli/commands/memory-upgrade.js +507 -5
- package/dist/adapters/cli/commands/memory-upgrade.js.map +1 -1
- package/dist/adapters/cli/commands/upgrade-projects.d.ts +17 -0
- package/dist/adapters/cli/commands/upgrade-projects.d.ts.map +1 -0
- package/dist/adapters/cli/commands/upgrade-projects.js +75 -0
- package/dist/adapters/cli/commands/upgrade-projects.js.map +1 -0
- package/dist/adapters/cli/report-renderer.d.ts +43 -0
- package/dist/adapters/cli/report-renderer.d.ts.map +1 -0
- package/dist/adapters/cli/report-renderer.js +184 -0
- package/dist/adapters/cli/report-renderer.js.map +1 -0
- package/dist/adapters/fs/claim-registry.d.ts.map +1 -1
- package/dist/adapters/fs/claim-registry.js +15 -2
- package/dist/adapters/fs/claim-registry.js.map +1 -1
- package/dist/adapters/fs/projects-registry.d.ts +21 -0
- package/dist/adapters/fs/projects-registry.d.ts.map +1 -1
- package/dist/adapters/fs/projects-registry.js +54 -1
- package/dist/adapters/fs/projects-registry.js.map +1 -1
- package/dist/adapters/fs/update-map.d.ts +102 -0
- package/dist/adapters/fs/update-map.d.ts.map +1 -0
- package/dist/adapters/fs/update-map.js +95 -0
- package/dist/adapters/fs/update-map.js.map +1 -0
- package/dist/adapters/fs/upgrade-lock.d.ts +23 -0
- package/dist/adapters/fs/upgrade-lock.d.ts.map +1 -0
- package/dist/adapters/fs/upgrade-lock.js +59 -0
- package/dist/adapters/fs/upgrade-lock.js.map +1 -0
- package/dist/adapters/render/opencode/opencode-renderer.d.ts +13 -1
- package/dist/adapters/render/opencode/opencode-renderer.d.ts.map +1 -1
- package/dist/adapters/render/opencode/opencode-renderer.js +76 -8
- package/dist/adapters/render/opencode/opencode-renderer.js.map +1 -1
- package/dist/app/use-cases/claim-artifact.d.ts +4 -1
- package/dist/app/use-cases/claim-artifact.d.ts.map +1 -1
- package/dist/app/use-cases/claim-artifact.js +9 -2
- package/dist/app/use-cases/claim-artifact.js.map +1 -1
- package/dist/app/use-cases/project-step.d.ts +52 -0
- package/dist/app/use-cases/project-step.d.ts.map +1 -0
- package/dist/app/use-cases/project-step.js +77 -0
- package/dist/app/use-cases/project-step.js.map +1 -0
- package/dist/app/use-cases/scan-unregistered.d.ts +25 -0
- package/dist/app/use-cases/scan-unregistered.d.ts.map +1 -0
- package/dist/app/use-cases/scan-unregistered.js +74 -0
- package/dist/app/use-cases/scan-unregistered.js.map +1 -0
- package/dist/app/use-cases/seed-base-playbooks.d.ts +10 -0
- package/dist/app/use-cases/seed-base-playbooks.d.ts.map +1 -1
- package/dist/app/use-cases/seed-base-playbooks.js +54 -13
- package/dist/app/use-cases/seed-base-playbooks.js.map +1 -1
- package/dist/app/use-cases/upgrade-projects.d.ts +61 -0
- package/dist/app/use-cases/upgrade-projects.d.ts.map +1 -0
- package/dist/app/use-cases/upgrade-projects.js +379 -0
- package/dist/app/use-cases/upgrade-projects.js.map +1 -0
- package/dist/app/use-cases/verify-against-map.d.ts +48 -0
- package/dist/app/use-cases/verify-against-map.d.ts.map +1 -0
- package/dist/app/use-cases/verify-against-map.js +161 -0
- package/dist/app/use-cases/verify-against-map.js.map +1 -0
- package/dist/ports/base-set-renderer.port.d.ts +13 -0
- package/dist/ports/base-set-renderer.port.d.ts.map +1 -1
- package/package.json +3 -2
- package/templates/.wolf/router.log +1 -1
- package/templates/opencode/plugins/wolf-router.ts +158 -48
- package/update-map.json +204 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { BaseSetRenderer, ModelContext } from '../../ports/base-set-renderer.port.js';
|
|
2
|
+
import type { UpdateMap } from '../../adapters/fs/update-map.js';
|
|
3
|
+
import { type SeedDeps, type SeedOutcome } from './seed-base-playbooks.js';
|
|
4
|
+
import { type SyncVerifyOutcome, type VerifyResult } from './verify-against-map.js';
|
|
5
|
+
/** Внешние зависимости шага: посев (SeedDeps без mode — режим задаёт шаг;
|
|
6
|
+
* files — базовые имена шаблонов, прецедент сборки memory-init.ts:183-196) +
|
|
7
|
+
* рендерер base-set. Контейнер собирает вызывающий слой (T7/Ф4), не шаг. */
|
|
8
|
+
export interface ProjectStepDeps extends Omit<SeedDeps, 'mode'> {
|
|
9
|
+
renderer: BaseSetRenderer;
|
|
10
|
+
/** Контекст моделей для sync-рендера (§4.5); дефолт 'omit' (прецедент sync). */
|
|
11
|
+
models?: ModelContext | 'omit';
|
|
12
|
+
/** Замер wall-time шага (NFR-03); дефолт Date.now. */
|
|
13
|
+
now?: () => number;
|
|
14
|
+
}
|
|
15
|
+
/** Подтверждение REQ-02: проектные пути removed-целей, покрытые единым
|
|
16
|
+
* списком. Шаг НЕ спрашивает второго подтверждения (ADR-4) — но и не
|
|
17
|
+
* удаляет ничего без него (fail-safe: без opts.confirmedRemovals удалений нет,
|
|
18
|
+
* оставшиеся removed-цели дают error сверки — план не доведён). */
|
|
19
|
+
export interface ProjectStepOpts {
|
|
20
|
+
confirmedRemovals?: string[];
|
|
21
|
+
}
|
|
22
|
+
/** Итог шага по exit-модели design §«Exit-модель»: 0-подобный / требует
|
|
23
|
+
* решения / error. Сам exit-код ставит CLI-слой (T7/T9), не шаг. */
|
|
24
|
+
export type ExitKind = 'done' | 'needs-decision' | 'error';
|
|
25
|
+
/** Отчёт по проекту — вход рендера T3 и сводки парка T7. */
|
|
26
|
+
export interface ProjectReport {
|
|
27
|
+
/** Имя (basename) и корень проекта. */
|
|
28
|
+
name: string;
|
|
29
|
+
root: string;
|
|
30
|
+
/** Фазы 1-2: исходы sync; осиротевшие, ОСТАВШИЕСЯ после шага удалений
|
|
31
|
+
* (дрейф без объявления); удалённые в этом проходе (подтверждённые). */
|
|
32
|
+
sync: {
|
|
33
|
+
outcomes: SyncVerifyOutcome[];
|
|
34
|
+
orphaned: string[];
|
|
35
|
+
removed: string[];
|
|
36
|
+
};
|
|
37
|
+
/** Фаза 3: исходы посева — единственная мутация памяти (REQ-07). */
|
|
38
|
+
seed: SeedOutcome[];
|
|
39
|
+
/** Фаза 4: ленивая миграция схемы (backup — внутри guard); refused —
|
|
40
|
+
* отказ guard (например схема из будущего), ошибка передаётся как есть. */
|
|
41
|
+
schema: {
|
|
42
|
+
status: 'ok' | 'migrated' | 'refused';
|
|
43
|
+
error?: string;
|
|
44
|
+
};
|
|
45
|
+
/** Фаза 5: строгая сверка с картой — каждый пункт со статусом (T5). */
|
|
46
|
+
verify: VerifyResult;
|
|
47
|
+
/** Замер шага (NFR-03), мс; минимум 1 — разрешение Date.now-обёртки. */
|
|
48
|
+
wallMs: number;
|
|
49
|
+
exitKind: ExitKind;
|
|
50
|
+
}
|
|
51
|
+
export declare function runProjectStep(deps: ProjectStepDeps, root: string, map: UpdateMap, opts?: ProjectStepOpts): Promise<ProjectReport>;
|
|
52
|
+
//# sourceMappingURL=project-step.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-step.d.ts","sourceRoot":"","sources":["../../../src/app/use-cases/project-step.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC3F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAGjE,OAAO,EAAqB,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC9F,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,yBAAyB,CAAC;AAEjC;;4EAE4E;AAC5E,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC7D,QAAQ,EAAE,eAAe,CAAC;IAC1B,gFAAgF;IAChF,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IAC/B,sDAAsD;IACtD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED;;;mEAGmE;AACnE,MAAM,WAAW,eAAe;IAC9B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;oEACoE;AACpE,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,gBAAgB,GAAG,OAAO,CAAC;AAE3D,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb;4EACwE;IACxE,IAAI,EAAE;QAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/E,oEAAoE;IACpE,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB;+EAC2E;IAC3E,MAAM,EAAE;QAAE,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,SAAS,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,uEAAuE;IACvE,MAAM,EAAE,YAAY,CAAC;IACrB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,SAAS,EACd,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,aAAa,CAAC,CAiExB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// src/app/use-cases/project-step.ts
|
|
2
|
+
// T6 (волна 2.19.0, REQ-03/07/11, ADR-3/4, design §«Проектный шаг»): тонкая
|
|
3
|
+
// композиция ОДНОГО проекта — sync → removals → посев → миграция → сверка.
|
|
4
|
+
// Семантика шагов живёт в самих шагах (ADR-3); здесь только порядок фаз,
|
|
5
|
+
// ввод подтверждения удалений (REQ-02/ADR-4) и сведение исходов в ProjectReport
|
|
6
|
+
// (контракт для оркестратора T7 и рендера T3). Пофазная фиксация: записи фаз
|
|
7
|
+
// атомарны внутри шагов, сбой фазы k не откатывает k-1 — повтор доводит до
|
|
8
|
+
// конца (NFR-02). Единственная мутация памяти — посев (REQ-07).
|
|
9
|
+
import { existsSync } from 'fs';
|
|
10
|
+
import { unlink } from 'fs/promises';
|
|
11
|
+
import { basename, join } from 'path';
|
|
12
|
+
import { ensureCurrentSchema } from '../../adapters/fs/schema-guard.js';
|
|
13
|
+
import { syncBaseSet } from './sync-base-set.js';
|
|
14
|
+
import { seedBasePlaybooks } from './seed-base-playbooks.js';
|
|
15
|
+
import { projectPath as mapEntryProjectPath, verifyAgainstMap, } from './verify-against-map.js';
|
|
16
|
+
export async function runProjectStep(deps, root, map, opts = {}) {
|
|
17
|
+
const now = deps.now ?? Date.now;
|
|
18
|
+
const startedAt = now();
|
|
19
|
+
// 1. sync: перезапись / skip-mutated / identical; orphaned — вход шага удалений.
|
|
20
|
+
const { outcomes: syncOutcomes, orphaned } = await syncBaseSet(deps.renderer, root, deps.models ?? 'omit');
|
|
21
|
+
// 2. removals: удаляется только объявленное картой И подтверждённое списком
|
|
22
|
+
// REQ-02 (второго подтверждения нет — ADR-4). Прочий orphaned не трогаем.
|
|
23
|
+
const removedTargets = new Set(map.files.filter((e) => e.category === 'removed').map((e) => mapEntryProjectPath(e)));
|
|
24
|
+
const confirmed = new Set(opts.confirmedRemovals ?? []);
|
|
25
|
+
const removed = [];
|
|
26
|
+
for (const p of orphaned) {
|
|
27
|
+
if (!removedTargets.has(p) || !confirmed.has(p))
|
|
28
|
+
continue;
|
|
29
|
+
await unlink(join(root, p));
|
|
30
|
+
removed.push(p);
|
|
31
|
+
}
|
|
32
|
+
// Контракт T5: removals = подтверждённо отсутствующие ПОСЛЕ шага — удалённые
|
|
33
|
+
// теперь или отсутствовавшие ранее (идемпотентность повтора, NFR-02).
|
|
34
|
+
const removals = [...removedTargets].filter((p) => confirmed.has(p) && !existsSync(join(root, p)));
|
|
35
|
+
// Дрейф без объявления: оставшийся orphaned вне карты — факт для сверки
|
|
36
|
+
// («файл вне карты» → conflict → «требует решения», design §«Сверка»).
|
|
37
|
+
const drift = orphaned
|
|
38
|
+
.filter((p) => !removedTargets.has(p))
|
|
39
|
+
.map((p) => ({
|
|
40
|
+
file: p,
|
|
41
|
+
action: 'conflict',
|
|
42
|
+
reason: 'orphaned after pass — stamped file outside the map, not declared removed (drift without declaration)',
|
|
43
|
+
}));
|
|
44
|
+
// 3. посев — только недостающие лица (mode задаёт шаг) и только шаблоны,
|
|
45
|
+
// объявленные картой с seed:true; deprecated-шаблоны не сеются (REQ-11).
|
|
46
|
+
const seedTemplates = new Set(map.faces.filter((f) => f.seed).map((f) => basename(f.template)));
|
|
47
|
+
const seedFiles = new Map([...deps.files].filter(([file]) => seedTemplates.has(file)));
|
|
48
|
+
const seedOutcomes = await seedBasePlaybooks({ ...deps, files: seedFiles, mode: 'seed-missing-only' });
|
|
49
|
+
// 4. миграция: отказ guard'а (например схема из будущего) — в отчёт как есть,
|
|
50
|
+
// не крах шага; эффекты фаз 1-3 стабильны.
|
|
51
|
+
let schema = { status: 'ok' };
|
|
52
|
+
try {
|
|
53
|
+
schema = { status: await ensureCurrentSchema(root) };
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
schema = { status: 'refused', error: err instanceof Error ? err.message : String(err) };
|
|
57
|
+
}
|
|
58
|
+
// 5. сверка: исходы всех фаз → статус каждого пункта карты.
|
|
59
|
+
const verify = verifyAgainstMap(map, {
|
|
60
|
+
syncOutcomes: [...syncOutcomes, ...drift],
|
|
61
|
+
seedOutcomes,
|
|
62
|
+
removals,
|
|
63
|
+
});
|
|
64
|
+
const errors = verify.summary.errors + (schema.status === 'refused' ? 1 : 0);
|
|
65
|
+
const exitKind = errors > 0 ? 'error' : verify.summary.needsDecision > 0 ? 'needs-decision' : 'done';
|
|
66
|
+
return {
|
|
67
|
+
name: basename(root),
|
|
68
|
+
root,
|
|
69
|
+
sync: { outcomes: syncOutcomes, orphaned: orphaned.filter((p) => !removed.includes(p)), removed },
|
|
70
|
+
seed: seedOutcomes,
|
|
71
|
+
schema,
|
|
72
|
+
verify,
|
|
73
|
+
wallMs: Math.max(1, now() - startedAt),
|
|
74
|
+
exitKind,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=project-step.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-step.js","sourceRoot":"","sources":["../../../src/app/use-cases/project-step.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ScanUnregisteredDeps {
|
|
2
|
+
/** Пути из реестра (projects.yaml); сверка по realpath (прецедент T4 dedupeByRealpath), несуществующие пропускаются мягко. */
|
|
3
|
+
registeredPaths: string[];
|
|
4
|
+
/** Корень скана; по умолчанию домашний каталог. */
|
|
5
|
+
root?: string;
|
|
6
|
+
/** Максимальная глубина обхода (уровни каталогов ниже root). */
|
|
7
|
+
maxDepth?: number;
|
|
8
|
+
/** Мягкий бюджет скана, мс: при превышении вернуть найденное к моменту остановки. */
|
|
9
|
+
budgetMs?: number;
|
|
10
|
+
/** Инжект часов (бюджет тестируем без fake timers). */
|
|
11
|
+
now?: () => number;
|
|
12
|
+
}
|
|
13
|
+
export type ScanResult = {
|
|
14
|
+
found: number;
|
|
15
|
+
top: string[];
|
|
16
|
+
hint: string;
|
|
17
|
+
} | null;
|
|
18
|
+
/**
|
|
19
|
+
* Ограниченный read-only скан живых памятей вне реестра (REQ-09):
|
|
20
|
+
* обход root BFS на глубину maxDepth, «живая» = `<dir>/.wolf/memory`.
|
|
21
|
+
* Read-only (readdir/stat/realpath); мутаций и автозаписи в реестр нет.
|
|
22
|
+
* null — ничего не найдено или root недоступен (R09.2: это не ошибка).
|
|
23
|
+
*/
|
|
24
|
+
export declare function scanUnregistered(deps: ScanUnregisteredDeps): Promise<ScanResult>;
|
|
25
|
+
//# sourceMappingURL=scan-unregistered.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-unregistered.d.ts","sourceRoot":"","sources":["../../../src/app/use-cases/scan-unregistered.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,oBAAoB;IACnC,8HAA8H;IAC9H,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC;AAK/E;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,CA6DtF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { readdir, realpath, stat } from 'fs/promises';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
const HINT_TAIL = 'projects with wolf memory outside the registry; running any wolf command in a project registers it (self-healing)';
|
|
5
|
+
/**
|
|
6
|
+
* Ограниченный read-only скан живых памятей вне реестра (REQ-09):
|
|
7
|
+
* обход root BFS на глубину maxDepth, «живая» = `<dir>/.wolf/memory`.
|
|
8
|
+
* Read-only (readdir/stat/realpath); мутаций и автозаписи в реестр нет.
|
|
9
|
+
* null — ничего не найдено или root недоступен (R09.2: это не ошибка).
|
|
10
|
+
*/
|
|
11
|
+
export async function scanUnregistered(deps) {
|
|
12
|
+
const root = deps.root ?? homedir();
|
|
13
|
+
const maxDepth = deps.maxDepth ?? 4;
|
|
14
|
+
const budgetMs = deps.budgetMs ?? 5000;
|
|
15
|
+
const now = deps.now ?? Date.now;
|
|
16
|
+
const registered = new Set();
|
|
17
|
+
for (const path of deps.registeredPaths) {
|
|
18
|
+
try {
|
|
19
|
+
registered.add(await realpath(path));
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// несуществующий registered-путь realpath не резолвится — пропускаем мягко
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const startedAt = now();
|
|
26
|
+
const candidates = [];
|
|
27
|
+
const queue = [{ dir: root, depth: 0 }];
|
|
28
|
+
for (let i = 0; i < queue.length; i++) {
|
|
29
|
+
const { dir, depth } = queue[i];
|
|
30
|
+
if (now() - startedAt > budgetMs)
|
|
31
|
+
break; // мягкая остановка: вернуть найденное к моменту превышения
|
|
32
|
+
let entries;
|
|
33
|
+
try {
|
|
34
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
continue; // недоступный каталог (права/ошибки) — не ошибка скана (R09.2)
|
|
38
|
+
}
|
|
39
|
+
const memoryStat = await stat(join(dir, '.wolf', 'memory')).catch(() => null);
|
|
40
|
+
if (memoryStat) {
|
|
41
|
+
let real = dir;
|
|
42
|
+
try {
|
|
43
|
+
real = await realpath(dir);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// dir только что прочитан readdir'ом; на всякий случай падаем назад на сам путь
|
|
47
|
+
}
|
|
48
|
+
if (!registered.has(real)) {
|
|
49
|
+
let lastActivityMs = memoryStat.mtimeMs; // fallback — mtime .wolf/memory
|
|
50
|
+
const eventsStat = await stat(join(dir, '.wolf', 'events.jsonl')).catch(() => null);
|
|
51
|
+
if (eventsStat)
|
|
52
|
+
lastActivityMs = eventsStat.mtimeMs;
|
|
53
|
+
candidates.push({ dir, lastActivityMs });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (depth >= maxDepth)
|
|
57
|
+
continue;
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
// без спуска в symlink'и (циклы) и в .wolf/node_modules — проектов там нет, бюджет дороже
|
|
60
|
+
if (!entry.isDirectory() || entry.name === '.wolf' || entry.name === 'node_modules')
|
|
61
|
+
continue;
|
|
62
|
+
queue.push({ dir: join(dir, entry.name), depth: depth + 1 });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (candidates.length === 0)
|
|
66
|
+
return null;
|
|
67
|
+
candidates.sort((a, b) => b.lastActivityMs - a.lastActivityMs); // самый свежий первым
|
|
68
|
+
return {
|
|
69
|
+
found: candidates.length,
|
|
70
|
+
top: candidates.slice(0, 5).map((c) => c.dir),
|
|
71
|
+
hint: `found ${candidates.length} ${HINT_TAIL}`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=scan-unregistered.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-unregistered.js","sourceRoot":"","sources":["../../../src/app/use-cases/scan-unregistered.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,11 @@ import { MemoryTypeDeclaration } from '../../domain/memory-types.js';
|
|
|
8
8
|
export interface SeedOutcome {
|
|
9
9
|
file: string;
|
|
10
10
|
action: 'created' | 'updated' | 'skipped' | 'diverged';
|
|
11
|
+
/** Структурный код исхода для сверки (design §«Сверка», T5): выставляется
|
|
12
|
+
* ТОЛЬКО в mode='seed-missing-only' — seeded | skipped-live |
|
|
13
|
+
* legacy-absorbed | diverged; в дефолтном режиме отсутствует.
|
|
14
|
+
* НЕ reason-строка: consumer различает исходы по полю, не парсингом. */
|
|
15
|
+
kind?: 'seeded' | 'skipped-live' | 'legacy-absorbed' | 'diverged';
|
|
11
16
|
reason?: string;
|
|
12
17
|
}
|
|
13
18
|
export interface SeedDeps {
|
|
@@ -19,6 +24,11 @@ export interface SeedDeps {
|
|
|
19
24
|
index?: SearchIndex;
|
|
20
25
|
lock?: MemoryLock;
|
|
21
26
|
declarations?: readonly MemoryTypeDeclaration[];
|
|
27
|
+
/** 2.19.0 T2 (ADR-3, design §«Проектный шаг» шаг 3): посев ТОЛЬКО
|
|
28
|
+
* недостающих лиц; живые лица не трогаются (без template-update /
|
|
29
|
+
* переверсионирования); исходы несут структурный код kind. Дефолт
|
|
30
|
+
* (undefined) — прежнее поведение с template-update. */
|
|
31
|
+
mode?: 'seed-missing-only';
|
|
22
32
|
}
|
|
23
33
|
/** Посев + шаблонное обновление live-лиц (§3.6): одна точка решения о записи
|
|
24
34
|
* для каждого шаблона base-set с owner_skill. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-base-playbooks.d.ts","sourceRoot":"","sources":["../../../src/app/use-cases/seed-base-playbooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAIrE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IACvD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAeD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,KAAK,EAAE,WAAW,CAAC;IACnB,GAAG,EAAE,QAAQ,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,YAAY,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"seed-base-playbooks.d.ts","sourceRoot":"","sources":["../../../src/app/use-cases/seed-base-playbooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAIrE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IACvD;;;6EAGyE;IACzE,IAAI,CAAC,EAAE,QAAQ,GAAG,cAAc,GAAG,iBAAiB,GAAG,UAAU,CAAC;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAeD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,KAAK,EAAE,WAAW,CAAC;IACnB,GAAG,EAAE,QAAQ,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,YAAY,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAChD;;;6DAGyD;IACzD,IAAI,CAAC,EAAE,mBAAmB,CAAC;CAC5B;AAyBD;iDACiD;AACjD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CA0H9E"}
|
|
@@ -25,6 +25,7 @@ async function activeLegacyHead(store, ownerSkill) {
|
|
|
25
25
|
* для каждого шаблона base-set с owner_skill. */
|
|
26
26
|
export async function seedBasePlaybooks(deps) {
|
|
27
27
|
const outcomes = [];
|
|
28
|
+
const missingOnly = deps.mode === 'seed-missing-only';
|
|
28
29
|
const processedOwners = new Set();
|
|
29
30
|
// ponytail: без .sort() — порядок вставки Map функционально не важен
|
|
30
31
|
for (const [file, raw] of deps.files) {
|
|
@@ -35,6 +36,9 @@ export async function seedBasePlaybooks(deps) {
|
|
|
35
36
|
file,
|
|
36
37
|
action: 'skipped',
|
|
37
38
|
reason: `owner_skill=${ownerSkill} already seeded from another template in this run`,
|
|
39
|
+
// 2.19.0: структурный код для сверки (T5) — дедуп означает живое лицо
|
|
40
|
+
// уже посеяно в этом прогоне; не error (риск №2 отчёта T5).
|
|
41
|
+
...(missingOnly ? { kind: 'skipped-live' } : {}),
|
|
38
42
|
});
|
|
39
43
|
continue;
|
|
40
44
|
}
|
|
@@ -55,21 +59,51 @@ export async function seedBasePlaybooks(deps) {
|
|
|
55
59
|
.filter(Boolean),
|
|
56
60
|
legacyHeadId: legacyHead?.id,
|
|
57
61
|
});
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
if (missingOnly) {
|
|
63
|
+
outcomes.push(legacyHead !== null
|
|
64
|
+
? {
|
|
65
|
+
file,
|
|
66
|
+
action: 'created',
|
|
67
|
+
kind: 'legacy-absorbed',
|
|
68
|
+
reason: `seeded from template; superseded legacy howto ${legacyHead.id}`,
|
|
69
|
+
}
|
|
70
|
+
: { file, action: 'created', kind: 'seeded' });
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
outcomes.push(legacyHead !== null
|
|
74
|
+
? {
|
|
75
|
+
file,
|
|
76
|
+
action: 'created',
|
|
77
|
+
reason: `seeded from template; superseded legacy howto ${legacyHead.id}`,
|
|
78
|
+
}
|
|
79
|
+
: { file, action: 'created' });
|
|
80
|
+
}
|
|
65
81
|
continue;
|
|
66
82
|
}
|
|
67
83
|
// лицо есть: идемпотентный skip либо решение о шаблонном обновлении
|
|
68
84
|
if (active.body === body) {
|
|
69
|
-
outcomes.push(
|
|
85
|
+
outcomes.push(missingOnly
|
|
86
|
+
? {
|
|
87
|
+
file,
|
|
88
|
+
action: 'skipped',
|
|
89
|
+
kind: 'skipped-live',
|
|
90
|
+
reason: `live face v${active.version} matches template — untouched (seed-missing-only)`,
|
|
91
|
+
}
|
|
92
|
+
: { file, action: 'skipped', reason: `active face v${active.version} matches template` });
|
|
70
93
|
continue;
|
|
71
94
|
}
|
|
72
95
|
if (active.initiator === 'seed' || active.initiator === 'migration') {
|
|
96
|
+
// seed-missing-only: живое лицо не трогаем — штатное отставание (ADR-3,
|
|
97
|
+
// REQ-03 AC2 / REQ-07): обновление живых лиц — зона Стюарда (кандидат 2.20.0)
|
|
98
|
+
if (missingOnly) {
|
|
99
|
+
outcomes.push({
|
|
100
|
+
file,
|
|
101
|
+
action: 'skipped',
|
|
102
|
+
kind: 'skipped-live',
|
|
103
|
+
reason: `live face v${active.version} lags template (initiator ${active.initiator}) — untouched (seed-missing-only)`,
|
|
104
|
+
});
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
73
107
|
await createFaceVersion(deps, {
|
|
74
108
|
command: 'seed',
|
|
75
109
|
ownerSkill,
|
|
@@ -88,11 +122,18 @@ export async function seedBasePlaybooks(deps) {
|
|
|
88
122
|
});
|
|
89
123
|
}
|
|
90
124
|
else {
|
|
91
|
-
outcomes.push(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
125
|
+
outcomes.push(missingOnly
|
|
126
|
+
? {
|
|
127
|
+
file,
|
|
128
|
+
action: 'diverged',
|
|
129
|
+
kind: 'diverged',
|
|
130
|
+
reason: `diverged: face v${active.version} initiator=${active.initiator} — left untouched (steward zone, D4)`,
|
|
131
|
+
}
|
|
132
|
+
: {
|
|
133
|
+
file,
|
|
134
|
+
action: 'diverged',
|
|
135
|
+
reason: `diverged: face v${active.version} initiator=${active.initiator} — left untouched (steward zone, D4)`,
|
|
136
|
+
});
|
|
96
137
|
}
|
|
97
138
|
}
|
|
98
139
|
return outcomes;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-base-playbooks.js","sourceRoot":"","sources":["../../../src/app/use-cases/seed-base-playbooks.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"seed-base-playbooks.js","sourceRoot":"","sources":["../../../src/app/use-cases/seed-base-playbooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type RegisteredProject } from '../../adapters/fs/projects-registry.js';
|
|
2
|
+
import { type UpdateMap } from '../../adapters/fs/update-map.js';
|
|
3
|
+
import type { Counter, ReportNode } from '../../adapters/cli/report-renderer.js';
|
|
4
|
+
import { runProjectStep, type ProjectReport, type ProjectStepDeps } from './project-step.js';
|
|
5
|
+
import { scanUnregistered } from './scan-unregistered.js';
|
|
6
|
+
export interface UpgradeProjectsDeps {
|
|
7
|
+
/** Реестр проектов; listStrict различает «пусто» и «нечитаем» (T4). */
|
|
8
|
+
registry: {
|
|
9
|
+
listStrict(): Promise<RegisteredProject[]>;
|
|
10
|
+
};
|
|
11
|
+
/** Карта установленного релиза (T1), один раз на проход. */
|
|
12
|
+
loadMap: () => UpdateMap;
|
|
13
|
+
/** Проектный шаг (T6); мок в юнит-контуре, дефолт — runProjectStep. */
|
|
14
|
+
runStep?: typeof runProjectStep;
|
|
15
|
+
/** Фабрика проектных deps: адаптеры памяти привязаны к корню проекта
|
|
16
|
+
* (store/log/lock — per-project), один набор на весь парк невозможен.
|
|
17
|
+
* Собирает вызывающий слой (T8-контейнер), не проход. */
|
|
18
|
+
makeStepDeps: (root: string) => ProjectStepDeps;
|
|
19
|
+
/** Lock параллельного upgrade (T4); отсутствует — проход без lock. */
|
|
20
|
+
upgradeLock?: {
|
|
21
|
+
acquire(id: string): boolean;
|
|
22
|
+
release(id: string): void;
|
|
23
|
+
};
|
|
24
|
+
/** Скан незарегистрированных (REQ-09, T12); отсутствует — скан не выполняется
|
|
25
|
+
* (изоляция юнит-контура: дефолт скана — домашний каталог). */
|
|
26
|
+
scan?: typeof scanUnregistered;
|
|
27
|
+
}
|
|
28
|
+
export interface UpgradeProjectsOpts {
|
|
29
|
+
/** --yes: применить список без вопросов (REQ-02). */
|
|
30
|
+
yes?: boolean;
|
|
31
|
+
/** TTY-режим caller'а: подтверждение возможно только в TTY. */
|
|
32
|
+
tty?: boolean;
|
|
33
|
+
/** Интерактивное подтверждение списка; вызывается при tty && !yes.
|
|
34
|
+
* Аргумент — plans-секция (список+категории REQ-02): caller показывает её
|
|
35
|
+
* ДО вопроса (design «Фазы»: список+категории → подтверждение). */
|
|
36
|
+
confirm?: (plans: ReportNode) => boolean | Promise<boolean>;
|
|
37
|
+
/** Дефолт часов шагов (NFR-03), если фабрика шага не задала свои. */
|
|
38
|
+
now?: () => number;
|
|
39
|
+
}
|
|
40
|
+
export interface UpgradeRunResult {
|
|
41
|
+
exitCode: 0 | 1 | 2;
|
|
42
|
+
report: ReportNode;
|
|
43
|
+
counters: Counter[];
|
|
44
|
+
}
|
|
45
|
+
/** Статус проекта в проходе (REQ-05, палитра T3); T9 (--here) переиспользует
|
|
46
|
+
* словарь точечным импортом — единая семантика статусов для одной поверхности. */
|
|
47
|
+
export type OutcomeStatus = 'updated' | 'up-to-date' | 'needs-decision' | 'error';
|
|
48
|
+
export declare function runUpgradeProjects(deps: UpgradeProjectsDeps, opts?: UpgradeProjectsOpts): Promise<UpgradeRunResult>;
|
|
49
|
+
/** Статус проекта по отчёту шага (REQ-05): done с фактическими изменениями
|
|
50
|
+
* этого прохода — updated, без — up-to-date; needs-decision/error — как есть.
|
|
51
|
+
* «Действие» берём из фаз шага, не из кодов сверки: verify-код removed —
|
|
52
|
+
* состояние «подтверждённо отсутствует» (идемпотентность NFR-02), в повторном
|
|
53
|
+
* прогоне это не изменение. */
|
|
54
|
+
export declare function statusOf(report: ProjectReport): OutcomeStatus;
|
|
55
|
+
/** Категории карты (числами, REQ-02/R11.6) — считаются один раз по карте.
|
|
56
|
+
* Экспорт — точечный reuse для T9 (--here, одиночный план). */
|
|
57
|
+
export declare function mapCategories(map: UpdateMap): Record<'new' | 'changed' | 'deprecated' | 'removed', number>;
|
|
58
|
+
/** Отображение статуса в строке отчёта (REQ-05): «требует решения» — текст
|
|
59
|
+
* счётчика, не литерал ExitKind шага. Экспорт — точечный reuse для T9 (--here). */
|
|
60
|
+
export declare const STATUS_TEXT: Record<OutcomeStatus, string>;
|
|
61
|
+
//# sourceMappingURL=upgrade-projects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade-projects.d.ts","sourceRoot":"","sources":["../../../src/app/use-cases/upgrade-projects.ts"],"names":[],"mappings":"AAYA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAIlG,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAClF,OAAO,KAAK,EAAE,OAAO,EAAU,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAO1D,MAAM,WAAW,mBAAmB;IAClC,uEAAuE;IACvE,QAAQ,EAAE;QAAE,UAAU,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAA;KAAE,CAAC;IACzD,4DAA4D;IAC5D,OAAO,EAAE,MAAM,SAAS,CAAC;IACzB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,cAAc,CAAC;IAChC;;6DAEyD;IACzD,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,eAAe,CAAC;IAChD,sEAAsE;IACtE,WAAW,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAC1E;mEAC+D;IAC/D,IAAI,CAAC,EAAE,OAAO,gBAAgB,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,qDAAqD;IACrD,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;uEAEmE;IACnE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED;kFACkF;AAClF,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,YAAY,GAAG,gBAAgB,GAAG,OAAO,CAAC;AAwClF,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,mBAAmB,EACzB,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAe3B;AAmLD;;;;+BAI+B;AAC/B,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAQ7D;AAED;+DAC+D;AAC/D,wBAAgB,aAAa,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAAC,KAAK,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,EAAE,MAAM,CAAC,CAM1G;AA6DD;mFACmF;AACnF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAKrD,CAAC"}
|