@bike4mind/cli 0.2.29-subagent-delegation.18906 → 0.2.29

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.
package/dist/index.js CHANGED
@@ -5,7 +5,8 @@ import {
5
5
  getEffectiveApiKey,
6
6
  getOpenWeatherKey,
7
7
  getSerperKey
8
- } from "./chunk-XTJDV3TC.js";
8
+ } from "./chunk-22VR7SKO.js";
9
+ import "./chunk-RUI6HNLO.js";
9
10
  import {
10
11
  ConfigStore,
11
12
  logger
@@ -14,8 +15,8 @@ import {
14
15
  selectActiveBackgroundAgents,
15
16
  useCliStore
16
17
  } from "./chunk-TVW4ZESU.js";
17
- import "./chunk-TKZJAHDN.js";
18
- import "./chunk-HZNRFX2D.js";
18
+ import "./chunk-UYN4HMRF.js";
19
+ import "./chunk-YQWFK5O2.js";
19
20
  import {
20
21
  BFLImageService,
21
22
  BaseStorage,
@@ -27,7 +28,7 @@ import {
27
28
  OpenAIBackend,
28
29
  OpenAIImageService,
29
30
  XAIImageService
30
- } from "./chunk-SA634LPQ.js";
31
+ } from "./chunk-5J4RL57F.js";
31
32
  import {
32
33
  AiEvents,
33
34
  ApiKeyEvents,
@@ -83,7 +84,7 @@ import {
83
84
  XAI_IMAGE_MODELS,
84
85
  b4mLLMTools,
85
86
  getMcpProviderMetadata
86
- } from "./chunk-WKJ6QNRZ.js";
87
+ } from "./chunk-TNFZP7FG.js";
87
88
  import {
88
89
  Logger
89
90
  } from "./chunk-OCYRD7D6.js";
@@ -3331,8 +3332,7 @@ ${options.context}` : this.getSystemPrompt()
3331
3332
  maxTokens,
3332
3333
  temperature,
3333
3334
  abortSignal: options.signal,
3334
- tool_choice: this.context.toolChoice,
3335
- executeTools: false
3335
+ tool_choice: this.context.toolChoice
3336
3336
  },
3337
3337
  async (texts, completionInfo) => {
3338
3338
  for (const text of texts) {
@@ -4073,7 +4073,8 @@ var recalculateUserStorageSchema = z14.object({
4073
4073
  // ../../b4m-core/packages/services/dist/src/userService/listRecentActivities.js
4074
4074
  import { z as z15 } from "zod";
4075
4075
  var listRecentActivitiesSchema = z15.object({
4076
- coverage: z15.enum(["all", "important"]).default("important")
4076
+ coverage: z15.enum(["all", "important"]).default("important"),
4077
+ userId: z15.string().optional()
4077
4078
  });
4078
4079
  var IMPORTANT_COUNTER_NAMES = [
4079
4080
  SessionEvents.CREATE_SESSION,
@@ -5717,7 +5718,19 @@ import { z as z129 } from "zod";
5717
5718
  var createArtifactSchema = z129.object({
5718
5719
  id: z129.string().optional(),
5719
5720
  // Allow custom ID for AI-generated artifacts
5720
- type: z129.enum(["mermaid", "recharts", "python", "react", "html", "svg", "code", "quest", "file", "questmaster"]),
5721
+ type: z129.enum([
5722
+ "mermaid",
5723
+ "recharts",
5724
+ "python",
5725
+ "react",
5726
+ "html",
5727
+ "svg",
5728
+ "code",
5729
+ "quest",
5730
+ "file",
5731
+ "questmaster",
5732
+ "lattice"
5733
+ ]),
5721
5734
  title: z129.string().min(1).max(255),
5722
5735
  description: z129.string().max(1e3).optional(),
5723
5736
  content: z129.string().min(1),
@@ -10325,6 +10338,819 @@ BLOCKED OPERATIONS:
10325
10338
  })
10326
10339
  };
10327
10340
 
10341
+ // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/lattice/index.js
10342
+ function createModelData(name, modelType, userId, description, sessionId) {
10343
+ const now = /* @__PURE__ */ new Date();
10344
+ return {
10345
+ name,
10346
+ description: description || "",
10347
+ modelType,
10348
+ userId,
10349
+ sessionId,
10350
+ data: { entities: [], relationships: [] },
10351
+ rules: { rules: [], rulesets: [] },
10352
+ views: { views: [] },
10353
+ settings: {
10354
+ currency: "USD",
10355
+ fiscalYearStart: "01-01",
10356
+ periodGrain: "quarter",
10357
+ defaultDecimalPlaces: 2,
10358
+ negativeFormat: "parentheses"
10359
+ },
10360
+ scenarios: [],
10361
+ operations: [],
10362
+ operationIndex: -1,
10363
+ version: 1,
10364
+ createdAt: now,
10365
+ updatedAt: now
10366
+ };
10367
+ }
10368
+ var latticeCreateModelTool = {
10369
+ name: "lattice_create_model",
10370
+ implementation: (context) => ({
10371
+ toolFn: async (params) => {
10372
+ const { name, description, modelType = "custom", initialData } = params;
10373
+ console.log("[LATTICE DEBUG] \u{1F3D7}\uFE0F lattice_create_model called:", {
10374
+ name,
10375
+ description,
10376
+ modelType,
10377
+ hasInitialData: !!initialData,
10378
+ entityCount: initialData?.entities?.length || 0,
10379
+ ruleCount: initialData?.rules?.length || 0
10380
+ });
10381
+ const modelData = createModelData(name, modelType, context.userId, description);
10382
+ if (initialData?.entities && modelData.data) {
10383
+ const now = /* @__PURE__ */ new Date();
10384
+ for (const entityDef of initialData.entities) {
10385
+ const entityId = entityDef.name.toLowerCase().replace(/\s+/g, "_");
10386
+ const attributes = [];
10387
+ if (entityDef.values) {
10388
+ for (const val of entityDef.values) {
10389
+ attributes.push({
10390
+ key: "period",
10391
+ value: val.period,
10392
+ dataType: "string",
10393
+ isComputed: false
10394
+ });
10395
+ attributes.push({
10396
+ key: "value",
10397
+ value: val.value,
10398
+ dataType: "currency",
10399
+ isComputed: false
10400
+ });
10401
+ attributes.push({
10402
+ key: "category",
10403
+ value: entityDef.name,
10404
+ dataType: "string",
10405
+ isComputed: false
10406
+ });
10407
+ modelData.data.entities.push({
10408
+ id: `${entityId}_${val.period.toLowerCase().replace(/\s+/g, "_")}`,
10409
+ type: entityDef.type || "line_item",
10410
+ name: `${entityDef.name} ${val.period}`,
10411
+ displayName: `${entityDef.name} ${val.period}`,
10412
+ attributes: [
10413
+ { key: "period", value: val.period, dataType: "string", isComputed: false },
10414
+ { key: "value", value: val.value, dataType: "currency", isComputed: false },
10415
+ { key: "category", value: entityDef.name, dataType: "string", isComputed: false }
10416
+ ],
10417
+ metadata: {},
10418
+ createdAt: now,
10419
+ updatedAt: now
10420
+ });
10421
+ }
10422
+ }
10423
+ console.log(`[LATTICE DEBUG] \u2795 Created entity: ${entityDef.name} with ${entityDef.values?.length || 0} period values`);
10424
+ }
10425
+ }
10426
+ if (initialData?.rules && modelData.rules) {
10427
+ const now = /* @__PURE__ */ new Date();
10428
+ for (const ruleDef of initialData.rules) {
10429
+ const ruleId = `rule_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
10430
+ const parsedRule = parseFormula(ruleDef.formula);
10431
+ modelData.rules.rules.push({
10432
+ id: ruleId,
10433
+ name: ruleDef.name,
10434
+ description: ruleDef.formula,
10435
+ type: "formula",
10436
+ definition: {
10437
+ operation: parsedRule.operation,
10438
+ inputs: parsedRule.inputs.map((ref) => ({ type: "entity", ref })),
10439
+ output: {
10440
+ targetEntityId: parsedRule.outputEntity.toLowerCase().replace(/\s+/g, "_"),
10441
+ targetAttribute: "computed",
10442
+ dataType: "number"
10443
+ }
10444
+ },
10445
+ dependencies: parsedRule.inputs.map((i) => i.toLowerCase().replace(/\s+/g, "_")),
10446
+ priority: 0,
10447
+ enabled: true,
10448
+ createdAt: now,
10449
+ updatedAt: now
10450
+ });
10451
+ console.log(`[LATTICE DEBUG] \u{1F4D0} Created rule: ${ruleDef.name} = ${ruleDef.formula}`);
10452
+ }
10453
+ }
10454
+ let model;
10455
+ let persistenceStatus = "unknown";
10456
+ const dbKeys = Object.keys(context.db || {});
10457
+ const hasLatticeModels = !!context.db?.latticeModels;
10458
+ if (context.db.latticeModels) {
10459
+ try {
10460
+ model = await context.db.latticeModels.create(modelData);
10461
+ persistenceStatus = `PERSISTED to MongoDB (id: ${model.id})`;
10462
+ context.logger.info(`[Lattice] Created model ${model.id} in database`);
10463
+ } catch (error) {
10464
+ persistenceStatus = `FAILED: ${error instanceof Error ? error.message : String(error)}`;
10465
+ context.logger.error(`[Lattice] Failed to persist model to database:`, error);
10466
+ model = {
10467
+ ...modelData,
10468
+ id: `lattice_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
10469
+ };
10470
+ }
10471
+ } else {
10472
+ persistenceStatus = `IN-MEMORY (no latticeModels adapter). DB keys: [${dbKeys.join(", ")}]`;
10473
+ context.logger.warn("[Lattice] No database adapter available, creating in-memory model");
10474
+ model = {
10475
+ ...modelData,
10476
+ id: `lattice_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
10477
+ };
10478
+ }
10479
+ const artifactData = {
10480
+ type: "lattice",
10481
+ id: model.id,
10482
+ title: name,
10483
+ content: JSON.stringify(model),
10484
+ metadata: {
10485
+ modelType,
10486
+ periodGrain: model.settings?.periodGrain || "quarter",
10487
+ currency: model.settings?.currency || "USD",
10488
+ entityCount: model.data?.entities?.length || 0,
10489
+ ruleCount: model.rules?.rules?.length || 0,
10490
+ // DEBUG: Include persistence info in metadata
10491
+ _debug: {
10492
+ persistenceStatus,
10493
+ hasLatticeModels,
10494
+ dbKeys
10495
+ }
10496
+ },
10497
+ createdAt: model.createdAt?.toISOString?.() || (/* @__PURE__ */ new Date()).toISOString(),
10498
+ updatedAt: model.updatedAt?.toISOString?.() || (/* @__PURE__ */ new Date()).toISOString()
10499
+ };
10500
+ const entityCount = model.data?.entities?.length || 0;
10501
+ const ruleCount = model.rules?.rules?.length || 0;
10502
+ return `Created "${name}" model with ${entityCount} entities and ${ruleCount} rules.
10503
+
10504
+ <artifact identifier="${model.id}" type="application/vnd.b4m.lattice" title="${name}">
10505
+ ${JSON.stringify(artifactData, null, 2)}
10506
+ </artifact>
10507
+
10508
+ The model is ready for viewing. You can add more data by asking to add line items or create formulas.`;
10509
+ },
10510
+ toolSchema: {
10511
+ name: "lattice_create_model",
10512
+ description: `Create a new Lattice financial model with optional initial data. Use initialData to populate entities and rules in ONE call.
10513
+
10514
+ **IMPORTANT**: Always include initialData when the user provides specific values! This creates a fully populated model immediately.
10515
+
10516
+ **When to use:** When the user wants to:
10517
+ - Create a new financial model, spreadsheet, or pro-forma
10518
+ - Start building an income statement, balance sheet, or cash flow
10519
+ - Set up a SaaS metrics dashboard
10520
+
10521
+ **Example with initialData:**
10522
+ User: "Create income statement with $100K revenue and $60K costs for Q1"
10523
+ Call: lattice_create_model with:
10524
+ - name: "Income Statement"
10525
+ - modelType: "income_statement"
10526
+ - initialData: {
10527
+ entities: [
10528
+ { name: "Revenue", values: [{ period: "Q1", value: 100000 }] },
10529
+ { name: "Costs", values: [{ period: "Q1", value: 60000 }] }
10530
+ ],
10531
+ rules: [
10532
+ { name: "Gross Profit", formula: "Gross Profit = Revenue - Costs" }
10533
+ ]
10534
+ }`,
10535
+ parameters: {
10536
+ type: "object",
10537
+ properties: {
10538
+ name: {
10539
+ type: "string",
10540
+ description: 'Name of the model (e.g., "2024 Budget", "Q1 Forecast")'
10541
+ },
10542
+ description: {
10543
+ type: "string",
10544
+ description: "Optional description of what this model represents"
10545
+ },
10546
+ modelType: {
10547
+ type: "string",
10548
+ enum: ["income_statement", "balance_sheet", "cashflow", "saas_metrics", "custom"],
10549
+ description: "Type of financial model to create"
10550
+ },
10551
+ initialData: {
10552
+ type: "object",
10553
+ description: "Initial entities and rules to populate the model. ALWAYS use this when user provides data!",
10554
+ properties: {
10555
+ entities: {
10556
+ type: "array",
10557
+ description: "Line items with their period values",
10558
+ items: {
10559
+ type: "object",
10560
+ properties: {
10561
+ name: { type: "string", description: 'Entity name (e.g., "Revenue", "COGS")' },
10562
+ type: { type: "string", description: "Entity type (default: line_item)" },
10563
+ values: {
10564
+ type: "array",
10565
+ description: "Period-value pairs",
10566
+ items: {
10567
+ type: "object",
10568
+ properties: {
10569
+ period: { type: "string", description: 'Period name (e.g., "Q1", "Jan", "2024")' },
10570
+ value: { type: "number", description: "Numeric value" }
10571
+ },
10572
+ required: ["period", "value"]
10573
+ }
10574
+ }
10575
+ },
10576
+ required: ["name"]
10577
+ }
10578
+ },
10579
+ rules: {
10580
+ type: "array",
10581
+ description: "Formulas/calculations to create",
10582
+ items: {
10583
+ type: "object",
10584
+ properties: {
10585
+ name: { type: "string", description: 'Rule name (e.g., "Gross Profit Calculation")' },
10586
+ formula: {
10587
+ type: "string",
10588
+ description: 'Natural language formula (e.g., "Gross Profit = Revenue - Costs")'
10589
+ }
10590
+ },
10591
+ required: ["name", "formula"]
10592
+ }
10593
+ }
10594
+ }
10595
+ }
10596
+ },
10597
+ required: ["name"]
10598
+ }
10599
+ }
10600
+ })
10601
+ };
10602
+ var latticeAddEntityTool = {
10603
+ name: "lattice_add_entity",
10604
+ implementation: (context) => ({
10605
+ toolFn: async (params) => {
10606
+ const { modelId, name, type, displayName, initialValues = [] } = params;
10607
+ console.log("[LATTICE DEBUG] \u2795 lattice_add_entity called:", { modelId, name, type, initialValues });
10608
+ const entityId = name.toLowerCase().replace(/\s+/g, "_");
10609
+ const entityData = {
10610
+ id: entityId,
10611
+ type,
10612
+ name,
10613
+ displayName: displayName || name,
10614
+ attributes: initialValues.map((v) => ({
10615
+ key: v.key,
10616
+ value: v.value,
10617
+ dataType: v.dataType || (typeof v.value === "number" ? "number" : "string"),
10618
+ isComputed: false
10619
+ })),
10620
+ metadata: {},
10621
+ createdAt: /* @__PURE__ */ new Date(),
10622
+ updatedAt: /* @__PURE__ */ new Date()
10623
+ };
10624
+ if (context.db.latticeModels && modelId && /^[a-f0-9]{24}$/.test(modelId)) {
10625
+ try {
10626
+ const model = await context.db.latticeModels.findById(modelId);
10627
+ if (model) {
10628
+ const existingIndex = model.data.entities.findIndex((e) => e.id === entityId);
10629
+ if (existingIndex >= 0) {
10630
+ model.data.entities[existingIndex] = entityData;
10631
+ } else {
10632
+ model.data.entities.push(entityData);
10633
+ }
10634
+ await context.db.latticeModels.update({
10635
+ id: modelId,
10636
+ data: model.data,
10637
+ updatedAt: /* @__PURE__ */ new Date()
10638
+ });
10639
+ context.logger.info(`[Lattice] Added entity ${entityId} to model ${modelId}`);
10640
+ } else {
10641
+ context.logger.warn(`[Lattice] Model ${modelId} not found in database`);
10642
+ }
10643
+ } catch (error) {
10644
+ context.logger.error(`[Lattice] Failed to persist entity to database:`, error);
10645
+ }
10646
+ }
10647
+ return JSON.stringify({
10648
+ success: true,
10649
+ action: "ADD_ENTITY",
10650
+ modelId,
10651
+ entityId,
10652
+ data: entityData,
10653
+ message: `Added ${type} "${displayName || name}" to model. ${initialValues.length > 0 ? `Set initial values: ${initialValues.map((v) => `${v.key}=${v.value}`).join(", ")}` : "No initial values set."}`
10654
+ });
10655
+ },
10656
+ toolSchema: {
10657
+ name: "lattice_add_entity",
10658
+ description: `Add a line item, account, period, or other entity to a Lattice model.
10659
+
10660
+ **When to use:** When the user mentions:
10661
+ - Adding a revenue line, expense category, or account
10662
+ - Creating periods (Q1, Q2, Jan, Feb, etc.)
10663
+ - Adding any measurable item to their model
10664
+
10665
+ **Entity types:**
10666
+ - line_item: Revenue streams, expense lines, KPIs
10667
+ - account: Cash, AR, AP, inventory, etc.
10668
+ - period: Q1 2024, Jan, FY2025, etc.
10669
+ - category: Groups of line items (Operating Expenses)
10670
+ - scenario: Base case, upside, downside
10671
+ - custom: Any other structured element
10672
+
10673
+ **Examples:**
10674
+ - "Add Revenue" \u2192 line_item named "Revenue"
10675
+ - "Create a Marketing Expenses category" \u2192 category named "Marketing Expenses"
10676
+ - "Add quarters Q1 through Q4" \u2192 4 period entities`,
10677
+ parameters: {
10678
+ type: "object",
10679
+ properties: {
10680
+ modelId: {
10681
+ type: "string",
10682
+ description: "ID of the model to add the entity to"
10683
+ },
10684
+ name: {
10685
+ type: "string",
10686
+ description: "Internal name for the entity (used in formulas)"
10687
+ },
10688
+ type: {
10689
+ type: "string",
10690
+ enum: ["line_item", "account", "period", "category", "scenario", "custom"],
10691
+ description: "Type of entity"
10692
+ },
10693
+ displayName: {
10694
+ type: "string",
10695
+ description: "Human-readable display name (defaults to name)"
10696
+ },
10697
+ initialValues: {
10698
+ type: "array",
10699
+ items: {
10700
+ type: "object",
10701
+ properties: {
10702
+ key: { type: "string", description: 'Period or attribute key (e.g., "Q1_2024")' },
10703
+ value: { type: "string", description: "The value (number or string)" },
10704
+ dataType: {
10705
+ type: "string",
10706
+ enum: ["number", "currency", "percentage", "string"],
10707
+ description: "Data type for the value"
10708
+ }
10709
+ },
10710
+ required: ["key", "value"]
10711
+ },
10712
+ description: "Optional initial values for this entity"
10713
+ }
10714
+ },
10715
+ required: ["modelId", "name", "type"]
10716
+ }
10717
+ }
10718
+ })
10719
+ };
10720
+ var latticeSetValueTool = {
10721
+ name: "lattice_set_value",
10722
+ implementation: (context) => ({
10723
+ toolFn: async (params) => {
10724
+ const { modelId, entityName, attributeKey, value: rawValue } = params;
10725
+ console.log("[LATTICE DEBUG] \u{1F4DD} lattice_set_value called:", { modelId, entityName, attributeKey, rawValue });
10726
+ let value = rawValue;
10727
+ const numValue = parseFloat(rawValue);
10728
+ if (!isNaN(numValue)) {
10729
+ value = numValue;
10730
+ } else if (rawValue.toLowerCase() === "true") {
10731
+ value = true;
10732
+ } else if (rawValue.toLowerCase() === "false") {
10733
+ value = false;
10734
+ }
10735
+ const entityId = entityName.toLowerCase().replace(/\s+/g, "_");
10736
+ if (context.db.latticeModels && modelId && /^[a-f0-9]{24}$/.test(modelId)) {
10737
+ try {
10738
+ const model = await context.db.latticeModels.findById(modelId);
10739
+ if (model) {
10740
+ const entity = model.data.entities.find((e) => e.id === entityId || e.name === entityName);
10741
+ if (entity) {
10742
+ const attrIndex = entity.attributes.findIndex((a) => a.key === attributeKey);
10743
+ const dataType = typeof value === "number" ? "number" : typeof value === "boolean" ? "boolean" : "string";
10744
+ const attributeData = {
10745
+ key: attributeKey,
10746
+ value,
10747
+ dataType,
10748
+ isComputed: false
10749
+ };
10750
+ if (attrIndex >= 0) {
10751
+ entity.attributes[attrIndex] = attributeData;
10752
+ } else {
10753
+ entity.attributes.push(attributeData);
10754
+ }
10755
+ entity.updatedAt = /* @__PURE__ */ new Date();
10756
+ await context.db.latticeModels.update({
10757
+ id: modelId,
10758
+ data: model.data,
10759
+ updatedAt: /* @__PURE__ */ new Date()
10760
+ });
10761
+ context.logger.info(`[Lattice] Set ${entityId}.${attributeKey} = ${value} in model ${modelId}`);
10762
+ } else {
10763
+ context.logger.warn(`[Lattice] Entity ${entityName} not found in model ${modelId}`);
10764
+ }
10765
+ } else {
10766
+ context.logger.warn(`[Lattice] Model ${modelId} not found in database`);
10767
+ }
10768
+ } catch (error) {
10769
+ context.logger.error(`[Lattice] Failed to persist value to database:`, error);
10770
+ }
10771
+ }
10772
+ return JSON.stringify({
10773
+ success: true,
10774
+ action: "SET_VALUE",
10775
+ modelId,
10776
+ data: {
10777
+ entityName,
10778
+ attributeKey,
10779
+ value
10780
+ },
10781
+ message: `Set ${entityName}.${attributeKey} = ${value}`
10782
+ });
10783
+ },
10784
+ toolSchema: {
10785
+ name: "lattice_set_value",
10786
+ description: `Set a specific value in a Lattice model.
10787
+
10788
+ **When to use:** When the user provides a specific number:
10789
+ - "Revenue in Q1 is 150,000"
10790
+ - "Set marketing spend to 50k for January"
10791
+ - "COGS is 40% of revenue" (use lattice_create_rule for formulas)
10792
+
10793
+ **Important:** This tool is for setting raw input values. For calculated values (formulas), use \`lattice_create_rule\` instead.
10794
+
10795
+ **Examples:**
10796
+ - "Q1 revenue is $100,000" \u2192 entityName="Revenue", attributeKey="Q1", value=100000
10797
+ - "Set headcount to 25" \u2192 entityName="Headcount", attributeKey="current", value=25`,
10798
+ parameters: {
10799
+ type: "object",
10800
+ properties: {
10801
+ modelId: {
10802
+ type: "string",
10803
+ description: "ID of the model"
10804
+ },
10805
+ entityName: {
10806
+ type: "string",
10807
+ description: "Name of the entity (line item, account, etc.)"
10808
+ },
10809
+ attributeKey: {
10810
+ type: "string",
10811
+ description: 'Period or attribute key (e.g., "Q1_2024", "current", "budget")'
10812
+ },
10813
+ value: {
10814
+ type: "string",
10815
+ description: "The value to set (will be parsed as number if numeric)"
10816
+ }
10817
+ },
10818
+ required: ["modelId", "entityName", "attributeKey", "value"]
10819
+ }
10820
+ }
10821
+ })
10822
+ };
10823
+ var latticeCreateRuleTool = {
10824
+ name: "lattice_create_rule",
10825
+ implementation: (context) => ({
10826
+ toolFn: async (params) => {
10827
+ const { modelId, name, description, formula } = params;
10828
+ console.log("[LATTICE DEBUG] \u{1F4D0} lattice_create_rule called:", { modelId, name, formula });
10829
+ const parsedRule = parseFormula(formula);
10830
+ const ruleId = `rule_${Date.now()}`;
10831
+ const ruleData = {
10832
+ id: ruleId,
10833
+ name,
10834
+ description: description || formula,
10835
+ type: "formula",
10836
+ definition: {
10837
+ operation: parsedRule.operation,
10838
+ inputs: parsedRule.inputs.map((ref) => ({
10839
+ type: "entity",
10840
+ ref
10841
+ })),
10842
+ output: {
10843
+ targetEntityId: parsedRule.outputEntity.toLowerCase().replace(/\s+/g, "_"),
10844
+ targetAttribute: "computed",
10845
+ dataType: "number"
10846
+ }
10847
+ },
10848
+ dependencies: parsedRule.inputs.map((i) => i.toLowerCase().replace(/\s+/g, "_")),
10849
+ priority: 0,
10850
+ enabled: true,
10851
+ createdAt: /* @__PURE__ */ new Date(),
10852
+ updatedAt: /* @__PURE__ */ new Date()
10853
+ };
10854
+ const outputEntityId = parsedRule.outputEntity.toLowerCase().replace(/\s+/g, "_");
10855
+ let entityCreatedMessage = "";
10856
+ if (context.db.latticeModels && modelId && /^[a-f0-9]{24}$/.test(modelId)) {
10857
+ try {
10858
+ const model = await context.db.latticeModels.findById(modelId);
10859
+ if (model) {
10860
+ const outputEntityExists = model.data.entities.some((e) => e.id === outputEntityId || e.name.toLowerCase() === parsedRule.outputEntity.toLowerCase());
10861
+ if (!outputEntityExists && parsedRule.outputEntity !== "unknown") {
10862
+ const now = /* @__PURE__ */ new Date();
10863
+ const newEntity = {
10864
+ id: outputEntityId,
10865
+ type: "line_item",
10866
+ name: parsedRule.outputEntity,
10867
+ displayName: parsedRule.outputEntity,
10868
+ attributes: [
10869
+ {
10870
+ key: "value",
10871
+ value: 0,
10872
+ dataType: "currency",
10873
+ isComputed: true
10874
+ },
10875
+ {
10876
+ key: "category",
10877
+ value: "Computed",
10878
+ dataType: "string",
10879
+ isComputed: false
10880
+ }
10881
+ ],
10882
+ metadata: { isComputed: true },
10883
+ createdAt: now,
10884
+ updatedAt: now
10885
+ };
10886
+ model.data.entities.push(newEntity);
10887
+ entityCreatedMessage = ` Created output entity "${parsedRule.outputEntity}".`;
10888
+ context.logger.info(`[Lattice] Auto-created output entity ${outputEntityId} for rule ${ruleId}`);
10889
+ }
10890
+ const existingIndex = model.rules.rules.findIndex((r) => r.id === ruleId || r.name === name);
10891
+ if (existingIndex >= 0) {
10892
+ model.rules.rules[existingIndex] = ruleData;
10893
+ } else {
10894
+ model.rules.rules.push(ruleData);
10895
+ }
10896
+ await context.db.latticeModels.update({
10897
+ id: modelId,
10898
+ data: model.data,
10899
+ rules: model.rules,
10900
+ updatedAt: /* @__PURE__ */ new Date()
10901
+ });
10902
+ context.logger.info(`[Lattice] Created rule ${ruleId} in model ${modelId}`);
10903
+ } else {
10904
+ context.logger.warn(`[Lattice] Model ${modelId} not found in database`);
10905
+ }
10906
+ } catch (error) {
10907
+ context.logger.error(`[Lattice] Failed to persist rule to database:`, error);
10908
+ }
10909
+ }
10910
+ return JSON.stringify({
10911
+ success: true,
10912
+ action: "CREATE_RULE",
10913
+ modelId,
10914
+ ruleId,
10915
+ data: {
10916
+ name,
10917
+ description,
10918
+ formula,
10919
+ parsed: parsedRule,
10920
+ outputEntityCreated: entityCreatedMessage !== ""
10921
+ },
10922
+ message: `Created rule "${name}": ${formula}.${entityCreatedMessage}`
10923
+ });
10924
+ },
10925
+ toolSchema: {
10926
+ name: "lattice_create_rule",
10927
+ description: `Create a formula or calculation rule in a Lattice model.
10928
+
10929
+ **When to use:** When the user defines a calculation:
10930
+ - "Gross profit equals revenue minus COGS"
10931
+ - "Net margin is net income divided by revenue times 100"
10932
+ - "Total expenses is the sum of all expense line items"
10933
+
10934
+ **IMPORTANT: For per-period calculations like "calculate X for each quarter", you MUST call this tool ONCE for EACH period.** For example, if asked to "calculate gross margin for each quarter", call this tool 4 times:
10935
+ 1. lattice_create_rule with formula "Q1 Gross Margin = Q1 Revenue - Q1 COGS"
10936
+ 2. lattice_create_rule with formula "Q2 Gross Margin = Q2 Revenue - Q2 COGS"
10937
+ 3. lattice_create_rule with formula "Q3 Gross Margin = Q3 Revenue - Q3 COGS"
10938
+ 4. lattice_create_rule with formula "Q4 Gross Margin = Q4 Revenue - Q4 COGS"
10939
+
10940
+ **Formula syntax (natural language):**
10941
+ - Arithmetic: "X equals Y plus Z", "A minus B", "C times D"
10942
+ - Aggregation: "sum of", "average of", "total"
10943
+ - Percentage: "X percent of Y", "as a percentage"
10944
+ - Comparison: "if X is greater than Y then A else B"
10945
+
10946
+ **Examples:**
10947
+ - "Gross Profit = Revenue - COGS"
10948
+ - "Gross Margin = Gross Profit / Revenue * 100"
10949
+ - "Total OpEx = sum of all Operating Expenses"
10950
+ - "YoY Growth = (Current Year - Prior Year) / Prior Year * 100"
10951
+ - "Q1 Gross Margin = Q1 Revenue - Q1 COGS" (per-period)`,
10952
+ parameters: {
10953
+ type: "object",
10954
+ properties: {
10955
+ modelId: {
10956
+ type: "string",
10957
+ description: "ID of the model"
10958
+ },
10959
+ name: {
10960
+ type: "string",
10961
+ description: 'Name for this rule (e.g., "Gross Profit Calculation")'
10962
+ },
10963
+ description: {
10964
+ type: "string",
10965
+ description: "Optional description of what this rule calculates"
10966
+ },
10967
+ formula: {
10968
+ type: "string",
10969
+ description: "The formula in natural language or equation format"
10970
+ }
10971
+ },
10972
+ required: ["modelId", "name", "formula"]
10973
+ }
10974
+ }
10975
+ })
10976
+ };
10977
+ var latticeQueryTool = {
10978
+ name: "lattice_query",
10979
+ implementation: () => ({
10980
+ toolFn: async (params) => {
10981
+ const { modelId, query } = params;
10982
+ const parsedQuery = parseQuery(query);
10983
+ return JSON.stringify({
10984
+ success: true,
10985
+ action: "QUERY",
10986
+ modelId,
10987
+ data: {
10988
+ query,
10989
+ parsed: parsedQuery
10990
+ },
10991
+ message: `Querying model for: ${query}`
10992
+ });
10993
+ },
10994
+ toolSchema: {
10995
+ name: "lattice_query",
10996
+ description: `Query a Lattice model for specific values or aggregations.
10997
+
10998
+ **When to use:** When the user asks about values in the model:
10999
+ - "What's Q1 gross margin?"
11000
+ - "Show me total revenue for 2024"
11001
+ - "What are all the expense categories?"
11002
+ - "Compare Q1 vs Q2 performance"
11003
+
11004
+ **Query types:**
11005
+ - Single value: "What is [entity] for [period]?"
11006
+ - Aggregation: "Total [entity] for [range]"
11007
+ - Comparison: "Compare [entity] across [periods]"
11008
+ - List: "Show all [entity type]"
11009
+
11010
+ **Examples:**
11011
+ - "What's Q2 revenue?" \u2192 Returns specific value
11012
+ - "Total revenue for 2024" \u2192 Sums Q1-Q4
11013
+ - "Compare gross margin Q1 vs Q2" \u2192 Side-by-side comparison`,
11014
+ parameters: {
11015
+ type: "object",
11016
+ properties: {
11017
+ modelId: {
11018
+ type: "string",
11019
+ description: "ID of the model to query"
11020
+ },
11021
+ query: {
11022
+ type: "string",
11023
+ description: "Natural language query about the model"
11024
+ }
11025
+ },
11026
+ required: ["modelId", "query"]
11027
+ }
11028
+ }
11029
+ })
11030
+ };
11031
+ var latticeExplainTool = {
11032
+ name: "lattice_explain",
11033
+ implementation: () => ({
11034
+ toolFn: async (params) => {
11035
+ const { modelId, entityName, attributeKey } = params;
11036
+ return JSON.stringify({
11037
+ success: true,
11038
+ action: "EXPLAIN",
11039
+ modelId,
11040
+ data: {
11041
+ entityName,
11042
+ attributeKey
11043
+ },
11044
+ message: `Explaining calculation for ${entityName}.${attributeKey}`
11045
+ });
11046
+ },
11047
+ toolSchema: {
11048
+ name: "lattice_explain",
11049
+ description: `Explain how a value in a Lattice model was calculated.
11050
+
11051
+ **When to use:** When the user wants to understand a calculation:
11052
+ - "How did you calculate gross profit?"
11053
+ - "Explain the Q2 margin number"
11054
+ - "Show me the formula for total expenses"
11055
+ - "Why is this number so high?"
11056
+
11057
+ This tool traces the calculation chain from the target value back through all its inputs and rules, providing a step-by-step explanation.`,
11058
+ parameters: {
11059
+ type: "object",
11060
+ properties: {
11061
+ modelId: {
11062
+ type: "string",
11063
+ description: "ID of the model"
11064
+ },
11065
+ entityName: {
11066
+ type: "string",
11067
+ description: "Name of the entity containing the value to explain"
11068
+ },
11069
+ attributeKey: {
11070
+ type: "string",
11071
+ description: "Period or attribute key of the value to explain"
11072
+ }
11073
+ },
11074
+ required: ["modelId", "entityName", "attributeKey"]
11075
+ }
11076
+ }
11077
+ })
11078
+ };
11079
+ function parseFormula(formula) {
11080
+ const normalized = formula.toLowerCase().trim();
11081
+ const equalsMatch = normalized.match(/^(.+?)\s*(?:=|equals?)\s*(.+)$/i);
11082
+ if (equalsMatch) {
11083
+ const [, output, expression] = equalsMatch;
11084
+ if (expression.includes("+") || expression.includes("plus")) {
11085
+ return {
11086
+ operation: "ADD",
11087
+ outputEntity: output,
11088
+ inputs: expression.split(/[+]|plus/i).map((s) => s.trim())
11089
+ };
11090
+ }
11091
+ if (expression.includes("-") || expression.includes("minus")) {
11092
+ return {
11093
+ operation: "SUBTRACT",
11094
+ outputEntity: output,
11095
+ inputs: expression.split(/[-]|minus/i).map((s) => s.trim())
11096
+ };
11097
+ }
11098
+ if (expression.includes("*") || expression.includes("times") || expression.includes("x")) {
11099
+ return {
11100
+ operation: "MULTIPLY",
11101
+ outputEntity: output,
11102
+ inputs: expression.split(/[*x]|times/i).map((s) => s.trim())
11103
+ };
11104
+ }
11105
+ if (expression.includes("/") || expression.includes("divided")) {
11106
+ return {
11107
+ operation: "DIVIDE",
11108
+ outputEntity: output,
11109
+ inputs: expression.split(/[/]|divided by/i).map((s) => s.trim())
11110
+ };
11111
+ }
11112
+ if (expression.includes("sum")) {
11113
+ return {
11114
+ operation: "SUM",
11115
+ outputEntity: output,
11116
+ inputs: [expression.replace(/sum of/i, "").trim()]
11117
+ };
11118
+ }
11119
+ }
11120
+ return {
11121
+ operation: "REFERENCE",
11122
+ outputEntity: "unknown",
11123
+ inputs: [formula]
11124
+ };
11125
+ }
11126
+ function parseQuery(query) {
11127
+ const normalized = query.toLowerCase();
11128
+ let type = "single_value";
11129
+ if (normalized.includes("total") || normalized.includes("sum")) {
11130
+ type = "aggregation";
11131
+ } else if (normalized.includes("compare") || normalized.includes("vs")) {
11132
+ type = "comparison";
11133
+ } else if (normalized.includes("list") || normalized.includes("show all")) {
11134
+ type = "list";
11135
+ }
11136
+ const entities = [];
11137
+ const periods = [];
11138
+ const periodPatterns = [/q[1-4]/gi, /\d{4}/g, /jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/gi];
11139
+ for (const pattern of periodPatterns) {
11140
+ const matches = query.match(pattern);
11141
+ if (matches) {
11142
+ periods.push(...matches);
11143
+ }
11144
+ }
11145
+ const commonEntities = ["revenue", "expenses", "profit", "margin", "income", "cost", "cogs", "ebitda"];
11146
+ for (const entity of commonEntities) {
11147
+ if (normalized.includes(entity)) {
11148
+ entities.push(entity);
11149
+ }
11150
+ }
11151
+ return { type, entities, periods };
11152
+ }
11153
+
10328
11154
  // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/editLocalFile/index.js
10329
11155
  import { promises as fs10 } from "fs";
10330
11156
  import { existsSync as existsSync7 } from "fs";
@@ -10796,7 +11622,14 @@ var cliOnlyTools = {
10796
11622
  // Shell execution
10797
11623
  bash_execute: bashExecuteTool,
10798
11624
  // Git operations
10799
- recent_changes: recentChangesTool
11625
+ recent_changes: recentChangesTool,
11626
+ // Lattice financial modeling tools
11627
+ lattice_create_model: latticeCreateModelTool,
11628
+ lattice_add_entity: latticeAddEntityTool,
11629
+ lattice_set_value: latticeSetValueTool,
11630
+ lattice_create_rule: latticeCreateRuleTool,
11631
+ lattice_query: latticeQueryTool,
11632
+ lattice_explain: latticeExplainTool
10800
11633
  };
10801
11634
  var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, imageProcessorLambdaName, tools = b4mTools) => {
10802
11635
  const context = {
@@ -10902,194 +11735,6 @@ var generateMcpTools = async (mcpData) => {
10902
11735
  return result;
10903
11736
  };
10904
11737
 
10905
- // ../../b4m-core/packages/services/dist/src/llm/agents/ExploreAgent.js
10906
- var ExploreAgent = (config) => ({
10907
- name: "explore",
10908
- description: "Fast research, exploration, and information search",
10909
- model: config?.model ?? "claude-3-5-haiku-20241022",
10910
- defaultThoroughness: config?.defaultThoroughness ?? "medium",
10911
- maxIterations: { quick: 2, medium: 5, very_thorough: 10 },
10912
- deniedTools: [
10913
- "image_generation",
10914
- "edit_image",
10915
- "deep_research",
10916
- "delegate_to_agent",
10917
- ...config?.extraDeniedTools ?? []
10918
- ],
10919
- allowedTools: config?.extraAllowedTools,
10920
- systemPrompt: `You are a research and exploration specialist. Your job is to search and analyze information efficiently.
10921
-
10922
- ## Focus Areas
10923
- - Finding relevant information across knowledge bases and the web
10924
- - Understanding context and patterns
10925
- - Providing clear, concise summaries
10926
-
10927
- ## Tool Usage
10928
- Use these tools strategically:
10929
- - \`web_search\` - Search the web for information
10930
- - \`web_fetch\` - Fetch and read full webpage content
10931
- - \`search_knowledge_base\` - Search the user's knowledge bases
10932
- - \`current_datetime\` - Get the current date and time
10933
-
10934
- ## Search Strategy
10935
- 1. Start with targeted searches using specific keywords
10936
- 2. Use web_fetch to read full content from promising results
10937
- 3. Cross-reference findings from multiple sources
10938
- 4. Check knowledge bases for relevant internal information
10939
-
10940
- ## Output Format
10941
- Provide a clear summary including:
10942
- 1. What you found (key facts, sources, patterns)
10943
- 2. Key insights or observations
10944
- 3. Relevant source references
10945
-
10946
- Be thorough but concise. Your summary will be used by the main agent.`
10947
- });
10948
-
10949
- // ../../b4m-core/packages/services/dist/src/llm/agents/PlanAgent.js
10950
- var PlanAgent = (config) => ({
10951
- name: "plan",
10952
- description: "Task breakdown and implementation planning",
10953
- model: config?.model ?? "claude-3-5-haiku-20241022",
10954
- defaultThoroughness: config?.defaultThoroughness ?? "medium",
10955
- maxIterations: { quick: 3, medium: 7, very_thorough: 12 },
10956
- deniedTools: [
10957
- "image_generation",
10958
- "edit_image",
10959
- "deep_research",
10960
- "delegate_to_agent",
10961
- ...config?.extraDeniedTools ?? []
10962
- ],
10963
- allowedTools: config?.extraAllowedTools,
10964
- systemPrompt: `You are a task planning specialist. Your job is to break down complex tasks into clear, actionable steps.
10965
-
10966
- ## Focus Areas
10967
- - Identifying dependencies and blockers
10968
- - Creating logical sequence of steps
10969
- - Researching context before planning
10970
-
10971
- ## Process
10972
- 1. First, research the topic to understand the current landscape
10973
- 2. Identify what already exists vs. what needs to be done
10974
- 3. Break down work into discrete, actionable steps
10975
- 4. Order steps by dependencies
10976
-
10977
- ## Output Format
10978
- Provide a structured plan:
10979
-
10980
- ### Prerequisites
10981
- - What must exist before starting
10982
-
10983
- ### Steps
10984
- 1. Step with clear deliverable
10985
- 2. Next step (depends on: Step 1)
10986
- ...
10987
-
10988
- ### Risks & Considerations
10989
- - Potential issues to watch for
10990
-
10991
- Be specific and actionable. Your plan will be used by the main agent.`
10992
- });
10993
-
10994
- // ../../b4m-core/packages/services/dist/src/llm/agents/ReviewAgent.js
10995
- var ReviewAgent = (config) => ({
10996
- name: "review",
10997
- description: "Content quality analysis and review",
10998
- model: config?.model ?? "claude-sonnet-4-5-20250929",
10999
- defaultThoroughness: config?.defaultThoroughness ?? "medium",
11000
- maxIterations: { quick: 3, medium: 8, very_thorough: 15 },
11001
- deniedTools: ["image_generation", "edit_image", "delegate_to_agent", ...config?.extraDeniedTools ?? []],
11002
- allowedTools: config?.extraAllowedTools,
11003
- systemPrompt: `You are a review specialist. Your job is to analyze content quality and identify issues.
11004
-
11005
- ## Focus Areas
11006
- - Content quality and accuracy
11007
- - Potential errors and edge cases
11008
- - Completeness and thoroughness
11009
- - Consistency and clarity
11010
-
11011
- ## Review Process
11012
- 1. Understand the context and purpose of the content
11013
- 2. Check for common issues (errors, inconsistencies, gaps)
11014
- 3. Verify claims against available sources
11015
- 4. Look for areas of improvement
11016
-
11017
- ## Output Format
11018
- Provide actionable feedback:
11019
-
11020
- ### Critical Issues
11021
- - Description of issue and why it matters
11022
-
11023
- ### Suggestions
11024
- - Improvement suggestion with rationale
11025
-
11026
- ### Positive Observations
11027
- - What's done well (optional)
11028
-
11029
- Focus on actionable feedback. Your review will be used by the main agent.`
11030
- });
11031
-
11032
- // ../../b4m-core/packages/services/dist/src/llm/agents/ProjectManagerAgent.js
11033
- var ProjectManagerAgent = (config) => ({
11034
- name: "project_manager",
11035
- description: "Project management via Jira and Confluence (create issues, search, update status, write docs). ALWAYS delegate Jira/Confluence requests to this agent \u2014 you do not have direct access to these tools",
11036
- model: config?.model ?? "claude-sonnet-4-5-20250929",
11037
- defaultThoroughness: config?.defaultThoroughness ?? "medium",
11038
- maxIterations: { quick: 3, medium: 8, very_thorough: 15 },
11039
- allowedTools: [...config?.extraAllowedTools ?? []],
11040
- deniedTools: [...config?.extraDeniedTools ?? []],
11041
- systemPrompt: `You are a project management specialist with access to Jira and Confluence. Your job is to help manage projects, issues, documentation, and team workflows.
11042
-
11043
- ## Capabilities
11044
-
11045
- ### Jira
11046
- - Search for issues using JQL
11047
- - Create, update, and transition issues
11048
- - Add comments and manage watchers
11049
- - List projects and issue types
11050
-
11051
- ### Confluence
11052
- - Search for documentation
11053
- - Create and update pages
11054
- - Browse spaces and page hierarchies
11055
-
11056
- ## Best Practices
11057
- 1. When searching Jira, use precise JQL queries (e.g., \`project = PROJ AND status = "In Progress"\`)
11058
- 2. When creating issues, always check available issue types first with \`atlassian__jira_list_issue_types\`
11059
- 3. When updating issue status, use \`atlassian__jira_update_issue_transition\` with the target status name
11060
- 4. When creating Confluence pages, use the user's personal space if no space is specified
11061
- 5. Always confirm destructive operations (delete) with the user before proceeding
11062
-
11063
- ## Output Format
11064
- Provide a clear summary of actions taken:
11065
- 1. What was done (created, updated, searched, etc.)
11066
- 2. Links or keys to relevant items (e.g., PROJ-123)
11067
- 3. Any issues or warnings encountered
11068
-
11069
- Be precise with issue keys and project names. Your results will be used by the main agent.`
11070
- });
11071
-
11072
- // ../../b4m-core/packages/services/dist/src/llm/agents/ServerAgentStore.js
11073
- var ServerAgentStore = class {
11074
- constructor() {
11075
- const builtInAgents = [ExploreAgent(), PlanAgent(), ReviewAgent(), ProjectManagerAgent()];
11076
- this.agents = new Map(builtInAgents.map((a) => [a.name, a]));
11077
- }
11078
- getAgent(name) {
11079
- return this.agents.get(name);
11080
- }
11081
- getAllAgents() {
11082
- return Array.from(this.agents.values());
11083
- }
11084
- getAgentNames() {
11085
- return Array.from(this.agents.keys());
11086
- }
11087
- hasAgent(name) {
11088
- return this.agents.has(name);
11089
- }
11090
- };
11091
- var serverAgentStore = new ServerAgentStore();
11092
-
11093
11738
  // ../../b4m-core/packages/services/dist/src/llm/ChatCompletionProcess.js
11094
11739
  import throttle2 from "lodash/throttle.js";
11095
11740
 
@@ -11110,6 +11755,7 @@ var QuestStartBodySchema = z139.object({
11110
11755
  enableMementos: z139.boolean().optional(),
11111
11756
  enableArtifacts: z139.boolean().optional(),
11112
11757
  enableAgents: z139.boolean().optional(),
11758
+ enableLattice: z139.boolean().optional(),
11113
11759
  promptMeta: PromptMetaZodSchema,
11114
11760
  tools: z139.array(z139.union([b4mLLMTools, z139.string()])).optional(),
11115
11761
  mcpServers: z139.array(z139.string()).optional(),
@@ -11954,7 +12600,7 @@ async function executeCommandHook(hook, context) {
11954
12600
  }
11955
12601
  }
11956
12602
  var MAX_PATTERN_LENGTH = 200;
11957
- function matchesToolPattern2(toolName, pattern) {
12603
+ function matchesToolPattern(toolName, pattern) {
11958
12604
  if (pattern.length > MAX_PATTERN_LENGTH) {
11959
12605
  console.warn(`Hook pattern exceeds max length (${MAX_PATTERN_LENGTH}), skipping: ${pattern.slice(0, 50)}...`);
11960
12606
  return false;
@@ -11972,7 +12618,7 @@ async function executeHooks(hooks, context) {
11972
12618
  }
11973
12619
  const matchingHooks = [];
11974
12620
  for (const matcher of hooks) {
11975
- const shouldMatch = !matcher.matcher || !context.tool_name || matchesToolPattern2(context.tool_name, matcher.matcher);
12621
+ const shouldMatch = !matcher.matcher || !context.tool_name || matchesToolPattern(context.tool_name, matcher.matcher);
11976
12622
  if (shouldMatch) {
11977
12623
  matchingHooks.push(...matcher.hooks);
11978
12624
  }
@@ -13989,7 +14635,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
13989
14635
  // package.json
13990
14636
  var package_default = {
13991
14637
  name: "@bike4mind/cli",
13992
- version: "0.2.29-subagent-delegation.18906+045a1d01f",
14638
+ version: "0.2.29",
13993
14639
  type: "module",
13994
14640
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
13995
14641
  license: "UNLICENSED",
@@ -14103,10 +14749,10 @@ var package_default = {
14103
14749
  },
14104
14750
  devDependencies: {
14105
14751
  "@bike4mind/agents": "0.1.0",
14106
- "@bike4mind/common": "2.50.1-subagent-delegation.18906+045a1d01f",
14107
- "@bike4mind/mcp": "1.29.1-subagent-delegation.18906+045a1d01f",
14108
- "@bike4mind/services": "2.48.1-subagent-delegation.18906+045a1d01f",
14109
- "@bike4mind/utils": "2.5.1-subagent-delegation.18906+045a1d01f",
14752
+ "@bike4mind/common": "2.51.0",
14753
+ "@bike4mind/mcp": "1.30.0",
14754
+ "@bike4mind/services": "2.49.0",
14755
+ "@bike4mind/utils": "2.6.0",
14110
14756
  "@types/better-sqlite3": "^7.6.13",
14111
14757
  "@types/diff": "^5.0.9",
14112
14758
  "@types/jsonwebtoken": "^9.0.4",
@@ -14124,7 +14770,7 @@ var package_default = {
14124
14770
  optionalDependencies: {
14125
14771
  "@vscode/ripgrep": "^1.17.0"
14126
14772
  },
14127
- gitHead: "045a1d01f262ab4133a6caaaa9d56debaa965143"
14773
+ gitHead: "dd78e3f7ac6eb31fbbae8df3be1f33310779a9d5"
14128
14774
  };
14129
14775
 
14130
14776
  // src/config/constants.ts
@@ -14133,25 +14779,25 @@ var MODEL_NAME_COLUMN_WIDTH = 18;
14133
14779
  var USAGE_CACHE_TTL = 5 * 60 * 1e3;
14134
14780
 
14135
14781
  // src/agents/toolFilter.ts
14136
- function matchesToolPattern3(toolName, pattern) {
14782
+ function matchesToolPattern2(toolName, pattern) {
14137
14783
  const regexPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
14138
14784
  return new RegExp(`^${regexPattern}$`).test(toolName);
14139
14785
  }
14140
- function matchesAnyPattern2(toolName, patterns) {
14141
- return patterns.some((pattern) => matchesToolPattern3(toolName, pattern));
14786
+ function matchesAnyPattern(toolName, patterns) {
14787
+ return patterns.some((pattern) => matchesToolPattern2(toolName, pattern));
14142
14788
  }
14143
- function filterToolsByPatterns2(allTools, allowedPatterns, deniedPatterns) {
14789
+ function filterToolsByPatterns(allTools, allowedPatterns, deniedPatterns) {
14144
14790
  return allTools.filter((tool) => {
14145
14791
  const toolName = tool.toolSchema.name;
14146
14792
  if (deniedPatterns && deniedPatterns.length > 0) {
14147
- if (matchesAnyPattern2(toolName, deniedPatterns)) {
14793
+ if (matchesAnyPattern(toolName, deniedPatterns)) {
14148
14794
  return false;
14149
14795
  }
14150
14796
  }
14151
14797
  if (!allowedPatterns || allowedPatterns.length === 0) {
14152
14798
  return true;
14153
14799
  }
14154
- return matchesAnyPattern2(toolName, allowedPatterns);
14800
+ return matchesAnyPattern(toolName, allowedPatterns);
14155
14801
  });
14156
14802
  }
14157
14803
 
@@ -14422,7 +15068,7 @@ var SubagentOrchestrator = class {
14422
15068
  this.deps.configStore,
14423
15069
  this.deps.apiClient
14424
15070
  );
14425
- const filteredTools = filterToolsByPatterns2(allTools, toolFilter.allowedTools, toolFilter.deniedTools);
15071
+ const filteredTools = filterToolsByPatterns(allTools, toolFilter.allowedTools, toolFilter.deniedTools);
14426
15072
  if (this.deps.customCommandStore) {
14427
15073
  const skillTool = createSkillTool({
14428
15074
  customCommandStore: this.deps.customCommandStore,