mindnet_obsidian/src/interview/wizardState.ts
Lars 8186ca5ce0
Some checks are pending
Node.js build / build (20.x) (push) Waiting to run
Node.js build / build (22.x) (push) Waiting to run
Enhance interview configuration and documentation for WP-26 integration
- Added the `Interview_Config_Guide.md` for comprehensive instructions on creating interview profiles and utilizing various note types.
- Updated `00_Dokumentations_Index.md` to include links to the new guide and improved navigation for WP-26 related resources.
- Enhanced `06_Konfigurationsdateien_Referenz.md` with references to the new guide and clarified YAML structure for interview configurations.
- Introduced `audit_geburtsdatei.md` for detailed analysis of section connections and edge types, highlighting critical issues and recommendations for improvement.
- Improved renderer tests to ensure proper handling of section types and edge generation, aligning with the new WP-26 features.
2026-01-30 12:37:06 +01:00

139 lines
4.4 KiB
TypeScript

import type { InterviewProfile, InterviewStep } from "./types";
import type { LoopRuntimeState } from "./loopState";
export interface PendingEdgeAssignment {
filePath: string;
sectionKey: string; // identifies heading/section in file (e.g. "H2:Wendepunkte..." or "ROOT")
linkBasename: string; // target note basename
chosenRawType: string; // user chosen edge type (alias allowed)
sourceNoteId?: string; // from frontmatter.id (optional)
targetNoteId?: string; // if resolved (optional)
createdAt: number;
}
// WP-26: Section-Info für Block-ID und Section-Type Tracking
export interface SectionInfo {
stepKey: string;
sectionType: string | null;
heading: string;
blockId: string | null;
noteType: string;
}
export interface WizardState {
profile: InterviewProfile;
currentStepIndex: number;
stepHistory: number[]; // Stack for back navigation
collectedData: Map<string, unknown>; // key -> value
loopContexts: Map<string, unknown[]>; // loop key -> array of collected items (deprecated, use loopRuntimeStates)
loopRuntimeStates: Map<string, LoopRuntimeState>; // loop step key -> runtime state
patches: Patch[]; // Collected patches to apply
activeLoopPath: string[]; // Stack of loop keys representing current nesting level (e.g. ["items", "item_list"])
pendingEdgeAssignments: PendingEdgeAssignment[]; // Inline micro edge assignments collected during wizard
// WP-26: Section-Type und Block-ID Tracking
generatedBlockIds: Map<string, SectionInfo>;
sectionSequence: SectionInfo[];
}
export interface Patch {
type: "frontmatter" | "content";
field?: string; // For frontmatter patches
value: unknown;
lineStart?: number;
lineEnd?: number;
}
export function createWizardState(profile: InterviewProfile): WizardState {
// Log flattened steps before creating state
const flat = flattenSteps(profile.steps);
const flatKinds = flat.map(s => s.type);
console.log("Wizard flattened steps", {
count: flat.length,
kinds: flatKinds,
});
return {
profile,
currentStepIndex: 0,
stepHistory: [],
collectedData: new Map(),
loopContexts: new Map(), // Keep for backwards compatibility
loopRuntimeStates: new Map(),
patches: [],
activeLoopPath: [], // Start at top level
pendingEdgeAssignments: [], // Start with empty pending assignments
// WP-26: Initialize Section-Type und Block-ID Tracking
generatedBlockIds: new Map(),
sectionSequence: [],
};
}
export function getCurrentStep(state: WizardState): InterviewStep | null {
const steps = flattenSteps(state.profile.steps);
// Log flattened steps count
if (state.currentStepIndex === 0) {
console.log("Flattened steps", { count: steps.length });
}
if (steps.length === 0) {
console.warn("No steps available in profile", { profileKey: state.profile.key });
return null;
}
if (state.currentStepIndex >= 0 && state.currentStepIndex < steps.length) {
return steps[state.currentStepIndex] || null;
}
return null;
}
export function getNextStepIndex(state: WizardState): number | null {
const steps = flattenSteps(state.profile.steps);
if (state.currentStepIndex < steps.length - 1) {
return state.currentStepIndex + 1;
}
return null;
}
export function getPreviousStepIndex(state: WizardState): number | null {
if (state.stepHistory.length > 0) {
const prev = state.stepHistory[state.stepHistory.length - 1];
return prev !== undefined ? prev : null;
}
return null;
}
export function canGoNext(state: WizardState): boolean {
return getNextStepIndex(state) !== null;
}
export function canGoBack(state: WizardState): boolean {
return state.stepHistory.length > 0;
}
/**
* Flatten steps including loops into a linear array.
* Returns ALL top-level steps (instruction, capture_text, capture_frontmatter, llm_dialog, review, loop).
* For loops, includes the loop step itself (nested items are handled during execution).
* Exported for use in InterviewWizardModal.
*/
export function flattenSteps(steps: InterviewStep[]): InterviewStep[] {
const result: InterviewStep[] = [];
if (!steps || steps.length === 0) {
return result;
}
for (const step of steps) {
if (!step) {
console.warn("Skipping null/undefined step");
continue;
}
// Include all step types: instruction, capture_text, capture_frontmatter, llm_dialog, review, loop
// For loops, include the loop step itself (nested items handled during execution)
result.push(step);
}
return result;
}