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