@bike4mind/cli 0.3.0 → 0.4.0

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.
@@ -1930,7 +1930,14 @@ const SceneCommandSchema = z.discriminatedUnion("type", [
1930
1930
  row: z.number(),
1931
1931
  gid: z.number()
1932
1932
  })),
1933
- worldVersion: z.number().optional()
1933
+ worldVersion: z.number().optional(),
1934
+ floorId: z.string().optional()
1935
+ }),
1936
+ z.object({
1937
+ type: z.literal("change_floor"),
1938
+ id: z.string(),
1939
+ floorId: z.string(),
1940
+ position: TilePositionSchema
1934
1941
  }),
1935
1942
  z.object({
1936
1943
  type: z.literal("update_metadata"),
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as version, n as fetchLatestVersion, r as forceCheckForUpdate } from "../updateChecker-CEeSpbaK.mjs";
2
+ import { i as version, n as fetchLatestVersion, r as forceCheckForUpdate } from "../updateChecker-DcJC1C8S.mjs";
3
3
  import { execSync } from "child_process";
4
4
  import { constants, existsSync, promises } from "fs";
5
5
  import { homedir } from "os";
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { B as ReActAgent, C as loadContextFiles, D as generateCliTools, E as PermissionManager, F as setWebSocketToolExecutor, H as CheckpointStore, L as buildCoreSystemPrompt, V as CustomCommandStore, W as SessionStore, _ as WebSocketLlmBackend, a as createCoordinateTaskTool, c as createAgentDelegateTool, d as createSkillTool, g as FallbackLlmBackend, h as WebSocketConnectionManager, i as createWriteTodosTool, l as AgentStore, m as WebSocketToolExecutor, n as createFindDefinitionTool, o as createBackgroundAgentTools, p as ApiClient, r as createTodoStore, s as BackgroundAgentManager, t as createGetFileStructureTool, u as SubagentOrchestrator, v as ServerLlmBackend, w as getApiUrl, y as McpManager, z as isReadOnlyTool } from "../tools-BImjpPlR.mjs";
3
- import { n as logger, t as ConfigStore } from "../ConfigStore-o5AblHqQ.mjs";
2
+ import { B as ReActAgent, C as loadContextFiles, D as generateCliTools, E as PermissionManager, F as setWebSocketToolExecutor, H as CheckpointStore, L as buildCoreSystemPrompt, V as CustomCommandStore, W as SessionStore, _ as WebSocketLlmBackend, a as createCoordinateTaskTool, c as createAgentDelegateTool, d as createSkillTool, g as FallbackLlmBackend, h as WebSocketConnectionManager, i as createWriteTodosTool, l as AgentStore, m as WebSocketToolExecutor, n as createFindDefinitionTool, o as createBackgroundAgentTools, p as ApiClient, r as createTodoStore, s as BackgroundAgentManager, t as createGetFileStructureTool, u as SubagentOrchestrator, v as ServerLlmBackend, w as getApiUrl, y as McpManager, z as isReadOnlyTool } from "../tools-DiSJh1Dv.mjs";
3
+ import { n as logger, t as ConfigStore } from "../ConfigStore-DBUmvCfe.mjs";
4
4
  import { t as DEFAULT_SANDBOX_CONFIG } from "../types-DBEjF9YS.mjs";
5
5
  import { t as createSandboxRuntime } from "../SandboxRuntimeAdapter-C1B4t20N.mjs";
6
6
  import { t as SandboxOrchestrator } from "../SandboxOrchestrator-BEW3rqYi.mjs";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as ConfigStore } from "../ConfigStore-o5AblHqQ.mjs";
2
+ import { t as ConfigStore } from "../ConfigStore-DBUmvCfe.mjs";
3
3
  //#region src/commands/mcpCommand.ts
4
4
  /**
5
5
  * External MCP commands (b4m mcp list, b4m mcp add, etc.)
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as version, r as forceCheckForUpdate } from "../updateChecker-CEeSpbaK.mjs";
2
+ import { i as version, r as forceCheckForUpdate } from "../updateChecker-DcJC1C8S.mjs";
3
3
  import { execSync } from "child_process";
4
4
  //#region src/commands/updateCommand.ts
5
5
  /**
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as useCliStore, t as selectActiveBackgroundAgents } from "./store-B7-LLvvx.mjs";
3
- import { A as DEFAULT_MAX_ITERATIONS, B as ReActAgent, C as loadContextFiles, D as generateCliTools, E as PermissionManager, F as setWebSocketToolExecutor, G as OAuthClient, H as CheckpointStore, I as OllamaBackend, J as searchCommands, K as hasFileReferences, L as buildCoreSystemPrompt, M as DEFAULT_THOROUGHNESS, N as clearFeatureModuleTools, O as ALWAYS_DENIED_FOR_AGENTS, P as registerFeatureModuleTools, Q as warmFileCache, R as buildSkillsPromptSection, S as extractCompactInstructions, T as getEnvironmentName, U as CommandHistoryStore, V as CustomCommandStore, W as SessionStore, X as formatFileSize, Y as mergeCommands, Z as searchFiles, _ as WebSocketLlmBackend, a as createCoordinateTaskTool, b as substituteArguments, c as createAgentDelegateTool, d as createSkillTool, f as parseAgentConfig, g as FallbackLlmBackend, h as WebSocketConnectionManager, i as createWriteTodosTool, j as DEFAULT_RETRY_CONFIG, k as DEFAULT_AGENT_MODEL, l as AgentStore, m as WebSocketToolExecutor, n as createFindDefinitionTool, o as createBackgroundAgentTools, p as ApiClient, q as processFileReferences, r as createTodoStore, s as BackgroundAgentManager, t as createGetFileStructureTool, u as SubagentOrchestrator, v as ServerLlmBackend, w as getApiUrl, x as formatStep, y as McpManager, z as isReadOnlyTool } from "./tools-BImjpPlR.mjs";
4
- import { Mt as validateNotebookPath$1, g as ChatModels, jt as validateJupyterKernelName, m as CREDIT_DEDUCT_TRANSACTION_TYPES, n as logger, t as ConfigStore } from "./ConfigStore-o5AblHqQ.mjs";
5
- import { i as version, t as checkForUpdate } from "./updateChecker-CEeSpbaK.mjs";
3
+ import { A as DEFAULT_MAX_ITERATIONS, B as ReActAgent, C as loadContextFiles, D as generateCliTools, E as PermissionManager, F as setWebSocketToolExecutor, G as OAuthClient, H as CheckpointStore, I as OllamaBackend, J as searchCommands, K as hasFileReferences, L as buildCoreSystemPrompt, M as DEFAULT_THOROUGHNESS, N as clearFeatureModuleTools, O as ALWAYS_DENIED_FOR_AGENTS, P as registerFeatureModuleTools, Q as warmFileCache, R as buildSkillsPromptSection, S as extractCompactInstructions, T as getEnvironmentName, U as CommandHistoryStore, V as CustomCommandStore, W as SessionStore, X as formatFileSize, Y as mergeCommands, Z as searchFiles, _ as WebSocketLlmBackend, a as createCoordinateTaskTool, b as substituteArguments, c as createAgentDelegateTool, d as createSkillTool, f as parseAgentConfig, g as FallbackLlmBackend, h as WebSocketConnectionManager, i as createWriteTodosTool, j as DEFAULT_RETRY_CONFIG, k as DEFAULT_AGENT_MODEL, l as AgentStore, m as WebSocketToolExecutor, n as createFindDefinitionTool, o as createBackgroundAgentTools, p as ApiClient, q as processFileReferences, r as createTodoStore, s as BackgroundAgentManager, t as createGetFileStructureTool, u as SubagentOrchestrator, v as ServerLlmBackend, w as getApiUrl, x as formatStep, y as McpManager, z as isReadOnlyTool } from "./tools-DiSJh1Dv.mjs";
4
+ import { Mt as validateNotebookPath$1, g as ChatModels, jt as validateJupyterKernelName, m as CREDIT_DEDUCT_TRANSACTION_TYPES, n as logger, t as ConfigStore } from "./ConfigStore-DBUmvCfe.mjs";
5
+ import { i as version, t as checkForUpdate } from "./updateChecker-DcJC1C8S.mjs";
6
6
  import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from "react";
7
7
  import { Box, Static, Text, render, useApp, useInput } from "ink";
8
8
  import { execSync } from "child_process";
@@ -3439,6 +3439,27 @@ var TavernService = class {
3439
3439
  async abortHeartbeats() {
3440
3440
  await this.apiClient.post("/api/tavern/abort-heartbeats", { abort: true });
3441
3441
  }
3442
+ async getQuestPlan(planId) {
3443
+ return this.apiClient.get(`/api/quest-master-plans/${encodeURIComponent(planId)}`);
3444
+ }
3445
+ async updateReviewGate(planId, questId, subQuestId, reviewStatus, reviewNote) {
3446
+ return this.apiClient.post(`/api/quest-master-plans/${encodeURIComponent(planId)}/review-gate`, {
3447
+ questId,
3448
+ subQuestId,
3449
+ reviewStatus,
3450
+ reviewNote
3451
+ });
3452
+ }
3453
+ async updateSubQuestProgress(planId, questId, subQuestId, updates) {
3454
+ return this.apiClient.post(`/api/quest-master-plans/${encodeURIComponent(planId)}/subquest-progress`, {
3455
+ questId,
3456
+ subQuestId,
3457
+ ...updates
3458
+ });
3459
+ }
3460
+ async updateHandoff(planId, handoff) {
3461
+ return this.apiClient.post(`/api/quest-master-plans/${encodeURIComponent(planId)}/handoff`, handoff);
3462
+ }
3442
3463
  };
3443
3464
  //#endregion
3444
3465
  //#region src/features/tavern/types.ts
@@ -3626,6 +3647,109 @@ z.object({
3626
3647
  error: z.string().optional()
3627
3648
  }))
3628
3649
  });
3650
+ /** Sub-quest within a quest */
3651
+ const SubQuestSchema = z.object({
3652
+ id: z.string(),
3653
+ title: z.string(),
3654
+ status: z.enum([
3655
+ "not_started",
3656
+ "in_progress",
3657
+ "completed",
3658
+ "skipped",
3659
+ "deleted"
3660
+ ]),
3661
+ questId: z.string().optional(),
3662
+ startedAt: z.number().optional(),
3663
+ evidence: z.string().optional(),
3664
+ reviewGate: z.boolean().optional(),
3665
+ reviewStatus: z.enum([
3666
+ "pending",
3667
+ "approved",
3668
+ "rejected"
3669
+ ]).optional(),
3670
+ reviewNote: z.string().optional()
3671
+ });
3672
+ /** Quest containing sub-quests */
3673
+ const QuestDataSchema = z.object({
3674
+ id: z.string(),
3675
+ title: z.string(),
3676
+ description: z.string(),
3677
+ complexity: z.string(),
3678
+ subQuests: z.array(SubQuestSchema)
3679
+ });
3680
+ /** Handoff state for session continuity */
3681
+ const HandoffSchema = z.object({
3682
+ summary: z.string(),
3683
+ nextSteps: z.array(z.string()),
3684
+ pendingDecisions: z.array(z.string()),
3685
+ blockers: z.array(z.string()),
3686
+ lastUpdatedBy: z.string(),
3687
+ updatedAt: z.string()
3688
+ });
3689
+ z.object({
3690
+ _id: z.string(),
3691
+ notebookId: z.string(),
3692
+ goal: z.string(),
3693
+ quests: z.array(QuestDataSchema),
3694
+ state: z.enum([
3695
+ "draft",
3696
+ "active",
3697
+ "paused",
3698
+ "completed",
3699
+ "archived"
3700
+ ]).optional(),
3701
+ handoff: HandoffSchema.optional(),
3702
+ metrics: z.object({
3703
+ totalTimeSpent: z.number(),
3704
+ completionRate: z.number(),
3705
+ subQuestsCompleted: z.number(),
3706
+ subQuestsTotal: z.number(),
3707
+ lastProgress: z.string().optional()
3708
+ }).optional()
3709
+ });
3710
+ z.object({
3711
+ planId: z.string(),
3712
+ questId: z.string(),
3713
+ subQuestId: z.string(),
3714
+ reviewStatus: z.enum([
3715
+ "pending",
3716
+ "approved",
3717
+ "rejected"
3718
+ ]),
3719
+ reviewNote: z.string().optional()
3720
+ });
3721
+ z.object({
3722
+ planId: z.string(),
3723
+ questId: z.string(),
3724
+ subQuestId: z.string(),
3725
+ status: z.enum([
3726
+ "not_started",
3727
+ "in_progress",
3728
+ "completed",
3729
+ "skipped",
3730
+ "deleted"
3731
+ ]).optional(),
3732
+ evidence: z.string().optional(),
3733
+ timeSpent: z.number().optional()
3734
+ });
3735
+ z.object({
3736
+ planId: z.string(),
3737
+ summary: z.string(),
3738
+ nextSteps: z.array(z.string()),
3739
+ pendingDecisions: z.array(z.string()),
3740
+ blockers: z.array(z.string())
3741
+ });
3742
+ z.object({
3743
+ success: z.boolean(),
3744
+ plan: z.unknown().optional(),
3745
+ metrics: z.object({
3746
+ totalTimeSpent: z.number(),
3747
+ completionRate: z.number(),
3748
+ subQuestsCompleted: z.number(),
3749
+ subQuestsTotal: z.number(),
3750
+ lastProgress: z.string().optional()
3751
+ }).optional()
3752
+ });
3629
3753
  //#endregion
3630
3754
  //#region src/features/tavern/TavernActivityStream.ts
3631
3755
  /**
@@ -3660,6 +3784,39 @@ var TavernActivityStream = class {
3660
3784
  };
3661
3785
  //#endregion
3662
3786
  //#region src/features/tavern/tavernTools.ts
3787
+ const GetQuestPlanParamsSchema = z.object({ plan_id: z.string().min(1) });
3788
+ const UpdateReviewGateParamsSchema = z.object({
3789
+ plan_id: z.string().min(1),
3790
+ quest_id: z.string().min(1),
3791
+ sub_quest_id: z.string().min(1),
3792
+ review_status: z.enum([
3793
+ "pending",
3794
+ "approved",
3795
+ "rejected"
3796
+ ]),
3797
+ review_note: z.string().optional()
3798
+ });
3799
+ const UpdateQuestProgressParamsSchema = z.object({
3800
+ plan_id: z.string().min(1),
3801
+ quest_id: z.string().min(1),
3802
+ sub_quest_id: z.string().min(1),
3803
+ status: z.enum([
3804
+ "not_started",
3805
+ "in_progress",
3806
+ "completed",
3807
+ "skipped",
3808
+ "deleted"
3809
+ ]).optional(),
3810
+ evidence: z.string().optional(),
3811
+ time_spent: z.number().min(0).optional()
3812
+ });
3813
+ const WriteHandoffParamsSchema = z.object({
3814
+ plan_id: z.string().min(1),
3815
+ summary: z.string().min(1),
3816
+ next_steps: z.array(z.string()),
3817
+ pending_decisions: z.array(z.string()),
3818
+ blockers: z.array(z.string())
3819
+ });
3663
3820
  /**
3664
3821
  * Factory that creates ICompletionOptionTools[] for the Tavern feature.
3665
3822
  *
@@ -3682,7 +3839,11 @@ function createTavernTools(service) {
3682
3839
  createToggleHeartbeatsTool(service),
3683
3840
  createTriggerHeartbeatTool(service),
3684
3841
  createAbortHeartbeatsTool(service),
3685
- createStatusTool(service)
3842
+ createStatusTool(service),
3843
+ createGetQuestPlanTool(service),
3844
+ createUpdateReviewGateTool(service),
3845
+ createUpdateQuestProgressTool(service),
3846
+ createWriteHandoffTool(service)
3686
3847
  ];
3687
3848
  }
3688
3849
  function createListAgentsTool(service) {
@@ -4211,6 +4372,187 @@ function createStatusTool(service) {
4211
4372
  }
4212
4373
  };
4213
4374
  }
4375
+ function createGetQuestPlanTool(service) {
4376
+ return {
4377
+ toolSchema: {
4378
+ name: "tavern_get_quest_plan",
4379
+ description: "Fetch a quest master plan by ID. Returns the full plan with all quests, sub-quests, review gate status, handoff state, and progress metrics. Use this to check which sub-quests have review gates and their current status.",
4380
+ parameters: {
4381
+ type: "object",
4382
+ properties: { plan_id: {
4383
+ type: "string",
4384
+ description: "The MongoDB ObjectId of the quest master plan"
4385
+ } },
4386
+ required: ["plan_id"]
4387
+ }
4388
+ },
4389
+ toolFn: async (params) => {
4390
+ const { plan_id } = GetQuestPlanParamsSchema.parse(params);
4391
+ const result = await service.getQuestPlan(plan_id);
4392
+ return JSON.stringify(result);
4393
+ }
4394
+ };
4395
+ }
4396
+ function createUpdateReviewGateTool(service) {
4397
+ return {
4398
+ toolSchema: {
4399
+ name: "tavern_update_review_gate",
4400
+ description: "Approve or reject a review gate on a sub-quest. Review gates are human approval checkpoints — when a sub-quest has reviewGate: true, the AI must stop and wait for human approval before proceeding.",
4401
+ parameters: {
4402
+ type: "object",
4403
+ properties: {
4404
+ plan_id: {
4405
+ type: "string",
4406
+ description: "The MongoDB ObjectId of the quest master plan"
4407
+ },
4408
+ quest_id: {
4409
+ type: "string",
4410
+ description: "The ID of the parent quest"
4411
+ },
4412
+ sub_quest_id: {
4413
+ type: "string",
4414
+ description: "The ID of the sub-quest with the review gate"
4415
+ },
4416
+ review_status: {
4417
+ type: "string",
4418
+ description: "The review decision",
4419
+ enum: [
4420
+ "pending",
4421
+ "approved",
4422
+ "rejected"
4423
+ ]
4424
+ },
4425
+ review_note: {
4426
+ type: "string",
4427
+ description: "Optional note explaining the review decision"
4428
+ }
4429
+ },
4430
+ required: [
4431
+ "plan_id",
4432
+ "quest_id",
4433
+ "sub_quest_id",
4434
+ "review_status"
4435
+ ]
4436
+ }
4437
+ },
4438
+ toolFn: async (params) => {
4439
+ const { plan_id, quest_id, sub_quest_id, review_status, review_note } = UpdateReviewGateParamsSchema.parse(params);
4440
+ const result = await service.updateReviewGate(plan_id, quest_id, sub_quest_id, review_status, review_note);
4441
+ return JSON.stringify(result);
4442
+ }
4443
+ };
4444
+ }
4445
+ function createUpdateQuestProgressTool(service) {
4446
+ return {
4447
+ toolSchema: {
4448
+ name: "tavern_update_quest_progress",
4449
+ description: "Update a sub-quest's progress. Set status to track completion, add evidence of what was accomplished, and optionally record time spent. Setting status to \"in_progress\" auto-resumes a paused plan.",
4450
+ parameters: {
4451
+ type: "object",
4452
+ properties: {
4453
+ plan_id: {
4454
+ type: "string",
4455
+ description: "The MongoDB ObjectId of the quest master plan"
4456
+ },
4457
+ quest_id: {
4458
+ type: "string",
4459
+ description: "The ID of the parent quest"
4460
+ },
4461
+ sub_quest_id: {
4462
+ type: "string",
4463
+ description: "The ID of the sub-quest to update"
4464
+ },
4465
+ status: {
4466
+ type: "string",
4467
+ description: "New status for the sub-quest",
4468
+ enum: [
4469
+ "not_started",
4470
+ "in_progress",
4471
+ "completed",
4472
+ "skipped",
4473
+ "deleted"
4474
+ ]
4475
+ },
4476
+ evidence: {
4477
+ type: "string",
4478
+ description: "Evidence of completion — links to artifacts, descriptions of output, or references to results"
4479
+ },
4480
+ time_spent: {
4481
+ type: "number",
4482
+ description: "Time spent on this sub-quest in milliseconds"
4483
+ }
4484
+ },
4485
+ required: [
4486
+ "plan_id",
4487
+ "quest_id",
4488
+ "sub_quest_id"
4489
+ ]
4490
+ }
4491
+ },
4492
+ toolFn: async (params) => {
4493
+ const { plan_id, quest_id, sub_quest_id, status, evidence, time_spent } = UpdateQuestProgressParamsSchema.parse(params);
4494
+ const updates = {};
4495
+ if (status !== void 0) updates.status = status;
4496
+ if (evidence !== void 0) updates.evidence = evidence;
4497
+ if (time_spent !== void 0) updates.timeSpent = time_spent;
4498
+ const result = await service.updateSubQuestProgress(plan_id, quest_id, sub_quest_id, updates);
4499
+ return JSON.stringify(result);
4500
+ }
4501
+ };
4502
+ }
4503
+ function createWriteHandoffTool(service) {
4504
+ return {
4505
+ toolSchema: {
4506
+ name: "tavern_write_handoff",
4507
+ description: "Write a handoff state for session continuity. Called when ending a session so the next session can resume with full context. Includes a summary of progress, next steps, pending decisions, and blockers.",
4508
+ parameters: {
4509
+ type: "object",
4510
+ properties: {
4511
+ plan_id: {
4512
+ type: "string",
4513
+ description: "The MongoDB ObjectId of the quest master plan"
4514
+ },
4515
+ summary: {
4516
+ type: "string",
4517
+ description: "Summary of what was accomplished in this session"
4518
+ },
4519
+ next_steps: {
4520
+ type: "array",
4521
+ items: { type: "string" },
4522
+ description: "List of next steps for the following session"
4523
+ },
4524
+ pending_decisions: {
4525
+ type: "array",
4526
+ items: { type: "string" },
4527
+ description: "Decisions that still need to be made"
4528
+ },
4529
+ blockers: {
4530
+ type: "array",
4531
+ items: { type: "string" },
4532
+ description: "Current blockers preventing progress"
4533
+ }
4534
+ },
4535
+ required: [
4536
+ "plan_id",
4537
+ "summary",
4538
+ "next_steps",
4539
+ "pending_decisions",
4540
+ "blockers"
4541
+ ]
4542
+ }
4543
+ },
4544
+ toolFn: async (params) => {
4545
+ const { plan_id, summary, next_steps, pending_decisions, blockers } = WriteHandoffParamsSchema.parse(params);
4546
+ const result = await service.updateHandoff(plan_id, {
4547
+ summary,
4548
+ nextSteps: next_steps,
4549
+ pendingDecisions: pending_decisions,
4550
+ blockers
4551
+ });
4552
+ return JSON.stringify(result);
4553
+ }
4554
+ };
4555
+ }
4214
4556
  //#endregion
4215
4557
  //#region src/features/tavern/TavernModule.ts
4216
4558
  /** Icons for heartbeat log actions shown in /tavern command */
@@ -4274,9 +4616,23 @@ Available actions:
4274
4616
  - **tavern_trigger_heartbeat**: Manually trigger a heartbeat cycle
4275
4617
  - **tavern_abort_heartbeats**: Emergency stop all in-flight heartbeats
4276
4618
  - **tavern_status**: Quick overview of agents, quests, and gates — good for situational awareness
4619
+ - **tavern_get_quest_plan**: Fetch a quest master plan with review gate status and handoff state
4620
+ - **tavern_update_review_gate**: Approve or reject a review gate on a sub-quest
4621
+ - **tavern_update_quest_progress**: Update sub-quest status and record evidence of completion
4622
+ - **tavern_write_handoff**: Write session handoff for continuity across sessions
4277
4623
 
4278
4624
  When the user mentions talking to agents, checking the quest board, or managing the tavern, use these tools.
4279
- Agents have personalities, moods, quests, and memories — they are autonomous entities, not chatbots.`;
4625
+ Agents have personalities, moods, quests, and memories — they are autonomous entities, not chatbots.
4626
+
4627
+ ## Quest Workflow (Review Gates)
4628
+ When working on a quest plan with review gates (reviewGate: true on sub-quests), you MUST:
4629
+ 1. Check review gate status with tavern_get_quest_plan before proceeding past a gated step
4630
+ 2. If the next sub-quest has reviewGate: true and reviewStatus is not 'approved', STOP and inform the user
4631
+ 3. Record evidence of completion with tavern_update_quest_progress when finishing a sub-quest
4632
+ 4. Write a handoff with tavern_write_handoff before ending a session with an active quest plan
4633
+
4634
+ ## Session Handoff & Resume
4635
+ When the user runs /quest resume <plan_id>, read the handoff context and continue from where the previous session left off. The handoff contains: summary of prior work, next steps, pending decisions, and blockers.`;
4280
4636
  }
4281
4637
  getCommands() {
4282
4638
  return [{
@@ -4301,6 +4657,95 @@ Agents have personalities, moods, quests, and memories — they are autonomous e
4301
4657
  }
4302
4658
  console.log("");
4303
4659
  }
4660
+ }, {
4661
+ name: "quest",
4662
+ description: "Quest workflow commands: review gates, resume from handoff",
4663
+ execute: async (args) => {
4664
+ const subCommand = args[0];
4665
+ if (subCommand === "resume") {
4666
+ const planId = args[1];
4667
+ if (!planId) {
4668
+ console.log("\nUsage: /quest resume <plan_id>");
4669
+ console.log(" Loads the quest plan and displays the session handoff for continuity.\n");
4670
+ return;
4671
+ }
4672
+ try {
4673
+ const plan = await this.service.getQuestPlan(planId);
4674
+ console.log(`\nQuest Plan: ${plan.goal}`);
4675
+ console.log(`State: ${plan.state ?? "unknown"}`);
4676
+ if (plan.metrics) {
4677
+ const pct = Math.round(plan.metrics.completionRate * 100);
4678
+ console.log(`Progress: ${plan.metrics.subQuestsCompleted}/${plan.metrics.subQuestsTotal} sub-quests (${pct}%)`);
4679
+ }
4680
+ if (!plan.handoff) {
4681
+ console.log("\n No handoff found — this plan has no saved session context.");
4682
+ console.log(" The AI can still read the plan via tavern_get_quest_plan.\n");
4683
+ return;
4684
+ }
4685
+ const { handoff } = plan;
4686
+ console.log(`\nSession Handoff (${new Date(handoff.updatedAt).toLocaleString()}):`);
4687
+ console.log(`\n Summary: ${handoff.summary}`);
4688
+ if (handoff.nextSteps.length > 0) {
4689
+ console.log("\n Next Steps:");
4690
+ for (const step of handoff.nextSteps) console.log(` \u2022 ${step}`);
4691
+ }
4692
+ if (handoff.pendingDecisions.length > 0) {
4693
+ console.log("\n Pending Decisions:");
4694
+ for (const decision of handoff.pendingDecisions) console.log(` \u2753 ${decision}`);
4695
+ }
4696
+ if (handoff.blockers.length > 0) {
4697
+ console.log("\n Blockers:");
4698
+ for (const blocker of handoff.blockers) console.log(` \u{1F6D1} ${blocker}`);
4699
+ }
4700
+ console.log("");
4701
+ } catch (error) {
4702
+ const message = error instanceof Error ? error.message : String(error);
4703
+ console.log(`\nError fetching quest plan: ${message}\n`);
4704
+ }
4705
+ return;
4706
+ }
4707
+ if (subCommand === "review") {
4708
+ const planId = args[1];
4709
+ if (!planId) {
4710
+ console.log("\nUsage: /quest review <plan_id>");
4711
+ console.log(" Fetches the quest plan and shows sub-quests with pending review gates.\n");
4712
+ return;
4713
+ }
4714
+ try {
4715
+ const plan = await this.service.getQuestPlan(planId);
4716
+ const pendingGates = [];
4717
+ for (const quest of plan.quests) for (const sq of quest.subQuests) if (sq.reviewGate) pendingGates.push({
4718
+ questTitle: quest.title,
4719
+ questId: quest.id,
4720
+ subQuestTitle: sq.title,
4721
+ subQuestId: sq.id,
4722
+ status: sq.reviewStatus ?? "pending"
4723
+ });
4724
+ if (pendingGates.length === 0) {
4725
+ console.log(`\nQuest Plan: ${plan.goal}`);
4726
+ console.log(" No review gates configured in this plan.\n");
4727
+ return;
4728
+ }
4729
+ console.log(`\nQuest Plan: ${plan.goal}`);
4730
+ console.log(`State: ${plan.state ?? "unknown"}\n`);
4731
+ console.log("Review Gates:");
4732
+ for (const gate of pendingGates) {
4733
+ const icon = gate.status === "approved" ? "✅" : gate.status === "rejected" ? "❌" : "⏸️";
4734
+ console.log(` ${icon} [${gate.status}] ${gate.questTitle} > ${gate.subQuestTitle}`);
4735
+ console.log(` quest_id: ${gate.questId} sub_quest_id: ${gate.subQuestId}`);
4736
+ }
4737
+ console.log("\n To approve: ask the AI to approve a review gate, or use tavern_update_review_gate tool.\n");
4738
+ } catch (error) {
4739
+ const message = error instanceof Error ? error.message : String(error);
4740
+ console.log(`\nError fetching quest plan: ${message}\n`);
4741
+ }
4742
+ return;
4743
+ }
4744
+ console.log("\nUsage:");
4745
+ console.log(" /quest review <plan_id> — Show review gates and their status");
4746
+ console.log(" /quest resume <plan_id> — Load handoff and resume from where you left off");
4747
+ console.log("");
4748
+ }
4304
4749
  }];
4305
4750
  }
4306
4751
  registerWsHandlers(wsManager) {
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { $ as RechartsChartTypeList, A as ImageGenerationUsageTransaction, At as secureParameters, B as NotFoundError, C as FileEvents, Ct as getMcpProviderMetadata, D as GenericCreditAddTransaction, Dt as obfuscateApiKey, E as GenerateImageToolCallSchema, Et as isGPTImageModel, F as KnowledgeType, G as ProfileEvents, H as OpenAIImageGenerationInput, I as LLMEvents, J as PurchaseTransaction, K as ProjectEvents, L as MiscEvents, M as InboxEvents, N as InviteEvents, Nt as CollectionType, O as GenericCreditDeductTransaction, Ot as resolveNavigationIntents, P as InviteType, Q as ReceivedCreditTransaction, R as ModalEvents, S as FeedbackEvents, St as getDataLakeTags, T as GEMINI_IMAGE_MODELS, Tt as isGPTImage2Model, U as Permission, V as OpenAIEmbeddingModel, W as PermissionDeniedError, X as REASONING_SUPPORTED_MODELS, Y as QuestMasterParamsSchema, Z as RealtimeVoiceUsageTransaction, _ as CompletionApiUsageTransaction, _t as VideoModels, a as ApiKeyEvents, at as SessionEvents, b as FIXED_TEMPERATURE_MODELS, bt as b4mLLMTools, c as AppFileEvents, ct as SupportedFabFileMimeTypes, d as BFL_IMAGE_MODELS, dt as TextGenerationUsageTransaction, et as RegInviteEvents, f as BFL_SAFETY_TOLERANCE, ft as ToolUsageTransaction, g as ChatModels, gt as VideoGenerationUsageTransaction, h as ChatCompletionCreateInputSchema, ht as VIDEO_SIZE_CONSTRAINTS, i as AiEvents, it as ResearchTaskType, j as ImageModels, k as ImageEditUsageTransaction, kt as sanitizeTelemetryError, l as ArtifactTypeSchema, lt as TagType, mt as UiNavigationEvents, n as logger, nt as ResearchTaskExecutionType, o as ApiKeyScope, ot as SpeechToTextModels, p as BedrockEmbeddingModel, pt as TransferCreditTransaction, q as PromptMetaZodSchema, r as ALERT_THRESHOLDS, rt as ResearchTaskPeriodicFrequencyType, s as ApiKeyType, st as SubscriptionCreditTransaction, t as ConfigStore, tt as ResearchModeParamsSchema, u as AuthEvents, ut as TaskScheduleHandler, v as DashboardParamsSchema, vt as VoyageAIEmbeddingModel, w as FriendshipEvents, wt as getViewById, x as FavoriteDocumentType, xt as getAccessibleDataLakes, y as ElabsEvents, yt as XAI_IMAGE_MODELS, z as ModelBackend } from "./ConfigStore-o5AblHqQ.mjs";
2
+ import { $ as RechartsChartTypeList, A as ImageGenerationUsageTransaction, At as secureParameters, B as NotFoundError, C as FileEvents, Ct as getMcpProviderMetadata, D as GenericCreditAddTransaction, Dt as obfuscateApiKey, E as GenerateImageToolCallSchema, Et as isGPTImageModel, F as KnowledgeType, G as ProfileEvents, H as OpenAIImageGenerationInput, I as LLMEvents, J as PurchaseTransaction, K as ProjectEvents, L as MiscEvents, M as InboxEvents, N as InviteEvents, Nt as CollectionType, O as GenericCreditDeductTransaction, Ot as resolveNavigationIntents, P as InviteType, Q as ReceivedCreditTransaction, R as ModalEvents, S as FeedbackEvents, St as getDataLakeTags, T as GEMINI_IMAGE_MODELS, Tt as isGPTImage2Model, U as Permission, V as OpenAIEmbeddingModel, W as PermissionDeniedError, X as REASONING_SUPPORTED_MODELS, Y as QuestMasterParamsSchema, Z as RealtimeVoiceUsageTransaction, _ as CompletionApiUsageTransaction, _t as VideoModels, a as ApiKeyEvents, at as SessionEvents, b as FIXED_TEMPERATURE_MODELS, bt as b4mLLMTools, c as AppFileEvents, ct as SupportedFabFileMimeTypes, d as BFL_IMAGE_MODELS, dt as TextGenerationUsageTransaction, et as RegInviteEvents, f as BFL_SAFETY_TOLERANCE, ft as ToolUsageTransaction, g as ChatModels, gt as VideoGenerationUsageTransaction, h as ChatCompletionCreateInputSchema, ht as VIDEO_SIZE_CONSTRAINTS, i as AiEvents, it as ResearchTaskType, j as ImageModels, k as ImageEditUsageTransaction, kt as sanitizeTelemetryError, l as ArtifactTypeSchema, lt as TagType, mt as UiNavigationEvents, n as logger, nt as ResearchTaskExecutionType, o as ApiKeyScope, ot as SpeechToTextModels, p as BedrockEmbeddingModel, pt as TransferCreditTransaction, q as PromptMetaZodSchema, r as ALERT_THRESHOLDS, rt as ResearchTaskPeriodicFrequencyType, s as ApiKeyType, st as SubscriptionCreditTransaction, t as ConfigStore, tt as ResearchModeParamsSchema, u as AuthEvents, ut as TaskScheduleHandler, v as DashboardParamsSchema, vt as VoyageAIEmbeddingModel, w as FriendshipEvents, wt as getViewById, x as FavoriteDocumentType, xt as getAccessibleDataLakes, y as ElabsEvents, yt as XAI_IMAGE_MODELS, z as ModelBackend } from "./ConfigStore-DBUmvCfe.mjs";
3
3
  import { n as isPathAllowed, t as assertPathAllowed } from "./pathValidation-CIytuhr3-Dt5dntLx.mjs";
4
4
  import { execFile, execFileSync, spawn } from "child_process";
5
5
  import { createHash, randomBytes } from "crypto";
@@ -15356,9 +15356,12 @@ z.object({
15356
15356
  direction: z.enum(["asc", "desc"])
15357
15357
  }).optional(),
15358
15358
  options: z.object({
15359
+ textSearch: z.coerce.boolean().optional(),
15359
15360
  includeShared: z.coerce.boolean().optional(),
15360
15361
  userGroups: z.array(z.string()).optional(),
15361
- dataLakeTags: z.array(z.string()).optional()
15362
+ dataLakeTags: z.array(z.string()).optional(),
15363
+ dataLakeTagPrefixes: z.array(z.string()).optional(),
15364
+ excludeContent: z.coerce.boolean().optional()
15362
15365
  }).optional()
15363
15366
  });
15364
15367
  z.object({ fileId: z.string() });
@@ -4,7 +4,7 @@ import { homedir } from "os";
4
4
  import path from "path";
5
5
  import axios from "axios";
6
6
  //#region package.json
7
- var version = "0.3.0";
7
+ var version = "0.4.0";
8
8
  //#endregion
9
9
  //#region src/utils/updateChecker.ts
10
10
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -118,11 +118,11 @@
118
118
  "tsx": "^4.21.0",
119
119
  "typescript": "^5.9.3",
120
120
  "vitest": "^4.1.2",
121
- "@bike4mind/agents": "0.5.0",
122
- "@bike4mind/common": "2.87.0",
123
- "@bike4mind/mcp": "1.35.9",
124
- "@bike4mind/services": "2.76.8",
125
- "@bike4mind/utils": "2.18.7"
121
+ "@bike4mind/agents": "0.5.2",
122
+ "@bike4mind/common": "2.88.0",
123
+ "@bike4mind/mcp": "1.35.11",
124
+ "@bike4mind/services": "2.76.10",
125
+ "@bike4mind/utils": "2.18.9"
126
126
  },
127
127
  "optionalDependencies": {
128
128
  "@vscode/ripgrep": "^1.17.1"