ferix-code 0.0.2-beta.3 → 0.0.2-beta.5

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