ferix-code 0.0.2-beta.2 → 0.0.2-beta.4

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +475 -14
  2. package/dist/index.js +1454 -775
  3. package/package.json +1 -3
package/dist/index.js CHANGED
@@ -71,7 +71,7 @@ import { Command } from "commander";
71
71
  // package.json
72
72
  var package_default = {
73
73
  name: "ferix-code",
74
- version: "0.0.2-beta.2",
74
+ version: "0.0.2-beta.4",
75
75
  description: "Composable RALPH loops for AI coding agents - v2 with Effect",
76
76
  type: "module",
77
77
  bin: {
@@ -88,8 +88,6 @@ var package_default = {
88
88
  "test:watch": "bun test --watch"
89
89
  },
90
90
  dependencies: {
91
- "@effect/platform": "^0.94.2",
92
- "@effect/platform-node": "^0.78.0",
93
91
  commander: "^14.0.0",
94
92
  effect: "^3.19.15",
95
93
  "human-id": "^4.1.3",
@@ -118,7 +116,7 @@ var package_default = {
118
116
 
119
117
  // src/program.ts
120
118
  init_esm_shims();
121
- import { Effect as Effect17, Stream as Stream10 } from "effect";
119
+ import { Effect as Effect21, Stream as Stream10 } from "effect";
122
120
 
123
121
  // src/consumers/index.ts
124
122
  init_esm_shims();
@@ -1305,6 +1303,34 @@ stateReducerRegistry.register(loopStartedReducer);
1305
1303
  stateReducerRegistry.register(loopCompletedReducer);
1306
1304
  stateReducerRegistry.register(loopFailedReducer);
1307
1305
 
1306
+ // src/consumers/tui/reducers/progress.ts
1307
+ init_esm_shims();
1308
+ var learningRecordedReducer = {
1309
+ tag: "LearningRecorded",
1310
+ reduce: (state, event) => {
1311
+ const category = event.category ? `[${event.category}] ` : "";
1312
+ const line = `Learning: ${category}${event.content}`;
1313
+ return appendOutput(state, `${line}
1314
+ `);
1315
+ }
1316
+ };
1317
+ var guardrailAddedReducer = {
1318
+ tag: "GuardrailAdded",
1319
+ reduce: (state, event) => {
1320
+ const severityIcon = event.severity === "critical" ? "[critical]" : "[warn]";
1321
+ const line = `${severityIcon} Guardrail: ${event.pattern}`;
1322
+ return appendOutput(state, `${line}
1323
+ `);
1324
+ }
1325
+ };
1326
+ var progressUpdatedReducer = {
1327
+ tag: "ProgressUpdated",
1328
+ reduce: (state) => state
1329
+ };
1330
+ stateReducerRegistry.register(learningRecordedReducer);
1331
+ stateReducerRegistry.register(guardrailAddedReducer);
1332
+ stateReducerRegistry.register(progressUpdatedReducer);
1333
+
1308
1334
  // src/consumers/tui/reducers/tasks.ts
1309
1335
  init_esm_shims();
1310
1336
  var tasksDefinedReducer = {
@@ -2307,23 +2333,13 @@ ${errorText}
2307
2333
 
2308
2334
  // src/layers/index.ts
2309
2335
  init_esm_shims();
2310
- import { Layer as Layer8 } from "effect";
2311
-
2312
- // src/layers/llm/claude-cli.ts
2313
- init_esm_shims();
2314
- import { spawn } from "child_process";
2315
- import { Effect as Effect5, Layer, Stream as Stream5 } from "effect";
2316
-
2317
- // src/services/llm.ts
2318
- init_esm_shims();
2319
- import { Context } from "effect";
2320
- var LLM = class extends Context.Tag("@ferix/LLM")() {
2321
- };
2336
+ import { Layer as Layer12 } from "effect";
2322
2337
 
2323
- // src/layers/llm/stream.ts
2338
+ // src/layers/guardrails/file-system.ts
2324
2339
  init_esm_shims();
2325
- import { createInterface } from "readline";
2326
- import { Effect as Effect4, Stream as Stream4 } from "effect";
2340
+ import { mkdir, readFile, writeFile } from "fs/promises";
2341
+ import { join } from "path";
2342
+ import { DateTime, Effect as Effect4, Layer } from "effect";
2327
2343
 
2328
2344
  // src/domain/errors.ts
2329
2345
  init_esm_shims();
@@ -2336,461 +2352,187 @@ var PlanStoreError = class extends Data.TaggedError("PlanStoreError") {
2336
2352
  };
2337
2353
  var SessionStoreError = class extends Data.TaggedError("SessionStoreError") {
2338
2354
  };
2355
+ var ProgressStoreError = class extends Data.TaggedError("ProgressStoreError") {
2356
+ };
2357
+ var GuardrailsStoreError = class extends Data.TaggedError(
2358
+ "GuardrailsStoreError"
2359
+ ) {
2360
+ };
2339
2361
  var OrchestratorError = class extends Data.TaggedError("OrchestratorError") {
2340
2362
  };
2341
2363
 
2342
- // src/layers/llm/parsers.ts
2364
+ // src/domain/index.ts
2343
2365
  init_esm_shims();
2344
- function parseJsonLine(line) {
2345
- if (!line.startsWith("{")) {
2346
- return null;
2347
- }
2348
- try {
2349
- return JSON.parse(line);
2350
- } catch {
2351
- return null;
2352
- }
2353
- }
2354
- function isTextContent(json) {
2355
- return typeof json === "object" && json !== null && "type" in json && typeof json.type === "string";
2356
- }
2357
- function isToolUse(json) {
2358
- return typeof json === "object" && json !== null && "type" in json && "content_block" in json;
2359
- }
2360
- function extractText(json) {
2361
- if (!isTextContent(json)) {
2362
- return null;
2363
- }
2364
- if (json.type === "content_block_delta") {
2365
- const delta = json;
2366
- if (delta.delta?.type === "text_delta" && delta.delta.text) {
2367
- return delta.delta.text;
2368
- }
2369
- }
2370
- if (json.type === "assistant" && json.message?.content) {
2371
- for (const block of json.message.content) {
2372
- if (block.type === "text" && block.text) {
2373
- return block.text;
2374
- }
2375
- }
2376
- }
2377
- return null;
2378
- }
2379
- function isToolInputDelta(json) {
2380
- return typeof json === "object" && json !== null && "type" in json && json.type === "content_block_delta" && "delta" in json;
2381
- }
2382
- function extractToolInfo(json) {
2383
- if (typeof json === "object" && json !== null && "type" in json && json.type === "content_block_stop") {
2384
- return {
2385
- type: "end",
2386
- name: "unknown"
2387
- };
2388
- }
2389
- if (!isToolUse(json)) {
2390
- if (isToolInputDelta(json) && json.delta?.type === "input_json_delta" && json.delta.partial_json) {
2391
- return {
2392
- type: "input_delta",
2393
- name: "",
2394
- partialJson: json.delta.partial_json
2395
- };
2396
- }
2397
- return null;
2398
- }
2399
- if (json.type === "content_block_start" && json.content_block?.type === "tool_use") {
2400
- return {
2401
- type: "start",
2402
- name: json.content_block.name || "unknown"
2403
- };
2404
- }
2405
- return null;
2406
- }
2407
- function safeParseJson(jsonStr) {
2408
- try {
2409
- return JSON.parse(jsonStr);
2410
- } catch {
2411
- return null;
2412
- }
2413
- }
2414
- function unwrapStreamEvent(json) {
2415
- if (typeof json === "object" && json !== null && "type" in json && json.type === "stream_event" && "event" in json) {
2416
- return json.event;
2417
- }
2418
- return json;
2419
- }
2420
2366
 
2421
- // src/layers/llm/stream.ts
2422
- function handleToolEvent(toolInfo, toolState, emit) {
2423
- if (toolInfo.type === "start") {
2424
- toolState.currentTool = toolInfo.name;
2425
- toolState.inputChunks.length = 0;
2426
- emit.single({ _tag: "ToolStart", tool: toolInfo.name });
2427
- return;
2428
- }
2429
- if (toolInfo.type === "input_delta" && toolInfo.partialJson) {
2430
- toolState.inputChunks.push(toolInfo.partialJson);
2431
- return;
2432
- }
2433
- if (toolInfo.type === "end" && toolState.currentTool) {
2434
- const inputJson = toolState.inputChunks.join("");
2435
- const input = safeParseJson(inputJson);
2436
- if (input !== null) {
2437
- emit.single({ _tag: "ToolUse", tool: toolState.currentTool, input });
2438
- }
2439
- emit.single({ _tag: "ToolEnd", tool: toolState.currentTool });
2440
- toolState.currentTool = "";
2441
- toolState.inputChunks.length = 0;
2442
- }
2443
- }
2444
- function processJsonLine(json, outputChunks, toolState, emit) {
2445
- const event = unwrapStreamEvent(json);
2446
- const text = extractText(event);
2447
- if (text) {
2448
- outputChunks.push(text);
2449
- emit.single({ _tag: "Text", text });
2450
- return;
2451
- }
2452
- const toolInfo = extractToolInfo(event);
2453
- if (toolInfo) {
2454
- handleToolEvent(toolInfo, toolState, emit);
2455
- }
2456
- }
2457
- function createEventStream(child) {
2458
- return Stream4.async((emit) => {
2459
- const outputChunks = [];
2460
- const toolState = { currentTool: "", inputChunks: [] };
2461
- const stdout = child.stdout;
2462
- if (!stdout) {
2463
- emit.fail(
2464
- new LLMError({ message: "Failed to get stdout from child process" })
2465
- );
2466
- return Effect4.void;
2467
- }
2468
- const rl = createInterface({
2469
- input: stdout,
2470
- crlfDelay: Number.POSITIVE_INFINITY
2471
- });
2472
- rl.on("line", (line) => {
2473
- const json = parseJsonLine(line);
2474
- if (json) {
2475
- processJsonLine(json, outputChunks, toolState, emit);
2476
- }
2477
- });
2478
- child.stderr?.on("data", (data) => {
2479
- const text = data.toString().trim();
2480
- if (text) {
2481
- emit.single({ _tag: "Text", text: `[stderr] ${text}` });
2482
- }
2483
- });
2484
- child.on("close", (exitCode) => {
2485
- if (exitCode !== 0) {
2486
- emit.fail(
2487
- new LLMError({
2488
- message: `Claude CLI exited with code ${exitCode}`
2489
- })
2490
- );
2491
- } else {
2492
- const fullOutput = outputChunks.join("");
2493
- emit.single({ _tag: "Done", output: fullOutput });
2494
- emit.end();
2495
- }
2496
- });
2497
- child.on("error", (error) => {
2498
- emit.fail(
2499
- new LLMError({
2500
- message: error.message,
2501
- cause: error
2502
- })
2503
- );
2504
- });
2505
- return Effect4.sync(() => {
2506
- child.kill("SIGTERM");
2507
- });
2508
- });
2509
- }
2367
+ // src/domain/schemas/index.ts
2368
+ init_esm_shims();
2510
2369
 
2511
- // src/layers/llm/claude-cli.ts
2512
- var make = {
2513
- execute: (prompt) => {
2514
- return Stream5.unwrap(
2515
- Effect5.sync(() => {
2516
- const child = spawn(
2517
- "claude",
2518
- [
2519
- "--permission-mode",
2520
- "acceptEdits",
2521
- "--output-format",
2522
- "stream-json",
2523
- "--verbose",
2524
- "--include-partial-messages",
2525
- "-p",
2526
- prompt
2527
- ],
2528
- {
2529
- stdio: ["inherit", "pipe", "pipe"],
2530
- env: {
2531
- ...process.env,
2532
- FORCE_COLOR: "1"
2533
- }
2534
- }
2535
- );
2536
- return createEventStream(child);
2537
- })
2538
- );
2539
- }
2540
- };
2541
- var Live = Layer.succeed(LLM, make);
2542
- var ClaudeCLI = {
2543
- Live
2544
- };
2370
+ // src/domain/schemas/config.ts
2371
+ init_esm_shims();
2372
+ import { Schema as S } from "effect";
2373
+ var PhasePromptOverridesSchema = S.Struct({
2374
+ breakdown: S.optional(S.String),
2375
+ planning: S.optional(S.String),
2376
+ execution: S.optional(S.String),
2377
+ check: S.optional(S.String),
2378
+ verify: S.optional(S.String),
2379
+ review: S.optional(S.String),
2380
+ completion: S.optional(S.String)
2381
+ });
2382
+ var PromptConfigSchema = S.Struct({
2383
+ systemPrompt: S.optional(S.String),
2384
+ phases: S.optional(PhasePromptOverridesSchema),
2385
+ additionalContext: S.optional(S.String)
2386
+ });
2387
+ var LoopConfigSchema = S.Struct({
2388
+ task: S.String,
2389
+ maxIterations: S.Number,
2390
+ verifyCommands: S.Array(S.String),
2391
+ sessionId: S.optional(S.String),
2392
+ branch: S.optional(S.String),
2393
+ push: S.optional(S.Boolean),
2394
+ pr: S.optional(S.Boolean),
2395
+ verbose: S.optional(S.Boolean),
2396
+ prompts: S.optional(PromptConfigSchema)
2397
+ });
2398
+ var LoopSummarySchema = S.Struct({
2399
+ iterations: S.Number,
2400
+ success: S.Boolean,
2401
+ sessionId: S.String,
2402
+ completedTasks: S.Array(S.String),
2403
+ durationMs: S.Number
2404
+ });
2405
+ var LoopErrorSchema = S.Struct({
2406
+ message: S.String,
2407
+ phase: S.String,
2408
+ iteration: S.optional(S.Number)
2409
+ });
2410
+ var decodeLoopConfig = S.decodeUnknown(LoopConfigSchema);
2545
2411
 
2546
- // src/layers/llm/mock.ts
2412
+ // src/domain/schemas/events.ts
2547
2413
  init_esm_shims();
2548
- import { Effect as Effect6, Layer as Layer2, Schema as S2, Stream as Stream6 } from "effect";
2414
+ import { Schema as S4 } from "effect";
2549
2415
 
2550
- // src/domain/schemas/llm.ts
2416
+ // src/domain/schemas/plan.ts
2551
2417
  init_esm_shims();
2552
- import { Schema as S } from "effect";
2553
- var TextEventSchema = S.TaggedStruct("Text", {
2554
- text: S.String
2418
+ import { Brand, Schema as S2 } from "effect";
2419
+ var PlanId = Brand.nominal();
2420
+ var TaskStatusSchema = S2.Literal(
2421
+ "pending",
2422
+ "planning",
2423
+ "in_progress",
2424
+ "done",
2425
+ "failed",
2426
+ "skipped"
2427
+ );
2428
+ var PhaseStatusSchema = S2.Literal(
2429
+ "pending",
2430
+ "in_progress",
2431
+ "done",
2432
+ "failed"
2433
+ );
2434
+ var CriterionStatusSchema = S2.Literal("pending", "passed", "failed");
2435
+ var PhaseSchema = S2.Struct({
2436
+ id: S2.String,
2437
+ description: S2.String,
2438
+ status: PhaseStatusSchema
2555
2439
  });
2556
- var ToolStartEventSchema = S.TaggedStruct("ToolStart", {
2557
- tool: S.String
2440
+ var CriterionSchema = S2.Struct({
2441
+ id: S2.String,
2442
+ description: S2.String,
2443
+ status: CriterionStatusSchema,
2444
+ failureReason: S2.optional(S2.String)
2558
2445
  });
2559
- var ToolUseEventSchema = S.TaggedStruct("ToolUse", {
2560
- tool: S.String,
2561
- input: S.Unknown
2446
+ var TaskSchema = S2.Struct({
2447
+ id: S2.String,
2448
+ title: S2.String,
2449
+ description: S2.String,
2450
+ status: TaskStatusSchema,
2451
+ phases: S2.Array(PhaseSchema),
2452
+ criteria: S2.Array(CriterionSchema),
2453
+ filesToModify: S2.Array(S2.String),
2454
+ attempts: S2.Number,
2455
+ completionNotes: S2.optional(S2.String)
2456
+ });
2457
+ var PlanDataSchema = S2.Struct({
2458
+ sessionId: S2.String,
2459
+ createdAt: S2.String,
2460
+ originalTask: S2.String,
2461
+ context: S2.optional(S2.String),
2462
+ tasks: S2.Array(TaskSchema)
2463
+ });
2464
+ var PlanSchema = S2.Struct({
2465
+ id: S2.String,
2466
+ sessionId: S2.String,
2467
+ createdAt: S2.String,
2468
+ originalTask: S2.String,
2469
+ context: S2.optional(S2.String),
2470
+ tasks: S2.Array(TaskSchema)
2471
+ });
2472
+ var decodePlan = S2.decodeUnknown(PlanSchema);
2473
+ var decodePlanData = S2.decodeUnknown(PlanDataSchema);
2474
+
2475
+ // src/domain/schemas/shared.ts
2476
+ init_esm_shims();
2477
+ import { Schema as S3 } from "effect";
2478
+ var TaskBasicInfoSchema = S3.Struct({
2479
+ id: S3.String,
2480
+ title: S3.String,
2481
+ description: S3.String
2562
2482
  });
2563
- var ToolEndEventSchema = S.TaggedStruct("ToolEnd", {
2564
- tool: S.String
2483
+ var PhaseBasicInfoSchema = S3.Struct({
2484
+ id: S3.String,
2485
+ description: S3.String
2565
2486
  });
2566
- var DoneEventSchema = S.TaggedStruct("Done", {
2567
- output: S.String
2487
+ var CriterionBasicInfoSchema = S3.Struct({
2488
+ id: S3.String,
2489
+ description: S3.String
2568
2490
  });
2569
- var LLMEventSchema = S.Union(
2570
- TextEventSchema,
2571
- ToolStartEventSchema,
2572
- ToolUseEventSchema,
2573
- ToolEndEventSchema,
2574
- DoneEventSchema
2575
- );
2576
- var decodeLLMEvent = S.decodeUnknown(LLMEventSchema);
2577
-
2578
- // src/layers/llm/mock.ts
2579
- var MockLLMConfigSchema = S2.Struct({
2580
- events: S2.Array(LLMEventSchema),
2581
- delayMs: S2.optional(S2.Number)
2582
- });
2583
- function createMockLLM(config) {
2584
- return {
2585
- execute: (_prompt) => {
2586
- const baseStream = Stream6.fromIterable(config.events);
2587
- if (config.delayMs !== void 0 && config.delayMs > 0) {
2588
- const delay = config.delayMs;
2589
- return baseStream.pipe(Stream6.tap(() => Effect6.sleep(delay)));
2590
- }
2591
- return baseStream;
2592
- }
2593
- };
2594
- }
2595
- var defaultMockEvents = [
2596
- { _tag: "Text", text: "Processing task...\n" },
2597
- { _tag: "ToolStart", tool: "Read" },
2598
- { _tag: "ToolEnd", tool: "Read" },
2599
- { _tag: "Text", text: "Task completed successfully.\n" },
2600
- {
2601
- _tag: "Done",
2602
- output: "Processing task...\nTask completed successfully.\n"
2603
- }
2604
- ];
2605
- var defaultMock = createMockLLM({ events: defaultMockEvents });
2606
- var Live2 = Layer2.succeed(LLM, defaultMock);
2607
- function layer(config) {
2608
- return Layer2.succeed(LLM, createMockLLM(config));
2609
- }
2610
- var Mock = {
2611
- Live: Live2,
2612
- layer,
2613
- createMockLLM
2614
- };
2615
-
2616
- // src/layers/plan/file-system.ts
2617
- init_esm_shims();
2618
- import { access, mkdir, readdir, readFile, writeFile } from "fs/promises";
2619
- import { join } from "path";
2620
- import { Effect as Effect7, Layer as Layer3 } from "effect";
2621
-
2622
- // src/domain/index.ts
2623
- init_esm_shims();
2624
-
2625
- // src/domain/schemas/index.ts
2626
- init_esm_shims();
2627
-
2628
- // src/domain/schemas/config.ts
2629
- init_esm_shims();
2630
- import { Schema as S3 } from "effect";
2631
- var PhasePromptOverridesSchema = S3.Struct({
2632
- breakdown: S3.optional(S3.String),
2633
- planning: S3.optional(S3.String),
2634
- execution: S3.optional(S3.String),
2635
- check: S3.optional(S3.String),
2636
- verify: S3.optional(S3.String),
2637
- review: S3.optional(S3.String),
2638
- completion: S3.optional(S3.String)
2639
- });
2640
- var PromptConfigSchema = S3.Struct({
2641
- systemPrompt: S3.optional(S3.String),
2642
- phases: S3.optional(PhasePromptOverridesSchema),
2643
- additionalContext: S3.optional(S3.String)
2644
- });
2645
- var LoopConfigSchema = S3.Struct({
2646
- task: S3.String,
2647
- maxIterations: S3.Number,
2648
- verifyCommands: S3.Array(S3.String),
2649
- sessionId: S3.optional(S3.String),
2650
- branch: S3.optional(S3.String),
2651
- push: S3.optional(S3.Boolean),
2652
- pr: S3.optional(S3.Boolean),
2653
- verbose: S3.optional(S3.Boolean),
2654
- prompts: S3.optional(PromptConfigSchema)
2655
- });
2656
- var LoopSummarySchema = S3.Struct({
2657
- iterations: S3.Number,
2658
- success: S3.Boolean,
2659
- sessionId: S3.String,
2660
- completedTasks: S3.Array(S3.String),
2661
- durationMs: S3.Number
2662
- });
2663
- var LoopErrorSchema = S3.Struct({
2664
- message: S3.String,
2665
- phase: S3.String,
2666
- iteration: S3.optional(S3.Number)
2667
- });
2668
- var decodeLoopConfig = S3.decodeUnknown(LoopConfigSchema);
2669
-
2670
- // src/domain/schemas/events.ts
2671
- init_esm_shims();
2672
- import { Schema as S6 } from "effect";
2673
-
2674
- // src/domain/schemas/plan.ts
2675
- init_esm_shims();
2676
- import { Brand, Schema as S4 } from "effect";
2677
- var PlanId = Brand.nominal();
2678
- var TaskStatusSchema = S4.Literal(
2679
- "pending",
2680
- "planning",
2681
- "in_progress",
2682
- "done",
2683
- "failed",
2684
- "skipped"
2685
- );
2686
- var PhaseStatusSchema = S4.Literal(
2687
- "pending",
2688
- "in_progress",
2689
- "done",
2690
- "failed"
2691
- );
2692
- var CriterionStatusSchema = S4.Literal("pending", "passed", "failed");
2693
- var PhaseSchema = S4.Struct({
2694
- id: S4.String,
2695
- description: S4.String,
2696
- status: PhaseStatusSchema
2491
+ var TasksDefinedDataSchema = S3.Struct({
2492
+ tasks: S3.Array(TaskBasicInfoSchema)
2697
2493
  });
2698
- var CriterionSchema = S4.Struct({
2699
- id: S4.String,
2700
- description: S4.String,
2701
- status: CriterionStatusSchema,
2702
- failureReason: S4.optional(S4.String)
2494
+ var PhasesDefinedDataSchema = S3.Struct({
2495
+ taskId: S3.String,
2496
+ phases: S3.Array(PhaseBasicInfoSchema)
2703
2497
  });
2704
- var TaskSchema = S4.Struct({
2705
- id: S4.String,
2706
- title: S4.String,
2707
- description: S4.String,
2708
- status: TaskStatusSchema,
2709
- phases: S4.Array(PhaseSchema),
2710
- criteria: S4.Array(CriterionSchema),
2711
- filesToModify: S4.Array(S4.String),
2712
- attempts: S4.Number,
2713
- completionNotes: S4.optional(S4.String)
2498
+ var CriteriaDefinedDataSchema = S3.Struct({
2499
+ taskId: S3.String,
2500
+ criteria: S3.Array(CriterionBasicInfoSchema)
2714
2501
  });
2715
- var PlanDataSchema = S4.Struct({
2716
- sessionId: S4.String,
2717
- createdAt: S4.String,
2718
- originalTask: S4.String,
2719
- context: S4.optional(S4.String),
2720
- tasks: S4.Array(TaskSchema)
2502
+ var PhaseIdDataSchema = S3.Struct({
2503
+ phaseId: S3.String
2721
2504
  });
2722
- var PlanSchema = S4.Struct({
2723
- id: S4.String,
2724
- sessionId: S4.String,
2725
- createdAt: S4.String,
2726
- originalTask: S4.String,
2727
- context: S4.optional(S4.String),
2728
- tasks: S4.Array(TaskSchema)
2505
+ var PhaseFailedDataSchema = S3.Struct({
2506
+ phaseId: S3.String,
2507
+ reason: S3.String
2729
2508
  });
2730
- var decodePlan = S4.decodeUnknown(PlanSchema);
2731
- var decodePlanData = S4.decodeUnknown(PlanDataSchema);
2732
-
2733
- // src/domain/schemas/shared.ts
2734
- init_esm_shims();
2735
- import { Schema as S5 } from "effect";
2736
- var TaskBasicInfoSchema = S5.Struct({
2737
- id: S5.String,
2738
- title: S5.String,
2739
- description: S5.String
2740
- });
2741
- var PhaseBasicInfoSchema = S5.Struct({
2742
- id: S5.String,
2743
- description: S5.String
2744
- });
2745
- var CriterionBasicInfoSchema = S5.Struct({
2746
- id: S5.String,
2747
- description: S5.String
2748
- });
2749
- var TasksDefinedDataSchema = S5.Struct({
2750
- tasks: S5.Array(TaskBasicInfoSchema)
2509
+ var CriterionIdDataSchema = S3.Struct({
2510
+ criterionId: S3.String
2751
2511
  });
2752
- var PhasesDefinedDataSchema = S5.Struct({
2753
- taskId: S5.String,
2754
- phases: S5.Array(PhaseBasicInfoSchema)
2512
+ var CriterionFailedDataSchema = S3.Struct({
2513
+ criterionId: S3.String,
2514
+ reason: S3.String
2755
2515
  });
2756
- var CriteriaDefinedDataSchema = S5.Struct({
2757
- taskId: S5.String,
2758
- criteria: S5.Array(CriterionBasicInfoSchema)
2516
+ var ReviewCompleteDataSchema = S3.Struct({
2517
+ changesMade: S3.Boolean
2759
2518
  });
2760
- var PhaseIdDataSchema = S5.Struct({
2761
- phaseId: S5.String
2519
+ var TaskCompleteSignalDataSchema = S3.Struct({
2520
+ taskId: S3.String,
2521
+ summary: S3.String,
2522
+ filesModified: S3.Array(S3.String),
2523
+ filesCreated: S3.Array(S3.String)
2762
2524
  });
2763
- var PhaseFailedDataSchema = S5.Struct({
2764
- phaseId: S5.String,
2765
- reason: S5.String
2766
- });
2767
- var CriterionIdDataSchema = S5.Struct({
2768
- criterionId: S5.String
2769
- });
2770
- var CriterionFailedDataSchema = S5.Struct({
2771
- criterionId: S5.String,
2772
- reason: S5.String
2773
- });
2774
- var ReviewCompleteDataSchema = S5.Struct({
2775
- changesMade: S5.Boolean
2776
- });
2777
- var TaskCompleteSignalDataSchema = S5.Struct({
2778
- taskId: S5.String,
2779
- summary: S5.String,
2780
- filesModified: S5.Array(S5.String),
2781
- filesCreated: S5.Array(S5.String)
2782
- });
2783
- var TaskCompleteDataSchema = S5.Struct({
2784
- taskId: S5.String,
2785
- summary: S5.String
2525
+ var TaskCompleteDataSchema = S3.Struct({
2526
+ taskId: S3.String,
2527
+ summary: S3.String
2786
2528
  });
2787
2529
 
2788
2530
  // src/domain/schemas/events.ts
2789
- var taggedEvent = (tag, fields) => S6.TaggedStruct(tag, fields);
2790
- var taggedFromData = (tag, dataSchema, extraFields = {}) => S6.TaggedStruct(tag, { ...dataSchema.fields, ...extraFields });
2531
+ var taggedEvent = (tag, fields) => S4.TaggedStruct(tag, fields);
2532
+ var taggedFromData = (tag, dataSchema, extraFields = {}) => S4.TaggedStruct(tag, { ...dataSchema.fields, ...extraFields });
2791
2533
  var LoopStartedEventSchema = taggedEvent("LoopStarted", {
2792
2534
  config: LoopConfigSchema,
2793
- timestamp: S6.Number
2535
+ timestamp: S4.Number
2794
2536
  });
2795
2537
  var LoopCompletedEventSchema = taggedEvent("LoopCompleted", {
2796
2538
  summary: LoopSummarySchema
@@ -2799,30 +2541,30 @@ var LoopFailedEventSchema = taggedEvent("LoopFailed", {
2799
2541
  error: LoopErrorSchema
2800
2542
  });
2801
2543
  var DiscoveryStartedEventSchema = taggedEvent("DiscoveryStarted", {
2802
- timestamp: S6.Number
2544
+ timestamp: S4.Number
2803
2545
  });
2804
2546
  var DiscoveryCompletedEventSchema = taggedEvent("DiscoveryCompleted", {
2805
- taskCount: S6.Number,
2806
- timestamp: S6.Number
2547
+ taskCount: S4.Number,
2548
+ timestamp: S4.Number
2807
2549
  });
2808
2550
  var IterationStartedEventSchema = taggedEvent("IterationStarted", {
2809
- iteration: S6.Number
2551
+ iteration: S4.Number
2810
2552
  });
2811
2553
  var IterationCompletedEventSchema = taggedEvent("IterationCompleted", {
2812
- iteration: S6.Number
2554
+ iteration: S4.Number
2813
2555
  });
2814
2556
  var LLMTextEventSchema = taggedEvent("LLMText", {
2815
- text: S6.String
2557
+ text: S4.String
2816
2558
  });
2817
2559
  var LLMToolStartEventSchema = taggedEvent("LLMToolStart", {
2818
- tool: S6.String
2560
+ tool: S4.String
2819
2561
  });
2820
2562
  var LLMToolUseEventSchema = taggedEvent("LLMToolUse", {
2821
- tool: S6.String,
2822
- input: S6.Unknown
2563
+ tool: S4.String,
2564
+ input: S4.Unknown
2823
2565
  });
2824
2566
  var LLMToolEndEventSchema = taggedEvent("LLMToolEnd", {
2825
- tool: S6.String
2567
+ tool: S4.String
2826
2568
  });
2827
2569
  var TasksDefinedEventSchema = taggedFromData(
2828
2570
  "TasksDefined",
@@ -2839,17 +2581,17 @@ var CriteriaDefinedEventSchema = taggedFromData(
2839
2581
  var PhaseStartedEventSchema = taggedFromData(
2840
2582
  "PhaseStarted",
2841
2583
  PhaseIdDataSchema,
2842
- { timestamp: S6.Number }
2584
+ { timestamp: S4.Number }
2843
2585
  );
2844
2586
  var PhaseCompletedEventSchema = taggedFromData(
2845
2587
  "PhaseCompleted",
2846
2588
  PhaseIdDataSchema,
2847
- { timestamp: S6.Number }
2589
+ { timestamp: S4.Number }
2848
2590
  );
2849
2591
  var PhaseFailedEventSchema = taggedFromData(
2850
2592
  "PhaseFailed",
2851
2593
  PhaseFailedDataSchema,
2852
- { timestamp: S6.Number }
2594
+ { timestamp: S4.Number }
2853
2595
  );
2854
2596
  var CriterionPassedEventSchema = taggedFromData(
2855
2597
  "CriterionPassed",
@@ -2859,9 +2601,9 @@ var CriterionFailedEventSchema = taggedFromData(
2859
2601
  "CriterionFailed",
2860
2602
  CriterionFailedDataSchema
2861
2603
  );
2862
- var CheckPassedEventSchema = S6.TaggedStruct("CheckPassed", {});
2604
+ var CheckPassedEventSchema = S4.TaggedStruct("CheckPassed", {});
2863
2605
  var CheckFailedEventSchema = taggedEvent("CheckFailed", {
2864
- failedCriteria: S6.Array(S6.String)
2606
+ failedCriteria: S4.Array(S4.String)
2865
2607
  });
2866
2608
  var ReviewCompleteEventSchema = taggedFromData(
2867
2609
  "ReviewComplete",
@@ -2870,7 +2612,7 @@ var ReviewCompleteEventSchema = taggedFromData(
2870
2612
  var TaskCompletedEventSchema = taggedFromData(
2871
2613
  "TaskCompleted",
2872
2614
  TaskCompleteDataSchema,
2873
- { timestamp: S6.Number }
2615
+ { timestamp: S4.Number }
2874
2616
  );
2875
2617
  var PlanCreatedEventSchema = taggedEvent("PlanCreated", {
2876
2618
  plan: PlanSchema
@@ -2879,11 +2621,33 @@ var PlanUpdatedEventSchema = taggedEvent("PlanUpdated", {
2879
2621
  plan: PlanSchema
2880
2622
  });
2881
2623
  var PlanUpdateFailedEventSchema = taggedEvent("PlanUpdateFailed", {
2882
- operation: S6.Literal("create", "update"),
2883
- error: S6.String,
2884
- planId: S6.optional(S6.String)
2624
+ operation: S4.Literal("create", "update"),
2625
+ error: S4.String,
2626
+ planId: S4.optional(S4.String)
2627
+ });
2628
+ var LearningRecordedEventSchema = taggedEvent("LearningRecorded", {
2629
+ iteration: S4.Number,
2630
+ content: S4.String,
2631
+ category: S4.optional(S4.Literal("success", "failure", "optimization")),
2632
+ timestamp: S4.Number
2885
2633
  });
2886
- var DomainEventSchema = S6.Union(
2634
+ var GuardrailAddedEventSchema = taggedEvent("GuardrailAdded", {
2635
+ id: S4.String,
2636
+ iteration: S4.Number,
2637
+ pattern: S4.String,
2638
+ sign: S4.String,
2639
+ avoidance: S4.String,
2640
+ severity: S4.Literal("warning", "critical"),
2641
+ timestamp: S4.Number
2642
+ });
2643
+ var ProgressUpdatedEventSchema = taggedEvent("ProgressUpdated", {
2644
+ sessionId: S4.String,
2645
+ iteration: S4.Number,
2646
+ taskId: S4.String,
2647
+ action: S4.Literal("started", "completed", "failed", "learning"),
2648
+ timestamp: S4.Number
2649
+ });
2650
+ var DomainEventSchema = S4.Union(
2887
2651
  LoopStartedEventSchema,
2888
2652
  LoopCompletedEventSchema,
2889
2653
  LoopFailedEventSchema,
@@ -2909,7 +2673,10 @@ var DomainEventSchema = S6.Union(
2909
2673
  TaskCompletedEventSchema,
2910
2674
  PlanCreatedEventSchema,
2911
2675
  PlanUpdatedEventSchema,
2912
- PlanUpdateFailedEventSchema
2676
+ PlanUpdateFailedEventSchema,
2677
+ LearningRecordedEventSchema,
2678
+ GuardrailAddedEventSchema,
2679
+ ProgressUpdatedEventSchema
2913
2680
  );
2914
2681
  var DomainEventUtils = {
2915
2682
  isLLMEvent: (e) => e._tag.startsWith("LLM"),
@@ -2919,6 +2686,55 @@ var DomainEventUtils = {
2919
2686
  isDiscoveryEvent: (e) => e._tag.startsWith("Discovery")
2920
2687
  };
2921
2688
 
2689
+ // src/domain/schemas/guardrails.ts
2690
+ init_esm_shims();
2691
+ import { Schema as S5 } from "effect";
2692
+ var GuardrailSeveritySchema = S5.Literal("warning", "critical");
2693
+ var GuardrailSchema = S5.Struct({
2694
+ id: S5.String,
2695
+ createdAt: S5.String,
2696
+ iteration: S5.Number,
2697
+ pattern: S5.String,
2698
+ sign: S5.String,
2699
+ avoidance: S5.String,
2700
+ severity: GuardrailSeveritySchema
2701
+ });
2702
+ var GuardrailsFileSchema = S5.Struct({
2703
+ sessionId: S5.String,
2704
+ createdAt: S5.String,
2705
+ guardrails: S5.Array(GuardrailSchema)
2706
+ });
2707
+ var decodeGuardrail = S5.decodeUnknown(GuardrailSchema);
2708
+ var decodeGuardrailsFile = S5.decodeUnknown(GuardrailsFileSchema);
2709
+
2710
+ // src/domain/schemas/llm.ts
2711
+ init_esm_shims();
2712
+ import { Schema as S6 } from "effect";
2713
+ var TextEventSchema = S6.TaggedStruct("Text", {
2714
+ text: S6.String
2715
+ });
2716
+ var ToolStartEventSchema = S6.TaggedStruct("ToolStart", {
2717
+ tool: S6.String
2718
+ });
2719
+ var ToolUseEventSchema = S6.TaggedStruct("ToolUse", {
2720
+ tool: S6.String,
2721
+ input: S6.Unknown
2722
+ });
2723
+ var ToolEndEventSchema = S6.TaggedStruct("ToolEnd", {
2724
+ tool: S6.String
2725
+ });
2726
+ var DoneEventSchema = S6.TaggedStruct("Done", {
2727
+ output: S6.String
2728
+ });
2729
+ var LLMEventSchema = S6.Union(
2730
+ TextEventSchema,
2731
+ ToolStartEventSchema,
2732
+ ToolUseEventSchema,
2733
+ ToolEndEventSchema,
2734
+ DoneEventSchema
2735
+ );
2736
+ var decodeLLMEvent = S6.decodeUnknown(LLMEventSchema);
2737
+
2922
2738
  // src/domain/schemas/logger.ts
2923
2739
  init_esm_shims();
2924
2740
  import { Schema as S7 } from "effect";
@@ -2947,29 +2763,55 @@ var RunOptionsDataSchema = S8.Struct({
2947
2763
  consumer: S8.optional(ConsumerTypeSchema)
2948
2764
  });
2949
2765
 
2950
- // src/domain/schemas/session.ts
2766
+ // src/domain/schemas/progress.ts
2951
2767
  init_esm_shims();
2952
2768
  import { Schema as S9 } from "effect";
2953
- var SessionStatusSchema = S9.Literal(
2769
+ var ProgressActionSchema = S9.Literal(
2770
+ "started",
2771
+ "completed",
2772
+ "failed",
2773
+ "learning"
2774
+ );
2775
+ var ProgressEntrySchema = S9.Struct({
2776
+ iteration: S9.Number,
2777
+ timestamp: S9.String,
2778
+ taskId: S9.String,
2779
+ action: ProgressActionSchema,
2780
+ summary: S9.String,
2781
+ learnings: S9.optional(S9.Array(S9.String)),
2782
+ filesModified: S9.optional(S9.Array(S9.String))
2783
+ });
2784
+ var ProgressFileSchema = S9.Struct({
2785
+ sessionId: S9.String,
2786
+ createdAt: S9.String,
2787
+ entries: S9.Array(ProgressEntrySchema)
2788
+ });
2789
+ var decodeProgressEntry = S9.decodeUnknown(ProgressEntrySchema);
2790
+ var decodeProgressFile = S9.decodeUnknown(ProgressFileSchema);
2791
+
2792
+ // src/domain/schemas/session.ts
2793
+ init_esm_shims();
2794
+ import { Schema as S10 } from "effect";
2795
+ var SessionStatusSchema = S10.Literal(
2954
2796
  "active",
2955
2797
  "completed",
2956
2798
  "failed",
2957
2799
  "paused"
2958
2800
  );
2959
- var SessionSchema = S9.Struct({
2960
- id: S9.String,
2961
- createdAt: S9.String,
2801
+ var SessionSchema = S10.Struct({
2802
+ id: S10.String,
2803
+ createdAt: S10.String,
2962
2804
  status: SessionStatusSchema,
2963
- originalTask: S9.String,
2964
- completedTasks: S9.Array(S9.String),
2965
- currentTaskId: S9.optional(S9.String)
2805
+ originalTask: S10.String,
2806
+ completedTasks: S10.Array(S10.String),
2807
+ currentTaskId: S10.optional(S10.String)
2966
2808
  });
2967
- var decodeSession = S9.decodeUnknown(SessionSchema);
2809
+ var decodeSession = S10.decodeUnknown(SessionSchema);
2968
2810
 
2969
2811
  // src/domain/schemas/signals.ts
2970
2812
  init_esm_shims();
2971
- import { Schema as S10 } from "effect";
2972
- var taggedFromData2 = (tag, dataSchema) => S10.TaggedStruct(tag, dataSchema.fields);
2813
+ import { Schema as S11 } from "effect";
2814
+ var taggedFromData2 = (tag, dataSchema) => S11.TaggedStruct(tag, dataSchema.fields);
2973
2815
  var TasksDefinedSignalSchema = taggedFromData2(
2974
2816
  "TasksDefined",
2975
2817
  TasksDefinedDataSchema
@@ -3002,8 +2844,8 @@ var CriterionFailedSignalSchema = taggedFromData2(
3002
2844
  "CriterionFailed",
3003
2845
  CriterionFailedDataSchema
3004
2846
  );
3005
- var CheckPassedSignalSchema = S10.TaggedStruct("CheckPassed", {});
3006
- var CheckFailedSignalSchema = S10.TaggedStruct("CheckFailed", {});
2847
+ var CheckPassedSignalSchema = S11.TaggedStruct("CheckPassed", {});
2848
+ var CheckFailedSignalSchema = S11.TaggedStruct("CheckFailed", {});
3007
2849
  var ReviewCompleteSignalSchema = taggedFromData2(
3008
2850
  "ReviewComplete",
3009
2851
  ReviewCompleteDataSchema
@@ -3012,8 +2854,23 @@ var TaskCompleteSignalSchema = taggedFromData2(
3012
2854
  "TaskComplete",
3013
2855
  TaskCompleteSignalDataSchema
3014
2856
  );
3015
- var LoopCompleteSignalSchema = S10.TaggedStruct("LoopComplete", {});
3016
- var SignalSchema = S10.Union(
2857
+ var LoopCompleteSignalSchema = S11.TaggedStruct("LoopComplete", {});
2858
+ var LearningCategorySchema = S11.Literal(
2859
+ "success",
2860
+ "failure",
2861
+ "optimization"
2862
+ );
2863
+ var LearningSignalSchema = S11.TaggedStruct("Learning", {
2864
+ content: S11.String,
2865
+ category: S11.optional(LearningCategorySchema)
2866
+ });
2867
+ var GuardrailSignalSchema = S11.TaggedStruct("Guardrail", {
2868
+ pattern: S11.String,
2869
+ sign: S11.String,
2870
+ avoidance: S11.String,
2871
+ severity: S11.Literal("warning", "critical")
2872
+ });
2873
+ var SignalSchema = S11.Union(
3017
2874
  TasksDefinedSignalSchema,
3018
2875
  PhasesDefinedSignalSchema,
3019
2876
  CriteriaDefinedSignalSchema,
@@ -3026,26 +2883,28 @@ var SignalSchema = S10.Union(
3026
2883
  CheckFailedSignalSchema,
3027
2884
  ReviewCompleteSignalSchema,
3028
2885
  TaskCompleteSignalSchema,
3029
- LoopCompleteSignalSchema
2886
+ LoopCompleteSignalSchema,
2887
+ LearningSignalSchema,
2888
+ GuardrailSignalSchema
3030
2889
  );
3031
- var decodeSignal = S10.decodeUnknown(SignalSchema);
3032
- var decodeSignalSync = S10.decodeUnknownSync(SignalSchema);
2890
+ var decodeSignal = S11.decodeUnknown(SignalSchema);
2891
+ var decodeSignalSync = S11.decodeUnknownSync(SignalSchema);
3033
2892
 
3034
2893
  // src/domain/schemas/task-generation.ts
3035
2894
  init_esm_shims();
3036
- import { Schema as S11 } from "effect";
3037
- var GeneratedTaskStatusSchema = S11.Literal(
2895
+ import { Schema as S12 } from "effect";
2896
+ var GeneratedTaskStatusSchema = S12.Literal(
3038
2897
  "pending",
3039
2898
  "in_progress",
3040
2899
  "done",
3041
2900
  "failed"
3042
2901
  );
3043
- var GeneratedTaskSchema = S11.Struct({
3044
- id: S11.String,
3045
- title: S11.String,
2902
+ var GeneratedTaskSchema = S12.Struct({
2903
+ id: S12.String,
2904
+ title: S12.String,
3046
2905
  status: GeneratedTaskStatusSchema
3047
2906
  });
3048
- var GeneratedTaskListSchema = S11.Array(GeneratedTaskSchema);
2907
+ var GeneratedTaskListSchema = S12.Array(GeneratedTaskSchema);
3049
2908
  var STATUS_ICONS = {
3050
2909
  done: "[x]",
3051
2910
  in_progress: "[~]",
@@ -3104,15 +2963,15 @@ function parseTasksMd(content) {
3104
2963
 
3105
2964
  // src/domain/schemas/tui.ts
3106
2965
  init_esm_shims();
3107
- import { Schema as S12 } from "effect";
3108
- var ViewModeSchema = S12.Literal("logs", "tasks", "detail");
3109
- var LoopStatusSchema = S12.Literal(
2966
+ import { Schema as S13 } from "effect";
2967
+ var ViewModeSchema = S13.Literal("logs", "tasks", "detail");
2968
+ var LoopStatusSchema = S13.Literal(
3110
2969
  "idle",
3111
2970
  "running",
3112
2971
  "complete",
3113
2972
  "error"
3114
2973
  );
3115
- var ExecutionModeSchema = S12.Literal(
2974
+ var ExecutionModeSchema = S13.Literal(
3116
2975
  "idle",
3117
2976
  "discovery",
3118
2977
  "breakdown",
@@ -3122,98 +2981,565 @@ var ExecutionModeSchema = S12.Literal(
3122
2981
  "verifying",
3123
2982
  "reviewing"
3124
2983
  );
3125
- var TUIPhaseStatusSchema = S12.Literal(
2984
+ var TUIPhaseStatusSchema = S13.Literal(
3126
2985
  "pending",
3127
2986
  "in_progress",
3128
2987
  "done",
3129
2988
  "failed"
3130
2989
  );
3131
- var TUICriterionStatusSchema = S12.Literal(
2990
+ var TUICriterionStatusSchema = S13.Literal(
3132
2991
  "pending",
3133
2992
  "passed",
3134
2993
  "failed"
3135
2994
  );
3136
- var TUITaskStatusSchema = S12.Literal(
2995
+ var TUITaskStatusSchema = S13.Literal(
3137
2996
  "pending",
3138
2997
  "in_progress",
3139
2998
  "done",
3140
2999
  "failed"
3141
3000
  );
3142
- var TUIPhaseSchema = S12.Struct({
3143
- id: S12.String,
3144
- description: S12.String,
3001
+ var TUIPhaseSchema = S13.Struct({
3002
+ id: S13.String,
3003
+ description: S13.String,
3145
3004
  status: TUIPhaseStatusSchema,
3146
- startedAt: S12.optional(S12.Number),
3147
- completedAt: S12.optional(S12.Number)
3005
+ startedAt: S13.optional(S13.Number),
3006
+ completedAt: S13.optional(S13.Number)
3148
3007
  });
3149
- var TUICriterionSchema = S12.Struct({
3150
- id: S12.String,
3151
- description: S12.String,
3008
+ var TUICriterionSchema = S13.Struct({
3009
+ id: S13.String,
3010
+ description: S13.String,
3152
3011
  status: TUICriterionStatusSchema,
3153
- failureReason: S12.optional(S12.String)
3012
+ failureReason: S13.optional(S13.String)
3154
3013
  });
3155
- var TUITaskSchema = S12.Struct({
3156
- id: S12.String,
3157
- title: S12.String,
3014
+ var TUITaskSchema = S13.Struct({
3015
+ id: S13.String,
3016
+ title: S13.String,
3158
3017
  status: TUITaskStatusSchema,
3159
- phases: S12.Array(TUIPhaseSchema),
3160
- criteria: S12.Array(TUICriterionSchema),
3161
- startedAt: S12.optional(S12.Number),
3162
- completedAt: S12.optional(S12.Number)
3018
+ phases: S13.Array(TUIPhaseSchema),
3019
+ criteria: S13.Array(TUICriterionSchema),
3020
+ startedAt: S13.optional(S13.Number),
3021
+ completedAt: S13.optional(S13.Number)
3163
3022
  });
3164
- var TUIStateSchema = S12.Struct({
3023
+ var TUIStateSchema = S13.Struct({
3165
3024
  // Loop info
3166
- task: S12.String,
3167
- iteration: S12.Number,
3168
- maxIterations: S12.Number,
3025
+ task: S13.String,
3026
+ iteration: S13.Number,
3027
+ maxIterations: S13.Number,
3169
3028
  status: LoopStatusSchema,
3170
- startTime: S12.Number,
3029
+ startTime: S13.Number,
3171
3030
  // Discovery phase
3172
- discoveryInProgress: S12.Boolean,
3173
- discoveryCompleted: S12.Boolean,
3031
+ discoveryInProgress: S13.Boolean,
3032
+ discoveryCompleted: S13.Boolean,
3174
3033
  // Current activity
3175
3034
  executionMode: ExecutionModeSchema,
3176
- currentTool: S12.optional(S12.String),
3177
- currentTaskId: S12.optional(S12.String),
3035
+ currentTool: S13.optional(S13.String),
3036
+ currentTaskId: S13.optional(S13.String),
3178
3037
  // Output
3179
- outputLines: S12.Array(S12.String),
3180
- partialLine: S12.String,
3038
+ outputLines: S13.Array(S13.String),
3039
+ partialLine: S13.String,
3181
3040
  // Tasks
3182
- tasks: S12.Array(TUITaskSchema),
3041
+ tasks: S13.Array(TUITaskSchema),
3183
3042
  // Navigation
3184
3043
  viewMode: ViewModeSchema,
3185
- selectedTaskIndex: S12.Number,
3186
- scrollOffset: S12.Number,
3187
- userScrolled: S12.Boolean,
3044
+ selectedTaskIndex: S13.Number,
3045
+ scrollOffset: S13.Number,
3046
+ userScrolled: S13.Boolean,
3188
3047
  // Git
3189
- gitBranch: S12.optional(S12.String),
3190
- gitPushed: S12.Boolean,
3191
- prUrl: S12.optional(S12.String)
3048
+ gitBranch: S13.optional(S13.String),
3049
+ gitPushed: S13.Boolean,
3050
+ prUrl: S13.optional(S13.String)
3051
+ });
3052
+
3053
+ // src/services/guardrails-store.ts
3054
+ init_esm_shims();
3055
+ import { Context } from "effect";
3056
+ var GuardrailsStore = class extends Context.Tag("@ferix/GuardrailsStore")() {
3057
+ };
3058
+
3059
+ // src/layers/guardrails/file-system.ts
3060
+ var PLANS_DIR = ".ferix/plans";
3061
+ function ensureDir(dirPath) {
3062
+ return Effect4.tryPromise({
3063
+ try: () => mkdir(dirPath, { recursive: true }),
3064
+ catch: (error) => new GuardrailsStoreError({
3065
+ message: `Failed to create directory: ${dirPath}`,
3066
+ operation: "add",
3067
+ cause: error
3068
+ })
3069
+ }).pipe(Effect4.asVoid);
3070
+ }
3071
+ function getSessionDir(sessionId) {
3072
+ return join(process.cwd(), PLANS_DIR, sessionId);
3073
+ }
3074
+ function getGuardrailsPath(sessionId) {
3075
+ return join(getSessionDir(sessionId), "guardrails.json");
3076
+ }
3077
+ function serializeGuardrails(guardrails) {
3078
+ return JSON.stringify(guardrails, null, 2);
3079
+ }
3080
+ function deserializeGuardrails(json) {
3081
+ return Effect4.gen(function* () {
3082
+ const parsed = yield* Effect4.try({
3083
+ try: () => JSON.parse(json),
3084
+ catch: (error) => new GuardrailsStoreError({
3085
+ message: `Invalid JSON in guardrails file: ${String(error)}`,
3086
+ operation: "load",
3087
+ cause: error
3088
+ })
3089
+ });
3090
+ const validated = yield* decodeGuardrailsFile(parsed).pipe(
3091
+ Effect4.mapError(
3092
+ (error) => new GuardrailsStoreError({
3093
+ message: `Guardrails validation failed: ${String(error)}`,
3094
+ operation: "load",
3095
+ cause: error
3096
+ })
3097
+ )
3098
+ );
3099
+ return validated;
3100
+ });
3101
+ }
3102
+ function createEmptyGuardrails(sessionId, createdAt) {
3103
+ return {
3104
+ sessionId,
3105
+ createdAt,
3106
+ guardrails: []
3107
+ };
3108
+ }
3109
+ var make = {
3110
+ add: (sessionId, guardrail) => Effect4.gen(function* () {
3111
+ const sessionDir = getSessionDir(sessionId);
3112
+ yield* ensureDir(sessionDir);
3113
+ const guardrailsPath = getGuardrailsPath(sessionId);
3114
+ const existing = yield* Effect4.tryPromise({
3115
+ try: async () => {
3116
+ try {
3117
+ const content = await readFile(guardrailsPath, "utf-8");
3118
+ return content;
3119
+ } catch {
3120
+ return null;
3121
+ }
3122
+ },
3123
+ catch: (error) => new GuardrailsStoreError({
3124
+ message: `Failed to read guardrails file: ${guardrailsPath}`,
3125
+ operation: "add",
3126
+ cause: error
3127
+ })
3128
+ });
3129
+ let guardrails;
3130
+ if (existing) {
3131
+ guardrails = yield* deserializeGuardrails(existing).pipe(
3132
+ Effect4.mapError(
3133
+ (err) => new GuardrailsStoreError({
3134
+ message: err.message,
3135
+ operation: "add",
3136
+ cause: err
3137
+ })
3138
+ )
3139
+ );
3140
+ } else {
3141
+ const now = yield* DateTime.now;
3142
+ guardrails = createEmptyGuardrails(sessionId, DateTime.formatIso(now));
3143
+ }
3144
+ const updatedGuardrails = {
3145
+ ...guardrails,
3146
+ guardrails: [...guardrails.guardrails, guardrail]
3147
+ };
3148
+ yield* Effect4.tryPromise({
3149
+ try: () => writeFile(
3150
+ guardrailsPath,
3151
+ serializeGuardrails(updatedGuardrails),
3152
+ "utf-8"
3153
+ ),
3154
+ catch: (error) => new GuardrailsStoreError({
3155
+ message: `Failed to write guardrails file: ${guardrailsPath}`,
3156
+ operation: "add",
3157
+ cause: error
3158
+ })
3159
+ });
3160
+ }),
3161
+ load: (sessionId) => Effect4.gen(function* () {
3162
+ const guardrailsPath = getGuardrailsPath(sessionId);
3163
+ const content = yield* Effect4.tryPromise({
3164
+ try: async () => {
3165
+ try {
3166
+ return await readFile(guardrailsPath, "utf-8");
3167
+ } catch {
3168
+ return null;
3169
+ }
3170
+ },
3171
+ catch: (error) => new GuardrailsStoreError({
3172
+ message: `Failed to read guardrails file: ${guardrailsPath}`,
3173
+ operation: "load",
3174
+ cause: error
3175
+ })
3176
+ });
3177
+ if (content === null) {
3178
+ const now = yield* DateTime.now;
3179
+ return createEmptyGuardrails(sessionId, DateTime.formatIso(now));
3180
+ }
3181
+ return yield* deserializeGuardrails(content);
3182
+ }),
3183
+ getActive: (sessionId) => Effect4.gen(function* () {
3184
+ const guardrails = yield* make.load(sessionId);
3185
+ return guardrails.guardrails;
3186
+ })
3187
+ };
3188
+ var Live = Layer.succeed(GuardrailsStore, make);
3189
+ var FileSystemGuardrails = {
3190
+ Live
3191
+ };
3192
+
3193
+ // src/layers/guardrails/memory.ts
3194
+ init_esm_shims();
3195
+ import { DateTime as DateTime2, Effect as Effect5, Layer as Layer2, Ref as Ref3 } from "effect";
3196
+ function createMemoryGuardrailsStore(stateRef) {
3197
+ return {
3198
+ add: (sessionId, guardrail) => Effect5.gen(function* () {
3199
+ const state = yield* Ref3.get(stateRef);
3200
+ let guardrails = state.get(sessionId);
3201
+ if (!guardrails) {
3202
+ const now = yield* DateTime2.now;
3203
+ guardrails = {
3204
+ sessionId,
3205
+ createdAt: DateTime2.formatIso(now),
3206
+ guardrails: []
3207
+ };
3208
+ }
3209
+ const updatedGuardrails = {
3210
+ ...guardrails,
3211
+ guardrails: [...guardrails.guardrails, guardrail]
3212
+ };
3213
+ state.set(sessionId, updatedGuardrails);
3214
+ yield* Ref3.set(stateRef, state);
3215
+ }),
3216
+ load: (sessionId) => Effect5.gen(function* () {
3217
+ const state = yield* Ref3.get(stateRef);
3218
+ const guardrails = state.get(sessionId);
3219
+ if (!guardrails) {
3220
+ const now = yield* DateTime2.now;
3221
+ return {
3222
+ sessionId,
3223
+ createdAt: DateTime2.formatIso(now),
3224
+ guardrails: []
3225
+ };
3226
+ }
3227
+ return guardrails;
3228
+ }),
3229
+ getActive: (sessionId) => Effect5.gen(function* () {
3230
+ const state = yield* Ref3.get(stateRef);
3231
+ const guardrails = state.get(sessionId);
3232
+ if (!guardrails) {
3233
+ return [];
3234
+ }
3235
+ return guardrails.guardrails;
3236
+ })
3237
+ };
3238
+ }
3239
+ function layer() {
3240
+ return Layer2.effect(
3241
+ GuardrailsStore,
3242
+ Effect5.gen(function* () {
3243
+ const stateRef = yield* Ref3.make(/* @__PURE__ */ new Map());
3244
+ return createMemoryGuardrailsStore(stateRef);
3245
+ })
3246
+ );
3247
+ }
3248
+ var Live2 = layer();
3249
+ var MemoryGuardrails = {
3250
+ Live: Live2,
3251
+ layer
3252
+ };
3253
+
3254
+ // src/layers/llm/claude-cli.ts
3255
+ init_esm_shims();
3256
+ import { spawn } from "child_process";
3257
+ import { Effect as Effect7, Layer as Layer3, Stream as Stream5 } from "effect";
3258
+
3259
+ // src/services/llm.ts
3260
+ init_esm_shims();
3261
+ import { Context as Context2 } from "effect";
3262
+ var LLM = class extends Context2.Tag("@ferix/LLM")() {
3263
+ };
3264
+
3265
+ // src/layers/llm/stream.ts
3266
+ init_esm_shims();
3267
+ import { createInterface } from "readline";
3268
+ import { Effect as Effect6, Stream as Stream4 } from "effect";
3269
+
3270
+ // src/layers/llm/parsers.ts
3271
+ init_esm_shims();
3272
+ function parseJsonLine(line) {
3273
+ if (!line.startsWith("{")) {
3274
+ return null;
3275
+ }
3276
+ try {
3277
+ return JSON.parse(line);
3278
+ } catch {
3279
+ return null;
3280
+ }
3281
+ }
3282
+ function isTextContent(json) {
3283
+ return typeof json === "object" && json !== null && "type" in json && typeof json.type === "string";
3284
+ }
3285
+ function isToolUse(json) {
3286
+ return typeof json === "object" && json !== null && "type" in json && "content_block" in json;
3287
+ }
3288
+ function extractText(json) {
3289
+ if (!isTextContent(json)) {
3290
+ return null;
3291
+ }
3292
+ if (json.type === "content_block_delta") {
3293
+ const delta = json;
3294
+ if (delta.delta?.type === "text_delta" && delta.delta.text) {
3295
+ return delta.delta.text;
3296
+ }
3297
+ }
3298
+ if (json.type === "assistant" && json.message?.content) {
3299
+ for (const block of json.message.content) {
3300
+ if (block.type === "text" && block.text) {
3301
+ return block.text;
3302
+ }
3303
+ }
3304
+ }
3305
+ return null;
3306
+ }
3307
+ function isToolInputDelta(json) {
3308
+ return typeof json === "object" && json !== null && "type" in json && json.type === "content_block_delta" && "delta" in json;
3309
+ }
3310
+ function extractToolInfo(json) {
3311
+ if (typeof json === "object" && json !== null && "type" in json && json.type === "content_block_stop") {
3312
+ return {
3313
+ type: "end",
3314
+ name: "unknown"
3315
+ };
3316
+ }
3317
+ if (!isToolUse(json)) {
3318
+ if (isToolInputDelta(json) && json.delta?.type === "input_json_delta" && json.delta.partial_json) {
3319
+ return {
3320
+ type: "input_delta",
3321
+ name: "",
3322
+ partialJson: json.delta.partial_json
3323
+ };
3324
+ }
3325
+ return null;
3326
+ }
3327
+ if (json.type === "content_block_start" && json.content_block?.type === "tool_use") {
3328
+ return {
3329
+ type: "start",
3330
+ name: json.content_block.name || "unknown"
3331
+ };
3332
+ }
3333
+ return null;
3334
+ }
3335
+ function safeParseJson(jsonStr) {
3336
+ try {
3337
+ return JSON.parse(jsonStr);
3338
+ } catch {
3339
+ return null;
3340
+ }
3341
+ }
3342
+ function unwrapStreamEvent(json) {
3343
+ if (typeof json === "object" && json !== null && "type" in json && json.type === "stream_event" && "event" in json) {
3344
+ return json.event;
3345
+ }
3346
+ return json;
3347
+ }
3348
+
3349
+ // src/layers/llm/stream.ts
3350
+ function handleToolEvent(toolInfo, toolState, emit) {
3351
+ if (toolInfo.type === "start") {
3352
+ toolState.currentTool = toolInfo.name;
3353
+ toolState.inputChunks.length = 0;
3354
+ emit.single({ _tag: "ToolStart", tool: toolInfo.name });
3355
+ return;
3356
+ }
3357
+ if (toolInfo.type === "input_delta" && toolInfo.partialJson) {
3358
+ toolState.inputChunks.push(toolInfo.partialJson);
3359
+ return;
3360
+ }
3361
+ if (toolInfo.type === "end" && toolState.currentTool) {
3362
+ const inputJson = toolState.inputChunks.join("");
3363
+ const input = safeParseJson(inputJson);
3364
+ if (input !== null) {
3365
+ emit.single({ _tag: "ToolUse", tool: toolState.currentTool, input });
3366
+ }
3367
+ emit.single({ _tag: "ToolEnd", tool: toolState.currentTool });
3368
+ toolState.currentTool = "";
3369
+ toolState.inputChunks.length = 0;
3370
+ }
3371
+ }
3372
+ function processJsonLine(json, outputChunks, toolState, emit) {
3373
+ const event = unwrapStreamEvent(json);
3374
+ const text = extractText(event);
3375
+ if (text) {
3376
+ outputChunks.push(text);
3377
+ emit.single({ _tag: "Text", text });
3378
+ return;
3379
+ }
3380
+ const toolInfo = extractToolInfo(event);
3381
+ if (toolInfo) {
3382
+ handleToolEvent(toolInfo, toolState, emit);
3383
+ }
3384
+ }
3385
+ function createEventStream(child) {
3386
+ return Stream4.async((emit) => {
3387
+ const outputChunks = [];
3388
+ const toolState = { currentTool: "", inputChunks: [] };
3389
+ const stdout = child.stdout;
3390
+ if (!stdout) {
3391
+ emit.fail(
3392
+ new LLMError({ message: "Failed to get stdout from child process" })
3393
+ );
3394
+ return Effect6.void;
3395
+ }
3396
+ const rl = createInterface({
3397
+ input: stdout,
3398
+ crlfDelay: Number.POSITIVE_INFINITY
3399
+ });
3400
+ rl.on("line", (line) => {
3401
+ const json = parseJsonLine(line);
3402
+ if (json) {
3403
+ processJsonLine(json, outputChunks, toolState, emit);
3404
+ }
3405
+ });
3406
+ child.stderr?.on("data", (data) => {
3407
+ const text = data.toString().trim();
3408
+ if (text) {
3409
+ emit.single({ _tag: "Text", text: `[stderr] ${text}` });
3410
+ }
3411
+ });
3412
+ child.on("close", (exitCode) => {
3413
+ if (exitCode !== 0) {
3414
+ emit.fail(
3415
+ new LLMError({
3416
+ message: `Claude CLI exited with code ${exitCode}`
3417
+ })
3418
+ );
3419
+ } else {
3420
+ const fullOutput = outputChunks.join("");
3421
+ emit.single({ _tag: "Done", output: fullOutput });
3422
+ emit.end();
3423
+ }
3424
+ });
3425
+ child.on("error", (error) => {
3426
+ emit.fail(
3427
+ new LLMError({
3428
+ message: error.message,
3429
+ cause: error
3430
+ })
3431
+ );
3432
+ });
3433
+ return Effect6.sync(() => {
3434
+ child.kill("SIGTERM");
3435
+ });
3436
+ });
3437
+ }
3438
+
3439
+ // src/layers/llm/claude-cli.ts
3440
+ var make2 = {
3441
+ execute: (prompt) => {
3442
+ return Stream5.unwrap(
3443
+ Effect7.sync(() => {
3444
+ const child = spawn(
3445
+ "claude",
3446
+ [
3447
+ "--permission-mode",
3448
+ "acceptEdits",
3449
+ "--output-format",
3450
+ "stream-json",
3451
+ "--verbose",
3452
+ "--include-partial-messages",
3453
+ "-p",
3454
+ prompt
3455
+ ],
3456
+ {
3457
+ stdio: ["inherit", "pipe", "pipe"],
3458
+ env: {
3459
+ ...process.env,
3460
+ FORCE_COLOR: "1"
3461
+ }
3462
+ }
3463
+ );
3464
+ return createEventStream(child);
3465
+ })
3466
+ );
3467
+ }
3468
+ };
3469
+ var Live3 = Layer3.succeed(LLM, make2);
3470
+ var ClaudeCLI = {
3471
+ Live: Live3
3472
+ };
3473
+
3474
+ // src/layers/llm/mock.ts
3475
+ init_esm_shims();
3476
+ import { Effect as Effect8, Layer as Layer4, Schema as S14, Stream as Stream6 } from "effect";
3477
+ var MockLLMConfigSchema = S14.Struct({
3478
+ events: S14.Array(LLMEventSchema),
3479
+ delayMs: S14.optional(S14.Number)
3192
3480
  });
3481
+ function createMockLLM(config) {
3482
+ return {
3483
+ execute: (_prompt) => {
3484
+ const baseStream = Stream6.fromIterable(config.events);
3485
+ if (config.delayMs !== void 0 && config.delayMs > 0) {
3486
+ const delay = config.delayMs;
3487
+ return baseStream.pipe(Stream6.tap(() => Effect8.sleep(delay)));
3488
+ }
3489
+ return baseStream;
3490
+ }
3491
+ };
3492
+ }
3493
+ var defaultMockEvents = [
3494
+ { _tag: "Text", text: "Processing task...\n" },
3495
+ { _tag: "ToolStart", tool: "Read" },
3496
+ { _tag: "ToolEnd", tool: "Read" },
3497
+ { _tag: "Text", text: "Task completed successfully.\n" },
3498
+ {
3499
+ _tag: "Done",
3500
+ output: "Processing task...\nTask completed successfully.\n"
3501
+ }
3502
+ ];
3503
+ var defaultMock = createMockLLM({ events: defaultMockEvents });
3504
+ var Live4 = Layer4.succeed(LLM, defaultMock);
3505
+ function layer2(config) {
3506
+ return Layer4.succeed(LLM, createMockLLM(config));
3507
+ }
3508
+ var Mock = {
3509
+ Live: Live4,
3510
+ layer: layer2,
3511
+ createMockLLM
3512
+ };
3513
+
3514
+ // src/layers/plan/file-system.ts
3515
+ init_esm_shims();
3516
+ import { access, mkdir as mkdir2, readdir, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
3517
+ import { join as join2 } from "path";
3518
+ import { Effect as Effect9, Layer as Layer5 } from "effect";
3193
3519
 
3194
3520
  // src/services/plan-store.ts
3195
3521
  init_esm_shims();
3196
- import { Context as Context2 } from "effect";
3197
- var PlanStore = class extends Context2.Tag("@ferix/PlanStore")() {
3522
+ import { Context as Context3 } from "effect";
3523
+ var PlanStore = class extends Context3.Tag("@ferix/PlanStore")() {
3198
3524
  };
3199
3525
 
3200
3526
  // src/layers/plan/file-system.ts
3201
- var PLANS_DIR = ".ferix/plans";
3202
- function ensureDir(dirPath) {
3203
- return Effect7.tryPromise({
3204
- try: () => mkdir(dirPath, { recursive: true }),
3527
+ var PLANS_DIR2 = ".ferix/plans";
3528
+ function ensureDir2(dirPath) {
3529
+ return Effect9.tryPromise({
3530
+ try: () => mkdir2(dirPath, { recursive: true }),
3205
3531
  catch: (error) => new PlanStoreError({
3206
3532
  message: `Failed to create directory: ${dirPath}`,
3207
3533
  operation: "create",
3208
3534
  cause: error
3209
3535
  })
3210
- }).pipe(Effect7.asVoid);
3536
+ }).pipe(Effect9.asVoid);
3211
3537
  }
3212
- function getSessionDir(sessionId) {
3213
- return join(process.cwd(), PLANS_DIR, sessionId);
3538
+ function getSessionDir2(sessionId) {
3539
+ return join2(process.cwd(), PLANS_DIR2, sessionId);
3214
3540
  }
3215
3541
  function getPlanPath(sessionId, planId) {
3216
- return join(getSessionDir(sessionId), `${planId}.json`);
3542
+ return join2(getSessionDir2(sessionId), `${planId}.json`);
3217
3543
  }
3218
3544
  function generatePlanId(taskNumber) {
3219
3545
  return PlanId(`task-${taskNumber}`);
@@ -3222,8 +3548,8 @@ function serializePlan(plan) {
3222
3548
  return JSON.stringify(plan, null, 2);
3223
3549
  }
3224
3550
  function deserializePlan(json, planId) {
3225
- return Effect7.gen(function* () {
3226
- const parsed = yield* Effect7.try({
3551
+ return Effect9.gen(function* () {
3552
+ const parsed = yield* Effect9.try({
3227
3553
  try: () => JSON.parse(json),
3228
3554
  catch: (error) => new PlanStoreError({
3229
3555
  message: `Invalid JSON in plan file: ${String(error)}`,
@@ -3232,7 +3558,7 @@ function deserializePlan(json, planId) {
3232
3558
  })
3233
3559
  });
3234
3560
  const validated = yield* decodePlanData(parsed).pipe(
3235
- Effect7.mapError(
3561
+ Effect9.mapError(
3236
3562
  (error) => new PlanStoreError({
3237
3563
  message: `Plan validation failed: ${String(error)}`,
3238
3564
  operation: "load",
@@ -3246,11 +3572,11 @@ function deserializePlan(json, planId) {
3246
3572
  };
3247
3573
  });
3248
3574
  }
3249
- var make2 = {
3250
- create: (sessionId, plan) => Effect7.gen(function* () {
3251
- const sessionDir = getSessionDir(sessionId);
3252
- yield* ensureDir(sessionDir);
3253
- const existingPlans = yield* Effect7.tryPromise({
3575
+ var make3 = {
3576
+ create: (sessionId, plan) => Effect9.gen(function* () {
3577
+ const sessionDir = getSessionDir2(sessionId);
3578
+ yield* ensureDir2(sessionDir);
3579
+ const existingPlans = yield* Effect9.tryPromise({
3254
3580
  try: async () => {
3255
3581
  try {
3256
3582
  const files = await readdir(sessionDir);
@@ -3267,8 +3593,8 @@ var make2 = {
3267
3593
  const planId = generatePlanId(existingPlans + 1);
3268
3594
  const planPath = getPlanPath(sessionId, planId);
3269
3595
  const fullPlan = { ...plan, id: planId };
3270
- yield* Effect7.tryPromise({
3271
- try: () => writeFile(planPath, serializePlan(fullPlan), "utf-8"),
3596
+ yield* Effect9.tryPromise({
3597
+ try: () => writeFile2(planPath, serializePlan(fullPlan), "utf-8"),
3272
3598
  catch: (error) => new PlanStoreError({
3273
3599
  message: `Failed to write plan file: ${planPath}`,
3274
3600
  operation: "create",
@@ -3277,11 +3603,11 @@ var make2 = {
3277
3603
  });
3278
3604
  return planId;
3279
3605
  }),
3280
- load: (planId, sessionId) => Effect7.gen(function* () {
3606
+ load: (planId, sessionId) => Effect9.gen(function* () {
3281
3607
  if (sessionId) {
3282
3608
  const planPath = getPlanPath(sessionId, planId);
3283
- const content = yield* Effect7.tryPromise({
3284
- try: () => readFile(planPath, "utf-8"),
3609
+ const content = yield* Effect9.tryPromise({
3610
+ try: () => readFile2(planPath, "utf-8"),
3285
3611
  catch: (error) => new PlanStoreError({
3286
3612
  message: `Failed to read plan file: ${planPath}`,
3287
3613
  operation: "load",
@@ -3290,9 +3616,9 @@ var make2 = {
3290
3616
  });
3291
3617
  return yield* deserializePlan(content, planId);
3292
3618
  }
3293
- const sessionDirs = yield* Effect7.tryPromise({
3619
+ const sessionDirs = yield* Effect9.tryPromise({
3294
3620
  try: async () => {
3295
- const plansDir = join(process.cwd(), PLANS_DIR);
3621
+ const plansDir = join2(process.cwd(), PLANS_DIR2);
3296
3622
  const dirs = await readdir(plansDir);
3297
3623
  return dirs;
3298
3624
  },
@@ -3304,7 +3630,7 @@ var make2 = {
3304
3630
  });
3305
3631
  for (const sid of sessionDirs) {
3306
3632
  const planPath = getPlanPath(sid, planId);
3307
- const exists = yield* Effect7.tryPromise({
3633
+ const exists = yield* Effect9.tryPromise({
3308
3634
  try: async () => {
3309
3635
  await access(planPath);
3310
3636
  return true;
@@ -3313,10 +3639,10 @@ var make2 = {
3313
3639
  message: "File not found",
3314
3640
  operation: "load"
3315
3641
  })
3316
- }).pipe(Effect7.orElseSucceed(() => false));
3642
+ }).pipe(Effect9.orElseSucceed(() => false));
3317
3643
  if (exists) {
3318
- const content = yield* Effect7.tryPromise({
3319
- try: () => readFile(planPath, "utf-8"),
3644
+ const content = yield* Effect9.tryPromise({
3645
+ try: () => readFile2(planPath, "utf-8"),
3320
3646
  catch: (error) => new PlanStoreError({
3321
3647
  message: `Failed to read plan file: ${planPath}`,
3322
3648
  operation: "load",
@@ -3326,17 +3652,17 @@ var make2 = {
3326
3652
  return yield* deserializePlan(content, planId);
3327
3653
  }
3328
3654
  }
3329
- return yield* Effect7.fail(
3655
+ return yield* Effect9.fail(
3330
3656
  new PlanStoreError({
3331
3657
  message: `Plan not found: ${planId}`,
3332
3658
  operation: "load"
3333
3659
  })
3334
3660
  );
3335
3661
  }),
3336
- update: (planId, plan) => Effect7.gen(function* () {
3662
+ update: (planId, plan) => Effect9.gen(function* () {
3337
3663
  const planPath = getPlanPath(plan.sessionId, planId);
3338
- yield* Effect7.tryPromise({
3339
- try: () => writeFile(planPath, serializePlan(plan), "utf-8"),
3664
+ yield* Effect9.tryPromise({
3665
+ try: () => writeFile2(planPath, serializePlan(plan), "utf-8"),
3340
3666
  catch: (error) => new PlanStoreError({
3341
3667
  message: `Failed to update plan file: ${planPath}`,
3342
3668
  operation: "update",
@@ -3344,9 +3670,9 @@ var make2 = {
3344
3670
  })
3345
3671
  });
3346
3672
  }),
3347
- list: (sessionId) => Effect7.gen(function* () {
3348
- const sessionDir = getSessionDir(sessionId);
3349
- const files = yield* Effect7.tryPromise({
3673
+ list: (sessionId) => Effect9.gen(function* () {
3674
+ const sessionDir = getSessionDir2(sessionId);
3675
+ const files = yield* Effect9.tryPromise({
3350
3676
  try: async () => {
3351
3677
  try {
3352
3678
  return await readdir(sessionDir);
@@ -3363,18 +3689,18 @@ var make2 = {
3363
3689
  return files.filter((f) => f.endsWith(".json")).map((f) => PlanId(f.replace(".json", "")));
3364
3690
  })
3365
3691
  };
3366
- var Live3 = Layer3.succeed(PlanStore, make2);
3692
+ var Live5 = Layer5.succeed(PlanStore, make3);
3367
3693
  var FileSystemPlan = {
3368
- Live: Live3
3694
+ Live: Live5
3369
3695
  };
3370
3696
 
3371
3697
  // src/layers/plan/memory.ts
3372
3698
  init_esm_shims();
3373
- import { Effect as Effect8, Layer as Layer4, Ref as Ref3 } from "effect";
3699
+ import { Effect as Effect10, Layer as Layer6, Ref as Ref4 } from "effect";
3374
3700
  function createMemoryPlanStore(stateRef) {
3375
3701
  return {
3376
- create: (sessionId, plan) => Effect8.gen(function* () {
3377
- const state = yield* Ref3.get(stateRef);
3702
+ create: (sessionId, plan) => Effect10.gen(function* () {
3703
+ const state = yield* Ref4.get(stateRef);
3378
3704
  if (!state.has(sessionId)) {
3379
3705
  state.set(sessionId, /* @__PURE__ */ new Map());
3380
3706
  }
@@ -3385,18 +3711,18 @@ function createMemoryPlanStore(stateRef) {
3385
3711
  const planId = PlanId(`task-${sessionPlans.size + 1}`);
3386
3712
  const fullPlan = { ...plan, id: planId };
3387
3713
  sessionPlans.set(planId, fullPlan);
3388
- yield* Ref3.set(stateRef, state);
3714
+ yield* Ref4.set(stateRef, state);
3389
3715
  return planId;
3390
3716
  }),
3391
- load: (planId, sessionId) => Effect8.gen(function* () {
3392
- const state = yield* Ref3.get(stateRef);
3717
+ load: (planId, sessionId) => Effect10.gen(function* () {
3718
+ const state = yield* Ref4.get(stateRef);
3393
3719
  if (sessionId) {
3394
3720
  const sessionPlans = state.get(sessionId);
3395
3721
  const plan = sessionPlans?.get(planId);
3396
3722
  if (plan) {
3397
3723
  return plan;
3398
3724
  }
3399
- return yield* Effect8.fail(
3725
+ return yield* Effect10.fail(
3400
3726
  new PlanStoreError({
3401
3727
  message: `Plan not found: ${planId}`,
3402
3728
  operation: "load"
@@ -3409,18 +3735,18 @@ function createMemoryPlanStore(stateRef) {
3409
3735
  return plan;
3410
3736
  }
3411
3737
  }
3412
- return yield* Effect8.fail(
3738
+ return yield* Effect10.fail(
3413
3739
  new PlanStoreError({
3414
3740
  message: `Plan not found: ${planId}`,
3415
3741
  operation: "load"
3416
3742
  })
3417
3743
  );
3418
3744
  }),
3419
- update: (planId, plan) => Effect8.gen(function* () {
3420
- const state = yield* Ref3.get(stateRef);
3745
+ update: (planId, plan) => Effect10.gen(function* () {
3746
+ const state = yield* Ref4.get(stateRef);
3421
3747
  const sessionPlans = state.get(plan.sessionId);
3422
3748
  if (!sessionPlans) {
3423
- return yield* Effect8.fail(
3749
+ return yield* Effect10.fail(
3424
3750
  new PlanStoreError({
3425
3751
  message: `Session not found: ${plan.sessionId}`,
3426
3752
  operation: "update"
@@ -3428,10 +3754,10 @@ function createMemoryPlanStore(stateRef) {
3428
3754
  );
3429
3755
  }
3430
3756
  sessionPlans.set(planId, plan);
3431
- yield* Ref3.set(stateRef, state);
3757
+ yield* Ref4.set(stateRef, state);
3432
3758
  }),
3433
- list: (sessionId) => Effect8.gen(function* () {
3434
- const state = yield* Ref3.get(stateRef);
3759
+ list: (sessionId) => Effect10.gen(function* () {
3760
+ const state = yield* Ref4.get(stateRef);
3435
3761
  const sessionPlans = state.get(sessionId);
3436
3762
  if (!sessionPlans) {
3437
3763
  return [];
@@ -3440,32 +3766,236 @@ function createMemoryPlanStore(stateRef) {
3440
3766
  })
3441
3767
  };
3442
3768
  }
3443
- function layer2() {
3444
- return Layer4.effect(
3769
+ function layer3() {
3770
+ return Layer6.effect(
3445
3771
  PlanStore,
3446
- Effect8.gen(function* () {
3447
- const stateRef = yield* Ref3.make(/* @__PURE__ */ new Map());
3772
+ Effect10.gen(function* () {
3773
+ const stateRef = yield* Ref4.make(/* @__PURE__ */ new Map());
3448
3774
  return createMemoryPlanStore(stateRef);
3449
3775
  })
3450
3776
  );
3451
3777
  }
3452
- var Live4 = layer2();
3778
+ var Live6 = layer3();
3453
3779
  var MemoryPlan = {
3454
- Live: Live4,
3455
- layer: layer2
3780
+ Live: Live6,
3781
+ layer: layer3
3782
+ };
3783
+
3784
+ // src/layers/progress/file-system.ts
3785
+ init_esm_shims();
3786
+ import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
3787
+ import { join as join3 } from "path";
3788
+ import { DateTime as DateTime3, Effect as Effect11, Layer as Layer7 } from "effect";
3789
+
3790
+ // src/services/progress-store.ts
3791
+ init_esm_shims();
3792
+ import { Context as Context4 } from "effect";
3793
+ var ProgressStore = class extends Context4.Tag("@ferix/ProgressStore")() {
3794
+ };
3795
+
3796
+ // src/layers/progress/file-system.ts
3797
+ var PLANS_DIR3 = ".ferix/plans";
3798
+ function ensureDir3(dirPath) {
3799
+ return Effect11.tryPromise({
3800
+ try: () => mkdir3(dirPath, { recursive: true }),
3801
+ catch: (error) => new ProgressStoreError({
3802
+ message: `Failed to create directory: ${dirPath}`,
3803
+ operation: "append",
3804
+ cause: error
3805
+ })
3806
+ }).pipe(Effect11.asVoid);
3807
+ }
3808
+ function getSessionDir3(sessionId) {
3809
+ return join3(process.cwd(), PLANS_DIR3, sessionId);
3810
+ }
3811
+ function getProgressPath(sessionId) {
3812
+ return join3(getSessionDir3(sessionId), "progress.json");
3813
+ }
3814
+ function serializeProgress(progress) {
3815
+ return JSON.stringify(progress, null, 2);
3816
+ }
3817
+ function deserializeProgress(json) {
3818
+ return Effect11.gen(function* () {
3819
+ const parsed = yield* Effect11.try({
3820
+ try: () => JSON.parse(json),
3821
+ catch: (error) => new ProgressStoreError({
3822
+ message: `Invalid JSON in progress file: ${String(error)}`,
3823
+ operation: "load",
3824
+ cause: error
3825
+ })
3826
+ });
3827
+ const validated = yield* decodeProgressFile(parsed).pipe(
3828
+ Effect11.mapError(
3829
+ (error) => new ProgressStoreError({
3830
+ message: `Progress validation failed: ${String(error)}`,
3831
+ operation: "load",
3832
+ cause: error
3833
+ })
3834
+ )
3835
+ );
3836
+ return validated;
3837
+ });
3838
+ }
3839
+ function createEmptyProgress(sessionId, createdAt) {
3840
+ return {
3841
+ sessionId,
3842
+ createdAt,
3843
+ entries: []
3844
+ };
3845
+ }
3846
+ var make4 = {
3847
+ append: (sessionId, entry) => Effect11.gen(function* () {
3848
+ const sessionDir = getSessionDir3(sessionId);
3849
+ yield* ensureDir3(sessionDir);
3850
+ const progressPath = getProgressPath(sessionId);
3851
+ const existing = yield* Effect11.tryPromise({
3852
+ try: async () => {
3853
+ try {
3854
+ const content = await readFile3(progressPath, "utf-8");
3855
+ return content;
3856
+ } catch {
3857
+ return null;
3858
+ }
3859
+ },
3860
+ catch: (error) => new ProgressStoreError({
3861
+ message: `Failed to read progress file: ${progressPath}`,
3862
+ operation: "append",
3863
+ cause: error
3864
+ })
3865
+ });
3866
+ let progress;
3867
+ if (existing) {
3868
+ progress = yield* deserializeProgress(existing).pipe(
3869
+ Effect11.mapError(
3870
+ (err) => new ProgressStoreError({
3871
+ message: err.message,
3872
+ operation: "append",
3873
+ cause: err
3874
+ })
3875
+ )
3876
+ );
3877
+ } else {
3878
+ const now = yield* DateTime3.now;
3879
+ progress = createEmptyProgress(sessionId, DateTime3.formatIso(now));
3880
+ }
3881
+ const updatedProgress = {
3882
+ ...progress,
3883
+ entries: [...progress.entries, entry]
3884
+ };
3885
+ yield* Effect11.tryPromise({
3886
+ try: () => writeFile3(progressPath, serializeProgress(updatedProgress), "utf-8"),
3887
+ catch: (error) => new ProgressStoreError({
3888
+ message: `Failed to write progress file: ${progressPath}`,
3889
+ operation: "append",
3890
+ cause: error
3891
+ })
3892
+ });
3893
+ }),
3894
+ load: (sessionId) => Effect11.gen(function* () {
3895
+ const progressPath = getProgressPath(sessionId);
3896
+ const content = yield* Effect11.tryPromise({
3897
+ try: async () => {
3898
+ try {
3899
+ return await readFile3(progressPath, "utf-8");
3900
+ } catch {
3901
+ return null;
3902
+ }
3903
+ },
3904
+ catch: (error) => new ProgressStoreError({
3905
+ message: `Failed to read progress file: ${progressPath}`,
3906
+ operation: "load",
3907
+ cause: error
3908
+ })
3909
+ });
3910
+ if (content === null) {
3911
+ const now = yield* DateTime3.now;
3912
+ return createEmptyProgress(sessionId, DateTime3.formatIso(now));
3913
+ }
3914
+ return yield* deserializeProgress(content);
3915
+ }),
3916
+ getRecent: (sessionId, count) => Effect11.gen(function* () {
3917
+ const progress = yield* make4.load(sessionId);
3918
+ const entries = progress.entries;
3919
+ return entries.slice(-count);
3920
+ })
3921
+ };
3922
+ var Live7 = Layer7.succeed(ProgressStore, make4);
3923
+ var FileSystemProgress = {
3924
+ Live: Live7
3925
+ };
3926
+
3927
+ // src/layers/progress/memory.ts
3928
+ init_esm_shims();
3929
+ import { DateTime as DateTime4, Effect as Effect12, Layer as Layer8, Ref as Ref5 } from "effect";
3930
+ function createMemoryProgressStore(stateRef) {
3931
+ return {
3932
+ append: (sessionId, entry) => Effect12.gen(function* () {
3933
+ const state = yield* Ref5.get(stateRef);
3934
+ let progress = state.get(sessionId);
3935
+ if (!progress) {
3936
+ const now = yield* DateTime4.now;
3937
+ progress = {
3938
+ sessionId,
3939
+ createdAt: DateTime4.formatIso(now),
3940
+ entries: []
3941
+ };
3942
+ }
3943
+ const updatedProgress = {
3944
+ ...progress,
3945
+ entries: [...progress.entries, entry]
3946
+ };
3947
+ state.set(sessionId, updatedProgress);
3948
+ yield* Ref5.set(stateRef, state);
3949
+ }),
3950
+ load: (sessionId) => Effect12.gen(function* () {
3951
+ const state = yield* Ref5.get(stateRef);
3952
+ const progress = state.get(sessionId);
3953
+ if (!progress) {
3954
+ const now = yield* DateTime4.now;
3955
+ return {
3956
+ sessionId,
3957
+ createdAt: DateTime4.formatIso(now),
3958
+ entries: []
3959
+ };
3960
+ }
3961
+ return progress;
3962
+ }),
3963
+ getRecent: (sessionId, count) => Effect12.gen(function* () {
3964
+ const state = yield* Ref5.get(stateRef);
3965
+ const progress = state.get(sessionId);
3966
+ if (!progress) {
3967
+ return [];
3968
+ }
3969
+ return progress.entries.slice(-count);
3970
+ })
3971
+ };
3972
+ }
3973
+ function layer4() {
3974
+ return Layer8.effect(
3975
+ ProgressStore,
3976
+ Effect12.gen(function* () {
3977
+ const stateRef = yield* Ref5.make(/* @__PURE__ */ new Map());
3978
+ return createMemoryProgressStore(stateRef);
3979
+ })
3980
+ );
3981
+ }
3982
+ var Live8 = layer4();
3983
+ var MemoryProgress = {
3984
+ Live: Live8,
3985
+ layer: layer4
3456
3986
  };
3457
3987
 
3458
3988
  // src/layers/session/file-system.ts
3459
3989
  init_esm_shims();
3460
- import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
3461
- import { join as join2 } from "path";
3462
- import { DateTime, Effect as Effect9, Layer as Layer5 } from "effect";
3990
+ import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
3991
+ import { join as join4 } from "path";
3992
+ import { DateTime as DateTime5, Effect as Effect13, Layer as Layer9 } from "effect";
3463
3993
  import { humanId } from "human-id";
3464
3994
 
3465
3995
  // src/services/session-store.ts
3466
3996
  init_esm_shims();
3467
- import { Context as Context3 } from "effect";
3468
- var SessionStore = class extends Context3.Tag("@ferix/SessionStore")() {
3997
+ import { Context as Context5 } from "effect";
3998
+ var SessionStore = class extends Context5.Tag("@ferix/SessionStore")() {
3469
3999
  };
3470
4000
 
3471
4001
  // src/layers/session/file-system.ts
@@ -3474,25 +4004,25 @@ function generateSessionId(timestampMs) {
3474
4004
  const id = humanId({ separator: "-", capitalize: false });
3475
4005
  return `${id}-${timestampMs}`;
3476
4006
  }
3477
- function ensureDir2(dirPath) {
3478
- return Effect9.tryPromise({
3479
- try: () => mkdir2(dirPath, { recursive: true }),
4007
+ function ensureDir4(dirPath) {
4008
+ return Effect13.tryPromise({
4009
+ try: () => mkdir4(dirPath, { recursive: true }),
3480
4010
  catch: (error) => new SessionStoreError({
3481
4011
  message: `Failed to create directory: ${dirPath}`,
3482
4012
  operation: "create",
3483
4013
  cause: error
3484
4014
  })
3485
- }).pipe(Effect9.asVoid);
4015
+ }).pipe(Effect13.asVoid);
3486
4016
  }
3487
4017
  function getSessionPath(sessionId) {
3488
- return join2(process.cwd(), SESSIONS_DIR, `${sessionId}.json`);
4018
+ return join4(process.cwd(), SESSIONS_DIR, `${sessionId}.json`);
3489
4019
  }
3490
4020
  function serializeSession(session) {
3491
4021
  return JSON.stringify(session, null, 2);
3492
4022
  }
3493
4023
  function deserializeSession(json) {
3494
- return Effect9.gen(function* () {
3495
- const parsed = yield* Effect9.try({
4024
+ return Effect13.gen(function* () {
4025
+ const parsed = yield* Effect13.try({
3496
4026
  try: () => JSON.parse(json),
3497
4027
  catch: (error) => new SessionStoreError({
3498
4028
  message: `Invalid JSON in session file: ${String(error)}`,
@@ -3501,7 +4031,7 @@ function deserializeSession(json) {
3501
4031
  })
3502
4032
  });
3503
4033
  const validated = yield* decodeSession(parsed).pipe(
3504
- Effect9.mapError(
4034
+ Effect13.mapError(
3505
4035
  (error) => new SessionStoreError({
3506
4036
  message: `Session validation failed: ${String(error)}`,
3507
4037
  operation: "get",
@@ -3512,23 +4042,23 @@ function deserializeSession(json) {
3512
4042
  return validated;
3513
4043
  });
3514
4044
  }
3515
- var make3 = {
3516
- create: (originalTask) => Effect9.gen(function* () {
3517
- const sessionsDir = join2(process.cwd(), SESSIONS_DIR);
3518
- yield* ensureDir2(sessionsDir);
3519
- const now = yield* DateTime.now;
3520
- const timestampMs = DateTime.toEpochMillis(now);
4045
+ var make5 = {
4046
+ create: (originalTask) => Effect13.gen(function* () {
4047
+ const sessionsDir = join4(process.cwd(), SESSIONS_DIR);
4048
+ yield* ensureDir4(sessionsDir);
4049
+ const now = yield* DateTime5.now;
4050
+ const timestampMs = DateTime5.toEpochMillis(now);
3521
4051
  const sessionId = generateSessionId(timestampMs);
3522
4052
  const session = {
3523
4053
  id: sessionId,
3524
- createdAt: DateTime.formatIso(now),
4054
+ createdAt: DateTime5.formatIso(now),
3525
4055
  status: "active",
3526
4056
  originalTask,
3527
4057
  completedTasks: []
3528
4058
  };
3529
4059
  const sessionPath = getSessionPath(sessionId);
3530
- yield* Effect9.tryPromise({
3531
- try: () => writeFile2(sessionPath, serializeSession(session), "utf-8"),
4060
+ yield* Effect13.tryPromise({
4061
+ try: () => writeFile4(sessionPath, serializeSession(session), "utf-8"),
3532
4062
  catch: (error) => new SessionStoreError({
3533
4063
  message: `Failed to write session file: ${sessionPath}`,
3534
4064
  operation: "create",
@@ -3537,10 +4067,10 @@ var make3 = {
3537
4067
  });
3538
4068
  return session;
3539
4069
  }),
3540
- get: (sessionId) => Effect9.gen(function* () {
4070
+ get: (sessionId) => Effect13.gen(function* () {
3541
4071
  const sessionPath = getSessionPath(sessionId);
3542
- const content = yield* Effect9.tryPromise({
3543
- try: () => readFile2(sessionPath, "utf-8"),
4072
+ const content = yield* Effect13.tryPromise({
4073
+ try: () => readFile4(sessionPath, "utf-8"),
3544
4074
  catch: (error) => new SessionStoreError({
3545
4075
  message: `Failed to read session file: ${sessionPath}`,
3546
4076
  operation: "get",
@@ -3549,10 +4079,10 @@ var make3 = {
3549
4079
  });
3550
4080
  return yield* deserializeSession(content);
3551
4081
  }),
3552
- update: (sessionId, session) => Effect9.gen(function* () {
4082
+ update: (sessionId, session) => Effect13.gen(function* () {
3553
4083
  const sessionPath = getSessionPath(sessionId);
3554
- yield* Effect9.tryPromise({
3555
- try: () => writeFile2(sessionPath, serializeSession(session), "utf-8"),
4084
+ yield* Effect13.tryPromise({
4085
+ try: () => writeFile4(sessionPath, serializeSession(session), "utf-8"),
3556
4086
  catch: (error) => new SessionStoreError({
3557
4087
  message: `Failed to update session file: ${sessionPath}`,
3558
4088
  operation: "update",
@@ -3561,37 +4091,37 @@ var make3 = {
3561
4091
  });
3562
4092
  })
3563
4093
  };
3564
- var Live5 = Layer5.succeed(SessionStore, make3);
4094
+ var Live9 = Layer9.succeed(SessionStore, make5);
3565
4095
  var FileSystemSession = {
3566
- Live: Live5
4096
+ Live: Live9
3567
4097
  };
3568
4098
 
3569
4099
  // src/layers/session/memory.ts
3570
4100
  init_esm_shims();
3571
- import { DateTime as DateTime2, Effect as Effect10, Layer as Layer6, Ref as Ref4 } from "effect";
4101
+ import { DateTime as DateTime6, Effect as Effect14, Layer as Layer10, Ref as Ref6 } from "effect";
3572
4102
  function createMemorySessionStore(stateRef, counterRef) {
3573
4103
  return {
3574
- create: (originalTask) => Effect10.gen(function* () {
3575
- const state = yield* Ref4.get(stateRef);
3576
- const counter = yield* Ref4.updateAndGet(counterRef, (n) => n + 1);
4104
+ create: (originalTask) => Effect14.gen(function* () {
4105
+ const state = yield* Ref6.get(stateRef);
4106
+ const counter = yield* Ref6.updateAndGet(counterRef, (n) => n + 1);
3577
4107
  const sessionId = `test-session-${counter}`;
3578
- const now = yield* DateTime2.now;
4108
+ const now = yield* DateTime6.now;
3579
4109
  const session = {
3580
4110
  id: sessionId,
3581
- createdAt: DateTime2.formatIso(now),
4111
+ createdAt: DateTime6.formatIso(now),
3582
4112
  status: "active",
3583
4113
  originalTask,
3584
4114
  completedTasks: []
3585
4115
  };
3586
4116
  state.set(sessionId, session);
3587
- yield* Ref4.set(stateRef, state);
4117
+ yield* Ref6.set(stateRef, state);
3588
4118
  return session;
3589
4119
  }),
3590
- get: (sessionId) => Effect10.gen(function* () {
3591
- const state = yield* Ref4.get(stateRef);
4120
+ get: (sessionId) => Effect14.gen(function* () {
4121
+ const state = yield* Ref6.get(stateRef);
3592
4122
  const session = state.get(sessionId);
3593
4123
  if (!session) {
3594
- return yield* Effect10.fail(
4124
+ return yield* Effect14.fail(
3595
4125
  new SessionStoreError({
3596
4126
  message: `Session not found: ${sessionId}`,
3597
4127
  operation: "get"
@@ -3600,10 +4130,10 @@ function createMemorySessionStore(stateRef, counterRef) {
3600
4130
  }
3601
4131
  return session;
3602
4132
  }),
3603
- update: (sessionId, session) => Effect10.gen(function* () {
3604
- const state = yield* Ref4.get(stateRef);
4133
+ update: (sessionId, session) => Effect14.gen(function* () {
4134
+ const state = yield* Ref6.get(stateRef);
3605
4135
  if (!state.has(sessionId)) {
3606
- return yield* Effect10.fail(
4136
+ return yield* Effect14.fail(
3607
4137
  new SessionStoreError({
3608
4138
  message: `Session not found: ${sessionId}`,
3609
4139
  operation: "update"
@@ -3611,34 +4141,34 @@ function createMemorySessionStore(stateRef, counterRef) {
3611
4141
  );
3612
4142
  }
3613
4143
  state.set(sessionId, session);
3614
- yield* Ref4.set(stateRef, state);
4144
+ yield* Ref6.set(stateRef, state);
3615
4145
  })
3616
4146
  };
3617
4147
  }
3618
- function layer3() {
3619
- return Layer6.effect(
4148
+ function layer5() {
4149
+ return Layer10.effect(
3620
4150
  SessionStore,
3621
- Effect10.gen(function* () {
3622
- const stateRef = yield* Ref4.make(/* @__PURE__ */ new Map());
3623
- const counterRef = yield* Ref4.make(0);
4151
+ Effect14.gen(function* () {
4152
+ const stateRef = yield* Ref6.make(/* @__PURE__ */ new Map());
4153
+ const counterRef = yield* Ref6.make(0);
3624
4154
  return createMemorySessionStore(stateRef, counterRef);
3625
4155
  })
3626
4156
  );
3627
4157
  }
3628
- var Live6 = layer3();
4158
+ var Live10 = layer5();
3629
4159
  var MemorySession = {
3630
- Live: Live6,
3631
- layer: layer3
4160
+ Live: Live10,
4161
+ layer: layer5
3632
4162
  };
3633
4163
 
3634
4164
  // src/layers/signal/ferix-parser.ts
3635
4165
  init_esm_shims();
3636
- import { Effect as Effect11, Layer as Layer7, Ref as Ref5 } from "effect";
4166
+ import { Effect as Effect15, Layer as Layer11, Ref as Ref7 } from "effect";
3637
4167
 
3638
4168
  // src/services/signal-parser.ts
3639
4169
  init_esm_shims();
3640
- import { Context as Context4 } from "effect";
3641
- var SignalParser = class extends Context4.Tag("@ferix/SignalParser")() {
4170
+ import { Context as Context6 } from "effect";
4171
+ var SignalParser = class extends Context6.Tag("@ferix/SignalParser")() {
3642
4172
  };
3643
4173
 
3644
4174
  // src/layers/signal/specs/index.ts
@@ -3646,7 +4176,7 @@ init_esm_shims();
3646
4176
 
3647
4177
  // src/layers/signal/specs/check.ts
3648
4178
  init_esm_shims();
3649
- import { Schema as S13 } from "effect";
4179
+ import { Schema as S15 } from "effect";
3650
4180
 
3651
4181
  // src/layers/signal/specs/registry.ts
3652
4182
  init_esm_shims();
@@ -3703,7 +4233,7 @@ var checkPassedSpec = {
3703
4233
  parse: (text) => {
3704
4234
  if (CHECK_PASSED.test(text)) {
3705
4235
  const raw = { _tag: "CheckPassed" };
3706
- const result = S13.decodeUnknownEither(CheckPassedSignalSchema)(raw);
4236
+ const result = S15.decodeUnknownEither(CheckPassedSignalSchema)(raw);
3707
4237
  if (result._tag === "Right") {
3708
4238
  return [result.right];
3709
4239
  }
@@ -3719,7 +4249,7 @@ var checkFailedSpec = {
3719
4249
  parse: (text) => {
3720
4250
  if (CHECK_FAILED.test(text)) {
3721
4251
  const raw = { _tag: "CheckFailed" };
3722
- const result = S13.decodeUnknownEither(CheckFailedSignalSchema)(raw);
4252
+ const result = S15.decodeUnknownEither(CheckFailedSignalSchema)(raw);
3723
4253
  if (result._tag === "Right") {
3724
4254
  return [result.right];
3725
4255
  }
@@ -3733,7 +4263,7 @@ signalSpecRegistry.register(checkFailedSpec);
3733
4263
 
3734
4264
  // src/layers/signal/specs/criteria.ts
3735
4265
  init_esm_shims();
3736
- import { Schema as S14 } from "effect";
4266
+ import { Schema as S16 } from "effect";
3737
4267
  var CRITERIA_BLOCK = /<ferix:criteria task="(\d+)">([\s\S]*?)<\/ferix:criteria>/g;
3738
4268
  var CRITERION = /<criterion id="([^"]+)">([^<]+)<\/criterion>/g;
3739
4269
  var CRITERION_PASSED = /<ferix:criterion-passed id="([\d.c]+)"\/>/g;
@@ -3764,7 +4294,7 @@ var criteriaDefinedSpec = {
3764
4294
  taskId: match[1],
3765
4295
  criteria
3766
4296
  };
3767
- const result = S14.decodeUnknownEither(CriteriaDefinedSignalSchema)(raw);
4297
+ const result = S16.decodeUnknownEither(CriteriaDefinedSignalSchema)(raw);
3768
4298
  if (result._tag === "Right") {
3769
4299
  signals.push(result.right);
3770
4300
  }
@@ -3783,7 +4313,7 @@ var criterionPassedSpec = {
3783
4313
  for (const m of text.matchAll(resetRegex(CRITERION_PASSED))) {
3784
4314
  if (m[1]) {
3785
4315
  const raw = { _tag: "CriterionPassed", criterionId: m[1] };
3786
- const result = S14.decodeUnknownEither(CriterionPassedSignalSchema)(raw);
4316
+ const result = S16.decodeUnknownEither(CriterionPassedSignalSchema)(raw);
3787
4317
  if (result._tag === "Right") {
3788
4318
  signals.push(result.right);
3789
4319
  }
@@ -3806,7 +4336,7 @@ var criterionFailedSpec = {
3806
4336
  criterionId: m[1],
3807
4337
  reason: m[2] || "Unknown reason"
3808
4338
  };
3809
- const result = S14.decodeUnknownEither(CriterionFailedSignalSchema)(raw);
4339
+ const result = S16.decodeUnknownEither(CriterionFailedSignalSchema)(raw);
3810
4340
  if (result._tag === "Right") {
3811
4341
  signals.push(result.right);
3812
4342
  }
@@ -3820,9 +4350,88 @@ signalSpecRegistry.register(criteriaDefinedSpec);
3820
4350
  signalSpecRegistry.register(criterionPassedSpec);
3821
4351
  signalSpecRegistry.register(criterionFailedSpec);
3822
4352
 
4353
+ // src/layers/signal/specs/guardrail.ts
4354
+ init_esm_shims();
4355
+ import { Schema as S17 } from "effect";
4356
+ var GUARDRAIL = /<ferix:guardrail\s+severity="(warning|critical)"\s*>([\s\S]*?)<\/ferix:guardrail>/g;
4357
+ var PATTERN = /<pattern>([\s\S]*?)<\/pattern>/;
4358
+ var SIGN = /<sign>([\s\S]*?)<\/sign>/;
4359
+ var AVOIDANCE = /<avoidance>([\s\S]*?)<\/avoidance>/;
4360
+ var guardrailSpec = {
4361
+ tag: "Guardrail",
4362
+ closingTag: "</ferix:guardrail>",
4363
+ schema: GuardrailSignalSchema,
4364
+ parse: (text) => {
4365
+ const signals = [];
4366
+ const matches = text.matchAll(GUARDRAIL);
4367
+ for (const match of matches) {
4368
+ const severity = match[1];
4369
+ const content = match[2] || "";
4370
+ const patternMatch = content.match(PATTERN);
4371
+ const signMatch = content.match(SIGN);
4372
+ const avoidanceMatch = content.match(AVOIDANCE);
4373
+ const pattern = patternMatch?.[1]?.trim() || "";
4374
+ const sign = signMatch?.[1]?.trim() || "";
4375
+ const avoidance = avoidanceMatch?.[1]?.trim() || "";
4376
+ if (!(pattern && sign && avoidance)) {
4377
+ continue;
4378
+ }
4379
+ const raw = {
4380
+ _tag: "Guardrail",
4381
+ pattern,
4382
+ sign,
4383
+ avoidance,
4384
+ severity
4385
+ };
4386
+ const result = S17.decodeUnknownEither(GuardrailSignalSchema)(raw);
4387
+ if (result._tag === "Right") {
4388
+ signals.push(result.right);
4389
+ }
4390
+ }
4391
+ return signals;
4392
+ },
4393
+ keyFields: (s) => s.pattern.slice(0, 50)
4394
+ };
4395
+ signalSpecRegistry.register(guardrailSpec);
4396
+
4397
+ // src/layers/signal/specs/learning.ts
4398
+ init_esm_shims();
4399
+ import { Schema as S18 } from "effect";
4400
+ var LEARNING = /<ferix:learning(?:\s+category="(success|failure|optimization)")?\s*>([\s\S]*?)<\/ferix:learning>/g;
4401
+ var learningSpec = {
4402
+ tag: "Learning",
4403
+ closingTag: "</ferix:learning>",
4404
+ schema: LearningSignalSchema,
4405
+ parse: (text) => {
4406
+ const signals = [];
4407
+ const matches = text.matchAll(LEARNING);
4408
+ for (const match of matches) {
4409
+ const category = match[1];
4410
+ const content = match[2]?.trim() || "";
4411
+ if (!content) {
4412
+ continue;
4413
+ }
4414
+ const raw = {
4415
+ _tag: "Learning",
4416
+ content
4417
+ };
4418
+ if (category) {
4419
+ raw.category = category;
4420
+ }
4421
+ const result = S18.decodeUnknownEither(LearningSignalSchema)(raw);
4422
+ if (result._tag === "Right") {
4423
+ signals.push(result.right);
4424
+ }
4425
+ }
4426
+ return signals;
4427
+ },
4428
+ keyFields: (s) => s.content.slice(0, 50)
4429
+ };
4430
+ signalSpecRegistry.register(learningSpec);
4431
+
3823
4432
  // src/layers/signal/specs/loop-complete.ts
3824
4433
  init_esm_shims();
3825
- import { Schema as S15 } from "effect";
4434
+ import { Schema as S19 } from "effect";
3826
4435
  var LOOP_COMPLETE = /<ferix:complete>/;
3827
4436
  var loopCompleteSpec = {
3828
4437
  tag: "LoopComplete",
@@ -3831,7 +4440,7 @@ var loopCompleteSpec = {
3831
4440
  parse: (text) => {
3832
4441
  if (LOOP_COMPLETE.test(text)) {
3833
4442
  const raw = { _tag: "LoopComplete" };
3834
- const result = S15.decodeUnknownEither(LoopCompleteSignalSchema)(raw);
4443
+ const result = S19.decodeUnknownEither(LoopCompleteSignalSchema)(raw);
3835
4444
  if (result._tag === "Right") {
3836
4445
  return [result.right];
3837
4446
  }
@@ -3844,7 +4453,7 @@ signalSpecRegistry.register(loopCompleteSpec);
3844
4453
 
3845
4454
  // src/layers/signal/specs/phases.ts
3846
4455
  init_esm_shims();
3847
- import { Schema as S16 } from "effect";
4456
+ import { Schema as S20 } from "effect";
3848
4457
  var PHASES_BLOCK = /<ferix:phases task="(\d+)">([\s\S]*?)<\/ferix:phases>/;
3849
4458
  var PHASE = /<phase id="([\d.]+)">([^<]+)<\/phase>/g;
3850
4459
  var PHASE_START = /<ferix:phase-start id="([\d.]+)"\/>/g;
@@ -3877,7 +4486,7 @@ var phasesDefinedSpec = {
3877
4486
  taskId: match[1],
3878
4487
  phases
3879
4488
  };
3880
- const result = S16.decodeUnknownEither(PhasesDefinedSignalSchema)(raw);
4489
+ const result = S20.decodeUnknownEither(PhasesDefinedSignalSchema)(raw);
3881
4490
  if (result._tag === "Left") {
3882
4491
  return [];
3883
4492
  }
@@ -3894,7 +4503,7 @@ var phaseStartedSpec = {
3894
4503
  for (const m of text.matchAll(resetRegex2(PHASE_START))) {
3895
4504
  if (m[1]) {
3896
4505
  const raw = { _tag: "PhaseStarted", phaseId: m[1] };
3897
- const result = S16.decodeUnknownEither(PhaseStartedSignalSchema)(raw);
4506
+ const result = S20.decodeUnknownEither(PhaseStartedSignalSchema)(raw);
3898
4507
  if (result._tag === "Right") {
3899
4508
  signals.push(result.right);
3900
4509
  }
@@ -3913,7 +4522,7 @@ var phaseCompletedSpec = {
3913
4522
  for (const m of text.matchAll(resetRegex2(PHASE_DONE))) {
3914
4523
  if (m[1]) {
3915
4524
  const raw = { _tag: "PhaseCompleted", phaseId: m[1] };
3916
- const result = S16.decodeUnknownEither(PhaseCompletedSignalSchema)(raw);
4525
+ const result = S20.decodeUnknownEither(PhaseCompletedSignalSchema)(raw);
3917
4526
  if (result._tag === "Right") {
3918
4527
  signals.push(result.right);
3919
4528
  }
@@ -3936,7 +4545,7 @@ var phaseFailedSpec = {
3936
4545
  phaseId: m[1],
3937
4546
  reason: m[2] || "Unknown reason"
3938
4547
  };
3939
- const result = S16.decodeUnknownEither(PhaseFailedSignalSchema)(raw);
4548
+ const result = S20.decodeUnknownEither(PhaseFailedSignalSchema)(raw);
3940
4549
  if (result._tag === "Right") {
3941
4550
  signals.push(result.right);
3942
4551
  }
@@ -3953,7 +4562,7 @@ signalSpecRegistry.register(phaseFailedSpec);
3953
4562
 
3954
4563
  // src/layers/signal/specs/review.ts
3955
4564
  init_esm_shims();
3956
- import { Schema as S17 } from "effect";
4565
+ import { Schema as S21 } from "effect";
3957
4566
  var REVIEW_COMPLETE = /<ferix:review-complete\/>/;
3958
4567
  var REVIEW_CHANGES = /<ferix:review-changes-made\/>/;
3959
4568
  var reviewCompleteSpec = {
@@ -3966,7 +4575,7 @@ var reviewCompleteSpec = {
3966
4575
  }
3967
4576
  const changesMade = REVIEW_CHANGES.test(text);
3968
4577
  const raw = { _tag: "ReviewComplete", changesMade };
3969
- const result = S17.decodeUnknownEither(ReviewCompleteSignalSchema)(raw);
4578
+ const result = S21.decodeUnknownEither(ReviewCompleteSignalSchema)(raw);
3970
4579
  if (result._tag === "Right") {
3971
4580
  return [result.right];
3972
4581
  }
@@ -3978,7 +4587,7 @@ signalSpecRegistry.register(reviewCompleteSpec);
3978
4587
 
3979
4588
  // src/layers/signal/specs/task-complete.ts
3980
4589
  init_esm_shims();
3981
- import { Schema as S18 } from "effect";
4590
+ import { Schema as S22 } from "effect";
3982
4591
  var TASK_COMPLETE = /<ferix:task-complete id="(\d+)">([\s\S]*?)<\/ferix:task-complete>/;
3983
4592
  var SUMMARY = /<summary>([\s\S]*?)<\/summary>/;
3984
4593
  var FILES_MODIFIED = /<files-modified>([\s\S]*?)<\/files-modified>/;
@@ -4009,7 +4618,7 @@ var taskCompleteSpec = {
4009
4618
  filesModified: parseFileList(filesModifiedMatch?.[1]),
4010
4619
  filesCreated: parseFileList(filesCreatedMatch?.[1])
4011
4620
  };
4012
- const result = S18.decodeUnknownEither(TaskCompleteSignalSchema)(raw);
4621
+ const result = S22.decodeUnknownEither(TaskCompleteSignalSchema)(raw);
4013
4622
  if (result._tag === "Right") {
4014
4623
  return [result.right];
4015
4624
  }
@@ -4021,7 +4630,7 @@ signalSpecRegistry.register(taskCompleteSpec);
4021
4630
 
4022
4631
  // src/layers/signal/specs/tasks.ts
4023
4632
  init_esm_shims();
4024
- import { Schema as S19 } from "effect";
4633
+ import { Schema as S23 } from "effect";
4025
4634
  var TASKS_BLOCK = /<ferix:tasks>([\s\S]*?)<\/ferix:tasks>/;
4026
4635
  var TASK = /<task id="(\d+)">([^<]+)<\/task>/g;
4027
4636
  function resetRegex3(pattern) {
@@ -4051,7 +4660,7 @@ var tasksDefinedSpec = {
4051
4660
  return [];
4052
4661
  }
4053
4662
  const raw = { _tag: "TasksDefined", tasks };
4054
- const result = S19.decodeUnknownEither(TasksDefinedSignalSchema)(raw);
4663
+ const result = S23.decodeUnknownEither(TasksDefinedSignalSchema)(raw);
4055
4664
  if (result._tag === "Left") {
4056
4665
  return [];
4057
4666
  }
@@ -4064,20 +4673,20 @@ signalSpecRegistry.register(tasksDefinedSpec);
4064
4673
  // src/layers/signal/ferix-parser.ts
4065
4674
  var MAX_BUFFER_SIZE = 1024 * 1024;
4066
4675
  function createAccumulatorImpl() {
4067
- return Effect11.gen(function* () {
4068
- const chunksRef = yield* Ref5.make([]);
4069
- const emittedRef = yield* Ref5.make(/* @__PURE__ */ new Set());
4070
- const feed = (text) => Effect11.gen(function* () {
4071
- const chunks = yield* Ref5.get(chunksRef);
4676
+ return Effect15.gen(function* () {
4677
+ const chunksRef = yield* Ref7.make([]);
4678
+ const emittedRef = yield* Ref7.make(/* @__PURE__ */ new Set());
4679
+ const feed = (text) => Effect15.gen(function* () {
4680
+ const chunks = yield* Ref7.get(chunksRef);
4072
4681
  chunks.push(text);
4073
4682
  const buffer = chunks.join("");
4074
4683
  if (buffer.length > MAX_BUFFER_SIZE) {
4075
- yield* Ref5.set(chunksRef, [
4684
+ yield* Ref7.set(chunksRef, [
4076
4685
  buffer.slice(buffer.length - MAX_BUFFER_SIZE)
4077
4686
  ]);
4078
4687
  }
4079
4688
  const signals = signalSpecRegistry.parseAll(buffer);
4080
- const emitted = yield* Ref5.get(emittedRef);
4689
+ const emitted = yield* Ref7.get(emittedRef);
4081
4690
  const newSignals = signals.filter((signal) => {
4082
4691
  const key = signalSpecRegistry.getSignalKey(signal);
4083
4692
  if (emitted.has(key)) {
@@ -4089,55 +4698,61 @@ function createAccumulatorImpl() {
4089
4698
  if (newSignals.length > 0) {
4090
4699
  const lastEndPos = signalSpecRegistry.findLastCompleteSignalEnd(buffer);
4091
4700
  if (lastEndPos > 0 && lastEndPos < buffer.length) {
4092
- yield* Ref5.set(chunksRef, [buffer.slice(lastEndPos)]);
4701
+ yield* Ref7.set(chunksRef, [buffer.slice(lastEndPos)]);
4093
4702
  }
4094
4703
  }
4095
- yield* Ref5.set(emittedRef, emitted);
4704
+ yield* Ref7.set(emittedRef, emitted);
4096
4705
  return newSignals;
4097
4706
  });
4098
- const flush = () => Effect11.gen(function* () {
4099
- const chunks = yield* Ref5.get(chunksRef);
4707
+ const flush = () => Effect15.gen(function* () {
4708
+ const chunks = yield* Ref7.get(chunksRef);
4100
4709
  const buffer = chunks.join("");
4101
- yield* Ref5.set(chunksRef, []);
4102
- const emitted = yield* Ref5.get(emittedRef);
4710
+ yield* Ref7.set(chunksRef, []);
4711
+ const emitted = yield* Ref7.get(emittedRef);
4103
4712
  const signals = signalSpecRegistry.parseAll(buffer);
4104
4713
  const result = signals.filter(
4105
4714
  (signal) => !emitted.has(signalSpecRegistry.getSignalKey(signal))
4106
4715
  );
4107
- yield* Ref5.set(emittedRef, /* @__PURE__ */ new Set());
4716
+ yield* Ref7.set(emittedRef, /* @__PURE__ */ new Set());
4108
4717
  return result;
4109
4718
  });
4110
4719
  return { feed, flush };
4111
4720
  });
4112
4721
  }
4113
- var make4 = {
4114
- parse: (text) => Effect11.succeed(signalSpecRegistry.parseAll(text)),
4722
+ var make6 = {
4723
+ parse: (text) => Effect15.succeed(signalSpecRegistry.parseAll(text)),
4115
4724
  createAccumulator: createAccumulatorImpl
4116
4725
  };
4117
- var Live7 = Layer7.succeed(SignalParser, make4);
4726
+ var Live11 = Layer11.succeed(SignalParser, make6);
4118
4727
  var FerixParser = {
4119
- Live: Live7
4728
+ Live: Live11
4120
4729
  };
4121
4730
 
4122
4731
  // src/layers/index.ts
4123
- var ProductionLayers = Layer8.mergeAll(
4732
+ var ProductionLayers = Layer12.mergeAll(
4124
4733
  ClaudeCLI.Live,
4125
4734
  FerixParser.Live,
4126
4735
  FileSystemPlan.Live,
4127
- FileSystemSession.Live
4736
+ FileSystemSession.Live,
4737
+ FileSystemProgress.Live,
4738
+ FileSystemGuardrails.Live
4128
4739
  );
4129
- var TestLayers = Layer8.mergeAll(
4740
+ var TestLayers = Layer12.mergeAll(
4130
4741
  Mock.Live,
4131
4742
  FerixParser.Live,
4132
4743
  MemoryPlan.Live,
4133
- MemorySession.Live
4744
+ MemorySession.Live,
4745
+ MemoryProgress.Live,
4746
+ MemoryGuardrails.Live
4134
4747
  );
4135
4748
  function createTestLayers(events) {
4136
- return Layer8.mergeAll(
4749
+ return Layer12.mergeAll(
4137
4750
  Mock.layer({ events }),
4138
4751
  FerixParser.Live,
4139
4752
  MemoryPlan.layer(),
4140
- MemorySession.layer()
4753
+ MemorySession.layer(),
4754
+ MemoryProgress.layer(),
4755
+ MemoryGuardrails.layer()
4141
4756
  );
4142
4757
  }
4143
4758
 
@@ -4146,42 +4761,42 @@ init_esm_shims();
4146
4761
 
4147
4762
  // src/orchestrator/loop.ts
4148
4763
  init_esm_shims();
4149
- import { DateTime as DateTime6, Effect as Effect16, Option, pipe as pipe3, Ref as Ref9, Stream as Stream9 } from "effect";
4764
+ import { DateTime as DateTime10, Effect as Effect20, Option, pipe as pipe3, Ref as Ref11, Stream as Stream9 } from "effect";
4150
4765
 
4151
4766
  // src/orchestrator/discovery.ts
4152
4767
  init_esm_shims();
4153
- import { DateTime as DateTime4, Effect as Effect14, pipe, Ref as Ref7, Stream as Stream7 } from "effect";
4768
+ import { DateTime as DateTime8, Effect as Effect18, pipe, Ref as Ref9, Stream as Stream7 } from "effect";
4154
4769
 
4155
4770
  // src/layers/plan/task-generation.ts
4156
4771
  init_esm_shims();
4157
- import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
4158
- import { join as join3 } from "path";
4159
- import { Effect as Effect12 } from "effect";
4160
- var PLANS_DIR2 = ".ferix/plans";
4161
- function ensureDir3(dirPath) {
4162
- return Effect12.tryPromise({
4163
- try: () => mkdir3(dirPath, { recursive: true }),
4772
+ import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
4773
+ import { join as join5 } from "path";
4774
+ import { Effect as Effect16 } from "effect";
4775
+ var PLANS_DIR4 = ".ferix/plans";
4776
+ function ensureDir5(dirPath) {
4777
+ return Effect16.tryPromise({
4778
+ try: () => mkdir5(dirPath, { recursive: true }),
4164
4779
  catch: (error) => new PlanStoreError({
4165
4780
  message: `Failed to create directory: ${dirPath}`,
4166
4781
  operation: "create",
4167
4782
  cause: error
4168
4783
  })
4169
- }).pipe(Effect12.asVoid);
4784
+ }).pipe(Effect16.asVoid);
4170
4785
  }
4171
- function getSessionDir2(sessionId) {
4172
- return join3(process.cwd(), PLANS_DIR2, sessionId);
4786
+ function getSessionDir4(sessionId) {
4787
+ return join5(process.cwd(), PLANS_DIR4, sessionId);
4173
4788
  }
4174
4789
  function getTasksMdPath(sessionId) {
4175
- return join3(getSessionDir2(sessionId), "tasks.md");
4790
+ return join5(getSessionDir4(sessionId), "tasks.md");
4176
4791
  }
4177
4792
  function writeTasksMd(sessionId, tasks) {
4178
- return Effect12.gen(function* () {
4179
- const sessionDir = getSessionDir2(sessionId);
4180
- yield* ensureDir3(sessionDir);
4793
+ return Effect16.gen(function* () {
4794
+ const sessionDir = getSessionDir4(sessionId);
4795
+ yield* ensureDir5(sessionDir);
4181
4796
  const tasksMdPath = getTasksMdPath(sessionId);
4182
4797
  const content = formatTasksMd(tasks);
4183
- yield* Effect12.tryPromise({
4184
- try: () => writeFile3(tasksMdPath, content, "utf-8"),
4798
+ yield* Effect16.tryPromise({
4799
+ try: () => writeFile5(tasksMdPath, content, "utf-8"),
4185
4800
  catch: (error) => new PlanStoreError({
4186
4801
  message: `Failed to write tasks.md: ${tasksMdPath}`,
4187
4802
  operation: "create",
@@ -4325,6 +4940,32 @@ eventMappingRegistry.registerSignalMapper({
4325
4940
  }
4326
4941
  })
4327
4942
  });
4943
+ eventMappingRegistry.registerSignalMapper({
4944
+ tag: "Learning",
4945
+ map: (signal, context) => ({
4946
+ _tag: "LearningRecorded",
4947
+ iteration: 0,
4948
+ // Will be overwritten by iteration stream
4949
+ content: signal.content,
4950
+ category: signal.category,
4951
+ timestamp: context.timestamp
4952
+ })
4953
+ });
4954
+ eventMappingRegistry.registerSignalMapper({
4955
+ tag: "Guardrail",
4956
+ map: (signal, context) => ({
4957
+ _tag: "GuardrailAdded",
4958
+ id: `gr-pending-${context.timestamp}`,
4959
+ // Temp ID, real one assigned in iteration
4960
+ iteration: 0,
4961
+ // Will be overwritten by iteration stream
4962
+ pattern: signal.pattern,
4963
+ sign: signal.sign,
4964
+ avoidance: signal.avoidance,
4965
+ severity: signal.severity,
4966
+ timestamp: context.timestamp
4967
+ })
4968
+ });
4328
4969
 
4329
4970
  // src/orchestrator/mapping/index.ts
4330
4971
  function mapLLMEventToDomain(event, context) {
@@ -4336,7 +4977,7 @@ function mapSignalToDomain(signal, context) {
4336
4977
 
4337
4978
  // src/orchestrator/plan-updates.ts
4338
4979
  init_esm_shims();
4339
- import { DateTime as DateTime3, Effect as Effect13, Ref as Ref6 } from "effect";
4980
+ import { DateTime as DateTime7, Effect as Effect17, Ref as Ref8 } from "effect";
4340
4981
 
4341
4982
  // src/orchestrator/plan-updates/index.ts
4342
4983
  init_esm_shims();
@@ -4548,6 +5189,20 @@ planUpdateRegistry.register({
4548
5189
  } : void 0
4549
5190
  });
4550
5191
 
5192
+ // src/orchestrator/plan-updates/handlers/guardrail.ts
5193
+ init_esm_shims();
5194
+ planUpdateRegistry.register({
5195
+ tag: "Guardrail",
5196
+ handle: (_signal, _currentPlan, _context) => void 0
5197
+ });
5198
+
5199
+ // src/orchestrator/plan-updates/handlers/learning.ts
5200
+ init_esm_shims();
5201
+ planUpdateRegistry.register({
5202
+ tag: "Learning",
5203
+ handle: (_signal, _currentPlan, _context) => void 0
5204
+ });
5205
+
4551
5206
  // src/orchestrator/plan-updates/handlers/phase-lifecycle.ts
4552
5207
  init_esm_shims();
4553
5208
  planUpdateRegistry.register({
@@ -4627,9 +5282,9 @@ function persistPlanUpdate(planStore, plan, operation) {
4627
5282
  tasks: plan.tasks
4628
5283
  }) : planStore.update(plan.id, plan);
4629
5284
  return storeOp.pipe(
4630
- Effect13.map(() => null),
4631
- Effect13.catchAll(
4632
- (error) => Effect13.succeed({
5285
+ Effect17.map(() => null),
5286
+ Effect17.catchAll(
5287
+ (error) => Effect17.succeed({
4633
5288
  _tag: "PlanUpdateFailed",
4634
5289
  operation,
4635
5290
  error: error.message,
@@ -4639,10 +5294,10 @@ function persistPlanUpdate(planStore, plan, operation) {
4639
5294
  );
4640
5295
  }
4641
5296
  function updatePlanFromSignal(currentPlanRef, persistenceStateRef, signal, sessionId, originalTask) {
4642
- return Effect13.gen(function* () {
4643
- const currentPlan = yield* Ref6.get(currentPlanRef);
4644
- const now = yield* DateTime3.now;
4645
- const timestamp = DateTime3.formatIso(now);
5297
+ return Effect17.gen(function* () {
5298
+ const currentPlan = yield* Ref8.get(currentPlanRef);
5299
+ const now = yield* DateTime7.now;
5300
+ const timestamp = DateTime7.formatIso(now);
4646
5301
  const updateResult = computePlanUpdate(signal, currentPlan, {
4647
5302
  sessionId,
4648
5303
  originalTask,
@@ -4652,8 +5307,8 @@ function updatePlanFromSignal(currentPlanRef, persistenceStateRef, signal, sessi
4652
5307
  return [];
4653
5308
  }
4654
5309
  const { plan, operation, eventTag } = updateResult;
4655
- yield* Ref6.set(currentPlanRef, plan);
4656
- yield* Ref6.update(persistenceStateRef, (state) => ({
5310
+ yield* Ref8.set(currentPlanRef, plan);
5311
+ yield* Ref8.update(persistenceStateRef, (state) => ({
4657
5312
  dirty: true,
4658
5313
  pendingOperation: state.pendingOperation === "create" ? "create" : operation
4659
5314
  }));
@@ -4661,12 +5316,12 @@ function updatePlanFromSignal(currentPlanRef, persistenceStateRef, signal, sessi
4661
5316
  });
4662
5317
  }
4663
5318
  function flushPlanPersistence(planStore, currentPlanRef, persistenceStateRef) {
4664
- return Effect13.gen(function* () {
4665
- const state = yield* Ref6.get(persistenceStateRef);
5319
+ return Effect17.gen(function* () {
5320
+ const state = yield* Ref8.get(persistenceStateRef);
4666
5321
  if (!(state.dirty && state.pendingOperation)) {
4667
5322
  return [];
4668
5323
  }
4669
- const plan = yield* Ref6.get(currentPlanRef);
5324
+ const plan = yield* Ref8.get(currentPlanRef);
4670
5325
  if (!plan) {
4671
5326
  return [];
4672
5327
  }
@@ -4679,7 +5334,7 @@ function flushPlanPersistence(planStore, currentPlanRef, persistenceStateRef) {
4679
5334
  if (failureEvent) {
4680
5335
  events.push(failureEvent);
4681
5336
  }
4682
- yield* Ref6.set(persistenceStateRef, {
5337
+ yield* Ref8.set(persistenceStateRef, {
4683
5338
  dirty: false,
4684
5339
  pendingOperation: null
4685
5340
  });
@@ -4929,12 +5584,12 @@ Begin.`);
4929
5584
 
4930
5585
  // src/orchestrator/discovery.ts
4931
5586
  function processTextSignals(signalParser, text, context) {
4932
- return Effect14.gen(function* () {
5587
+ return Effect18.gen(function* () {
4933
5588
  const events = [];
4934
5589
  const parsedSignals = [];
4935
5590
  const signals = yield* signalParser.parse(text).pipe(
4936
- Effect14.tapError(
4937
- (error) => Effect14.logDebug(
5591
+ Effect18.tapError(
5592
+ (error) => Effect18.logDebug(
4938
5593
  "Signal parsing failed, continuing with empty signals",
4939
5594
  {
4940
5595
  error: String(error),
@@ -4942,7 +5597,7 @@ function processTextSignals(signalParser, text, context) {
4942
5597
  }
4943
5598
  )
4944
5599
  ),
4945
- Effect14.orElseSucceed(() => [])
5600
+ Effect18.orElseSucceed(() => [])
4946
5601
  );
4947
5602
  for (const signal of signals) {
4948
5603
  events.push(mapSignalToDomain(signal, context));
@@ -4952,7 +5607,7 @@ function processTextSignals(signalParser, text, context) {
4952
5607
  });
4953
5608
  }
4954
5609
  function processLLMEvent(signalParser, llmEvent, context) {
4955
- return Effect14.gen(function* () {
5610
+ return Effect18.gen(function* () {
4956
5611
  const domainEvent = mapLLMEventToDomain(llmEvent, context);
4957
5612
  const events = [domainEvent];
4958
5613
  const allSignals = [];
@@ -4997,10 +5652,10 @@ function planTasksToGeneratedTasks(plan) {
4997
5652
  }
4998
5653
  function createDiscoveryStream(llm, signalParser, planStore, currentPlanRef, config, sessionId) {
4999
5654
  return Stream7.unwrap(
5000
- Effect14.gen(function* () {
5001
- const startTimeUtc = yield* DateTime4.now;
5002
- const startTime = DateTime4.toEpochMillis(startTimeUtc);
5003
- const persistenceStateRef = yield* Ref7.make({
5655
+ Effect18.gen(function* () {
5656
+ const startTimeUtc = yield* DateTime8.now;
5657
+ const startTime = DateTime8.toEpochMillis(startTimeUtc);
5658
+ const persistenceStateRef = yield* Ref9.make({
5004
5659
  dirty: false,
5005
5660
  pendingOperation: null
5006
5661
  });
@@ -5024,10 +5679,10 @@ function createDiscoveryStream(llm, signalParser, planStore, currentPlanRef, con
5024
5679
  ),
5025
5680
  Stream7.flatMap(
5026
5681
  (llmEvent) => Stream7.unwrap(
5027
- Effect14.gen(function* () {
5028
- const now = yield* DateTime4.now;
5682
+ Effect18.gen(function* () {
5683
+ const now = yield* DateTime8.now;
5029
5684
  const context = {
5030
- timestamp: DateTime4.toEpochMillis(now)
5685
+ timestamp: DateTime8.toEpochMillis(now)
5031
5686
  };
5032
5687
  const result = yield* processLLMEvent(
5033
5688
  signalParser,
@@ -5061,27 +5716,27 @@ function createDiscoveryStream(llm, signalParser, planStore, currentPlanRef, con
5061
5716
  )
5062
5717
  );
5063
5718
  const completionStream = Stream7.fromEffect(
5064
- Effect14.gen(function* () {
5719
+ Effect18.gen(function* () {
5065
5720
  const persistEvents = yield* flushPlanPersistence(
5066
5721
  planStore,
5067
5722
  currentPlanRef,
5068
5723
  persistenceStateRef
5069
5724
  );
5070
- const plan = yield* Ref7.get(currentPlanRef);
5725
+ const plan = yield* Ref9.get(currentPlanRef);
5071
5726
  const taskCount = plan?.tasks.length ?? 0;
5072
5727
  if (plan && plan.tasks.length > 0) {
5073
5728
  const generatedTasks = planTasksToGeneratedTasks(plan);
5074
5729
  yield* writeTasksMd(sessionId, generatedTasks).pipe(
5075
- Effect14.tapError(
5076
- (error) => Effect14.logDebug("Failed to write tasks.md, continuing", {
5730
+ Effect18.tapError(
5731
+ (error) => Effect18.logDebug("Failed to write tasks.md, continuing", {
5077
5732
  error: String(error)
5078
5733
  })
5079
5734
  ),
5080
- Effect14.orElseSucceed(() => void 0)
5735
+ Effect18.orElseSucceed(() => void 0)
5081
5736
  );
5082
5737
  }
5083
- const endTimeUtc = yield* DateTime4.now;
5084
- const endTime = DateTime4.toEpochMillis(endTimeUtc);
5738
+ const endTimeUtc = yield* DateTime8.now;
5739
+ const endTime = DateTime8.toEpochMillis(endTimeUtc);
5085
5740
  const discoveryCompleted = {
5086
5741
  _tag: "DiscoveryCompleted",
5087
5742
  taskCount,
@@ -5102,15 +5757,15 @@ function createDiscoveryStream(llm, signalParser, planStore, currentPlanRef, con
5102
5757
 
5103
5758
  // src/orchestrator/iteration.ts
5104
5759
  init_esm_shims();
5105
- import { DateTime as DateTime5, Effect as Effect15, pipe as pipe2, Ref as Ref8, Stream as Stream8 } from "effect";
5760
+ import { DateTime as DateTime9, Effect as Effect19, pipe as pipe2, Ref as Ref10, Stream as Stream8 } from "effect";
5106
5761
  function processTextSignals2(signalParser, text, context) {
5107
- return Effect15.gen(function* () {
5762
+ return Effect19.gen(function* () {
5108
5763
  const events = [];
5109
5764
  let completed = false;
5110
5765
  const parsedSignals = [];
5111
5766
  const signals = yield* signalParser.parse(text).pipe(
5112
- Effect15.tapError(
5113
- (error) => Effect15.logDebug(
5767
+ Effect19.tapError(
5768
+ (error) => Effect19.logDebug(
5114
5769
  "Signal parsing failed, continuing with empty signals",
5115
5770
  {
5116
5771
  error: String(error),
@@ -5118,7 +5773,7 @@ function processTextSignals2(signalParser, text, context) {
5118
5773
  }
5119
5774
  )
5120
5775
  ),
5121
- Effect15.orElseSucceed(() => [])
5776
+ Effect19.orElseSucceed(() => [])
5122
5777
  );
5123
5778
  for (const signal of signals) {
5124
5779
  events.push(mapSignalToDomain(signal, context));
@@ -5131,7 +5786,7 @@ function processTextSignals2(signalParser, text, context) {
5131
5786
  });
5132
5787
  }
5133
5788
  function processLLMEvent2(signalParser, llmEvent, context) {
5134
- return Effect15.gen(function* () {
5789
+ return Effect19.gen(function* () {
5135
5790
  const domainEvent = mapLLMEventToDomain(llmEvent, context);
5136
5791
  const events = [domainEvent];
5137
5792
  let completed = false;
@@ -5164,9 +5819,9 @@ function processLLMEvent2(signalParser, llmEvent, context) {
5164
5819
  }
5165
5820
  function createIterationStream(llm, signalParser, planStore, currentPlanRef, loopCompletedRef, config, iteration, sessionId) {
5166
5821
  return Stream8.unwrap(
5167
- Effect15.gen(function* () {
5168
- const currentPlan = yield* Ref8.get(currentPlanRef);
5169
- const persistenceStateRef = yield* Ref8.make({
5822
+ Effect19.gen(function* () {
5823
+ const currentPlan = yield* Ref10.get(currentPlanRef);
5824
+ const persistenceStateRef = yield* Ref10.make({
5170
5825
  dirty: false,
5171
5826
  pendingOperation: null
5172
5827
  });
@@ -5184,10 +5839,10 @@ function createIterationStream(llm, signalParser, planStore, currentPlanRef, loo
5184
5839
  ),
5185
5840
  Stream8.flatMap(
5186
5841
  (llmEvent) => Stream8.unwrap(
5187
- Effect15.gen(function* () {
5188
- const now = yield* DateTime5.now;
5842
+ Effect19.gen(function* () {
5843
+ const now = yield* DateTime9.now;
5189
5844
  const context = {
5190
- timestamp: DateTime5.toEpochMillis(now)
5845
+ timestamp: DateTime9.toEpochMillis(now)
5191
5846
  };
5192
5847
  const result = yield* processLLMEvent2(
5193
5848
  signalParser,
@@ -5206,7 +5861,7 @@ function createIterationStream(llm, signalParser, planStore, currentPlanRef, loo
5206
5861
  events.push(...planEvents);
5207
5862
  }
5208
5863
  if (result.completed) {
5209
- yield* Ref8.set(loopCompletedRef, true);
5864
+ yield* Ref10.set(loopCompletedRef, true);
5210
5865
  }
5211
5866
  return Stream8.fromIterable(events);
5212
5867
  })
@@ -5225,7 +5880,7 @@ function createIterationStream(llm, signalParser, planStore, currentPlanRef, loo
5225
5880
  )
5226
5881
  );
5227
5882
  const completionStream = Stream8.fromEffect(
5228
- Effect15.gen(function* () {
5883
+ Effect19.gen(function* () {
5229
5884
  const persistEvents = yield* flushPlanPersistence(
5230
5885
  planStore,
5231
5886
  currentPlanRef,
@@ -5250,13 +5905,13 @@ function createIterationStream(llm, signalParser, planStore, currentPlanRef, loo
5250
5905
  // src/orchestrator/loop.ts
5251
5906
  function runLoop(config) {
5252
5907
  return Stream9.unwrap(
5253
- Effect16.gen(function* () {
5908
+ Effect20.gen(function* () {
5254
5909
  const llm = yield* LLM;
5255
5910
  const signalParser = yield* SignalParser;
5256
5911
  const sessionStore = yield* SessionStore;
5257
5912
  const planStore = yield* PlanStore;
5258
5913
  const session = yield* sessionStore.create(config.task).pipe(
5259
- Effect16.mapError(
5914
+ Effect20.mapError(
5260
5915
  (e) => new OrchestratorError({
5261
5916
  message: `Failed to create session: ${e.message}`,
5262
5917
  phase: "setup",
@@ -5264,10 +5919,10 @@ function runLoop(config) {
5264
5919
  })
5265
5920
  )
5266
5921
  );
5267
- const startTimeUtc = yield* DateTime6.now;
5268
- const startTime = DateTime6.toEpochMillis(startTimeUtc);
5269
- const loopCompletedRef = yield* Ref9.make(false);
5270
- const currentPlanRef = yield* Ref9.make(void 0);
5922
+ const startTimeUtc = yield* DateTime10.now;
5923
+ const startTime = DateTime10.toEpochMillis(startTimeUtc);
5924
+ const loopCompletedRef = yield* Ref11.make(false);
5925
+ const currentPlanRef = yield* Ref11.make(void 0);
5271
5926
  const maxIterations = config.maxIterations === 0 ? Number.POSITIVE_INFINITY : config.maxIterations;
5272
5927
  const loopStarted = {
5273
5928
  _tag: "LoopStarted",
@@ -5284,8 +5939,8 @@ function runLoop(config) {
5284
5939
  );
5285
5940
  const iterationsStream = Stream9.unfoldEffect(
5286
5941
  1,
5287
- (iteration) => Effect16.gen(function* () {
5288
- const completed = yield* Ref9.get(loopCompletedRef);
5942
+ (iteration) => Effect20.gen(function* () {
5943
+ const completed = yield* Ref11.get(loopCompletedRef);
5289
5944
  if (completed || iteration > maxIterations) {
5290
5945
  return Option.none();
5291
5946
  }
@@ -5320,8 +5975,8 @@ function runLoop(config) {
5320
5975
  );
5321
5976
  }).pipe(
5322
5977
  // Also catch setup errors (e.g., session creation failure)
5323
- Effect16.catchAll(
5324
- (error) => Effect16.succeed(
5978
+ Effect20.catchAll(
5979
+ (error) => Effect20.succeed(
5325
5980
  Stream9.succeed({
5326
5981
  _tag: "LoopFailed",
5327
5982
  error: {
@@ -5336,10 +5991,10 @@ function runLoop(config) {
5336
5991
  }
5337
5992
  function createCompletionStream(sessionStore, session, config, startTime, loopCompletedRef) {
5338
5993
  return Stream9.fromEffect(
5339
- Effect16.gen(function* () {
5340
- const endTimeUtc = yield* DateTime6.now;
5341
- const durationMs = DateTime6.toEpochMillis(endTimeUtc) - startTime;
5342
- const completed = yield* Ref9.get(loopCompletedRef);
5994
+ Effect20.gen(function* () {
5995
+ const endTimeUtc = yield* DateTime10.now;
5996
+ const durationMs = DateTime10.toEpochMillis(endTimeUtc) - startTime;
5997
+ const completed = yield* Ref11.get(loopCompletedRef);
5343
5998
  const summary = {
5344
5999
  iterations: config.maxIterations,
5345
6000
  success: completed,
@@ -5351,13 +6006,13 @@ function createCompletionStream(sessionStore, session, config, startTime, loopCo
5351
6006
  ...session,
5352
6007
  status: completed ? "completed" : "paused"
5353
6008
  }).pipe(
5354
- Effect16.tapError(
5355
- (error) => Effect16.logDebug("Session update failed, continuing", {
6009
+ Effect20.tapError(
6010
+ (error) => Effect20.logDebug("Session update failed, continuing", {
5356
6011
  sessionId: session.id,
5357
6012
  error: String(error)
5358
6013
  })
5359
6014
  ),
5360
- Effect16.orElseSucceed(() => void 0)
6015
+ Effect20.orElseSucceed(() => void 0)
5361
6016
  );
5362
6017
  const event = { _tag: "LoopCompleted", summary };
5363
6018
  return event;
@@ -5369,7 +6024,7 @@ function createCompletionStream(sessionStore, session, config, startTime, loopCo
5369
6024
  function run(options) {
5370
6025
  const { config, consumer: consumerType = "headless", onEvent } = options;
5371
6026
  const events = runLoop(config);
5372
- const eventsWithCallback = onEvent ? events.pipe(Stream10.tap((event) => Effect17.sync(() => onEvent(event)))) : events;
6027
+ const eventsWithCallback = onEvent ? events.pipe(Stream10.tap((event) => Effect21.sync(() => onEvent(event)))) : events;
5373
6028
  const eventsWithLayers = eventsWithCallback.pipe(
5374
6029
  Stream10.provideLayer(ProductionLayers)
5375
6030
  );
@@ -5382,7 +6037,7 @@ function run(options) {
5382
6037
  function runTest(options, mockEvents) {
5383
6038
  const { config, onEvent } = options;
5384
6039
  const events = runLoop(config);
5385
- const eventsWithCallback = onEvent ? events.pipe(Stream10.tap((event) => Effect17.sync(() => onEvent(event)))) : events;
6040
+ const eventsWithCallback = onEvent ? events.pipe(Stream10.tap((event) => Effect21.sync(() => onEvent(event)))) : events;
5386
6041
  const layers = mockEvents ? createTestLayers(mockEvents) : TestLayers;
5387
6042
  const eventsWithLayers = eventsWithCallback.pipe(Stream10.provideLayer(layers));
5388
6043
  return eventsWithLayers.pipe(Stream10.runDrain);
@@ -5390,11 +6045,11 @@ function runTest(options, mockEvents) {
5390
6045
  function collectEvents(config, mockEvents) {
5391
6046
  const events = runLoop(config);
5392
6047
  const layers = mockEvents ? createTestLayers(mockEvents) : TestLayers;
5393
- return events.pipe(Stream10.provideLayer(layers), Stream10.runCollect).pipe(Effect17.map((chunk) => Array.from(chunk)));
6048
+ return events.pipe(Stream10.provideLayer(layers), Stream10.runCollect).pipe(Effect21.map((chunk) => Array.from(chunk)));
5394
6049
  }
5395
6050
  function main(config) {
5396
6051
  const consumerType = process.stdout.isTTY ? "tui" : "headless";
5397
- return run({ config, consumer: consumerType }).pipe(Effect17.runPromise);
6052
+ return run({ config, consumer: consumerType }).pipe(Effect21.runPromise);
5398
6053
  }
5399
6054
 
5400
6055
  // src/services/index.ts
@@ -5447,11 +6102,20 @@ export {
5447
6102
  ExecutionModeSchema,
5448
6103
  FerixParser,
5449
6104
  FileLoggerConfigSchema,
6105
+ FileSystemGuardrails,
5450
6106
  FileSystemPlan,
6107
+ FileSystemProgress,
5451
6108
  FileSystemSession,
5452
6109
  GeneratedTaskListSchema,
5453
6110
  GeneratedTaskSchema,
5454
6111
  GeneratedTaskStatusSchema,
6112
+ GuardrailAddedEventSchema,
6113
+ GuardrailSchema,
6114
+ GuardrailSeveritySchema,
6115
+ GuardrailSignalSchema,
6116
+ GuardrailsFileSchema,
6117
+ GuardrailsStore,
6118
+ GuardrailsStoreError,
5455
6119
  IterationCompletedEventSchema,
5456
6120
  IterationStartedEventSchema,
5457
6121
  LLM,
@@ -5461,6 +6125,9 @@ export {
5461
6125
  LLMToolEndEventSchema,
5462
6126
  LLMToolStartEventSchema,
5463
6127
  LLMToolUseEventSchema,
6128
+ LearningCategorySchema,
6129
+ LearningRecordedEventSchema,
6130
+ LearningSignalSchema,
5464
6131
  LogEntrySchema,
5465
6132
  LogLevelSchema,
5466
6133
  LoopCompleteSignalSchema,
@@ -5471,7 +6138,9 @@ export {
5471
6138
  LoopStartedEventSchema,
5472
6139
  LoopStatusSchema,
5473
6140
  LoopSummarySchema,
6141
+ MemoryGuardrails,
5474
6142
  MemoryPlan,
6143
+ MemoryProgress,
5475
6144
  MemorySession,
5476
6145
  Mock,
5477
6146
  Mock as MockLLM,
@@ -5501,6 +6170,12 @@ export {
5501
6170
  PlanUpdateFailedEventSchema,
5502
6171
  PlanUpdatedEventSchema,
5503
6172
  ProductionLayers,
6173
+ ProgressActionSchema,
6174
+ ProgressEntrySchema,
6175
+ ProgressFileSchema,
6176
+ ProgressStore,
6177
+ ProgressStoreError,
6178
+ ProgressUpdatedEventSchema,
5504
6179
  PromptConfigSchema,
5505
6180
  ReviewCompleteDataSchema,
5506
6181
  ReviewCompleteEventSchema,
@@ -5540,10 +6215,14 @@ export {
5540
6215
  createHeadlessConsumer,
5541
6216
  createTUIConsumer,
5542
6217
  createTestLayers,
6218
+ decodeGuardrail,
6219
+ decodeGuardrailsFile,
5543
6220
  decodeLLMEvent,
5544
6221
  decodeLoopConfig,
5545
6222
  decodePlan,
5546
6223
  decodePlanData,
6224
+ decodeProgressEntry,
6225
+ decodeProgressFile,
5547
6226
  decodeSession,
5548
6227
  decodeSignal,
5549
6228
  decodeSignalSync,