-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy path.windsurfrules
More file actions
79 lines (61 loc) · 2.86 KB
/
Copy path.windsurfrules
File metadata and controls
79 lines (61 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# footprint.js — Windsurf Rules
This is the footprint.js library — the flowchart pattern for backend code. Self-explainable systems that AI can reason about.
## Core Principle
**Collect during traversal, never post-process.** All data collection happens as side effects of the single DFS traversal. Never walk the tree after execution.
## Architecture
```
src/lib/
├── memory/ → Transactional state (SharedMemory, StageContext, TransactionBuffer)
├── schema/ → Validation (Zod optional, duck-typed)
├── builder/ → Fluent DSL (FlowChartBuilder, flowChart())
├── scope/ → Per-stage facades + recorders + providers
├── engine/ → DFS traversal + narrative + handlers
├── runner/ → FlowChartExecutor
└── contract/ → I/O schema + OpenAPI
```
Entry points: `footprintjs` (public) and `footprintjs/advanced` (internals).
## Builder API
```typescript
flowChart(name, fn, id, extractor?, description?)
.addFunction(name, fn, id, description?)
.addDeciderFunction(name, fn, id, description?)
.addFunctionBranch(branchId, name, fn) / .setDefault(id) / .end()
.addSelectorFunction(name, fn, id, description?)
.addListOfFunction([...], { failFast? })
.addSubFlowChartNext(id, subflow, mount, { inputMapper?, outputMapper? })
.loopTo(stageId)
.setEnableNarrative()
.build() / .toSpec() / .toMermaid()
```
## Stage Functions
```typescript
(scope: ScopeFacade, breakPipeline: () => void, streamCallback?: StreamCallback) => void | Promise<void>
```
## ScopeFacade
```typescript
scope.getValue('key') // tracked read → narrative
scope.setValue('key', value) // tracked write → narrative
scope.updateValue('key', partial) // deep merge (tracked)
scope.deleteValue('key') // tracked delete
scope.getArgs<T>() // frozen readonly input (NOT tracked)
```
## Executor
```typescript
const executor = new FlowChartExecutor(chart);
await executor.run({ input, timeoutMs?, signal? });
executor.getNarrative() // combined flow + data
executor.getNarrativeEntries() // structured entries
executor.getSnapshot() // memory state
executor.attachFlowRecorder(r) // plug flow observer
executor.setRedactionPolicy({ keys, patterns, fields })
```
## Observer Systems
- **Scope Recorder**: fires DURING stage (`onRead`, `onWrite`, `onCommit`)
- **FlowRecorder**: fires AFTER stage (`onStageExecuted`, `onDecision`, `onFork`, `onLoop`)
- 8 built-in strategies (Narrative, Adaptive, Windowed, RLE, Milestone, Progressive, Separate, Manifest)
- `CombinedNarrativeRecorder` implements both — auto-attached by `setEnableNarrative()`
## Rules
- Never post-process the tree — use recorders
- `getValue()`/`setValue()` for tracked state; `getArgs()` for frozen input
- Don't use deprecated `CombinedNarrativeBuilder`
- `setEnableNarrative()` is all you need for narrative