@bike4mind/cli 0.2.10-fix-b4m-cli-flicker.17235 → 0.2.10-github-update-projects.17240
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/{artifactExtractor-JAGU7QRL.js → artifactExtractor-CDVTG5A7.js} +1 -1
- package/dist/{chunk-VZU4Z7WI.js → chunk-5YF7VMO5.js} +2 -2
- package/dist/{chunk-GO75FMLY.js → chunk-AGGKFMPH.js} +2 -2
- package/dist/{chunk-DJPXSSP4.js → chunk-EN7MWHVV.js} +14 -8
- package/dist/{chunk-AQBZVAYO.js → chunk-LLQQ6KV2.js} +2 -2
- package/dist/{chunk-GCVIRGIN.js → chunk-R4KVFPRM.js} +1 -1
- package/dist/{create-ZDOTF7XD.js → create-BYLQBYID.js} +3 -3
- package/dist/index.js +211 -153
- package/dist/{llmMarkdownGenerator-LXUGJ7QH.js → llmMarkdownGenerator-HDOZIABH.js} +1 -1
- package/dist/{markdownGenerator-IMDG6OX6.js → markdownGenerator-MHBZWE56.js} +1 -1
- package/dist/{mementoService-TURUS3OH.js → mementoService-ZGTT5J2H.js} +3 -3
- package/dist/{src-YNY32ELR.js → src-BHBRMYPS.js} +1 -1
- package/dist/{src-6ZRXGE5J.js → src-GJ2QHH7Z.js} +2 -2
- package/dist/{subtractCredits-GOVKM3IR.js → subtractCredits-KGW5JBVX.js} +3 -3
- package/package.json +6 -6
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BadRequestError,
|
|
4
4
|
secureParameters
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-R4KVFPRM.js";
|
|
6
6
|
import {
|
|
7
7
|
GenericCreditDeductTransaction,
|
|
8
8
|
ImageEditUsageTransaction,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
RealtimeVoiceUsageTransaction,
|
|
11
11
|
TextGenerationUsageTransaction,
|
|
12
12
|
TransferCreditTransaction
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-EN7MWHVV.js";
|
|
14
14
|
|
|
15
15
|
// ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
|
|
16
16
|
import { z } from "zod";
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
getSettingsByNames,
|
|
7
7
|
obfuscateApiKey,
|
|
8
8
|
secureParameters
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-R4KVFPRM.js";
|
|
10
10
|
import {
|
|
11
11
|
ApiKeyType,
|
|
12
12
|
MementoTier,
|
|
13
13
|
isSupportedEmbeddingModel
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-EN7MWHVV.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/apiKeyService/get.js
|
|
17
17
|
import { z } from "zod";
|
|
@@ -5448,10 +5448,10 @@ var atlassianDescriptions = {
|
|
|
5448
5448
|
confluence_list_pages: "List all pages in a Confluence space. Use usePersonalSpace: true to automatically list pages from your personal space, provide a specific spaceId, or omit both to list pages from all accessible spaces.",
|
|
5449
5449
|
confluence_delete_page: "\u26A0\uFE0F DESTRUCTIVE PREVIEW-FIRST TOOL: ALWAYS call TWICE. First call: MUST use confirmed=false (or omit) to show preview. Second call: Use confirmed=true ONLY after user explicitly confirms. PERMANENTLY deletes a Confluence page. Cannot be undone.",
|
|
5450
5450
|
// Jira tools
|
|
5451
|
-
jira_get_issue: "Retrieve a Jira issue by key (e.g., PROJ-123). Returns issue details including summary, description, status, assignee, and custom fields.",
|
|
5452
|
-
jira_create_issue: "Create a new Jira issue. Requires project key, summary, issue type name. Optionally set description, priority, assignee, labels, and parent (for subtasks).",
|
|
5453
|
-
jira_update_issue: "Update an existing Jira issue. Can update summary, description, priority, labels, and other fields.",
|
|
5454
|
-
jira_search_issues: "Search for Jira issues using JQL (Jira Query Language). Returns matching issues with full details.",
|
|
5451
|
+
jira_get_issue: "[JIRA ONLY] Retrieve a Jira issue by key (e.g., PROJ-123, not #1). DO NOT use for GitHub issues - if user mentions owner/repo format, use GitHub tools instead. Returns issue details including summary, description, status, assignee, and custom fields.",
|
|
5452
|
+
jira_create_issue: "[JIRA ONLY] Create a new Jira issue. DO NOT use for GitHub repositories in owner/repo format. Requires project key, summary, issue type name. Optionally set description, priority, assignee, labels, and parent (for subtasks).",
|
|
5453
|
+
jira_update_issue: "[JIRA ONLY] Update an existing Jira issue. DO NOT use for GitHub issues or repositories in owner/repo format - use update_issue or update_project_item_fields instead. Can update summary, description, priority, labels, and other fields.",
|
|
5454
|
+
jira_search_issues: "[JIRA ONLY] Search for Jira issues using JQL (Jira Query Language). DO NOT use when user mentions GitHub repositories in owner/repo format. Returns matching issues with full details.",
|
|
5455
5455
|
jira_list_projects: "List all accessible Jira projects. Returns project keys, names, and details. Use this to discover project keys when creating or updating issues.",
|
|
5456
5456
|
jira_get_project: "Get detailed information about a specific Jira project.",
|
|
5457
5457
|
jira_list_issue_types: "List available issue types for a project (e.g., Task, Epic, Subtask). Use this to discover available issue type names, especially for projects with custom issue types.",
|
|
@@ -5468,10 +5468,10 @@ var MCP_PROVIDER_METADATA = {
|
|
|
5468
5468
|
github: {
|
|
5469
5469
|
defaultToolDescriptions: {
|
|
5470
5470
|
// Core GitHub tools (must match b4m-core/packages/mcp/src/github/index.ts)
|
|
5471
|
-
create_issue: "Create a new issue in a GitHub repository. Requires repository owner, repository name, issue title, and optional body, labels, and assignees.",
|
|
5472
|
-
update_issue: "Update an existing GitHub issue. Can modify title, body, state (open/closed), labels, assignees, and issue type
|
|
5473
|
-
list_issues:
|
|
5474
|
-
get_issue: "Get detailed information about a specific GitHub issue by number. Returns full issue details including body, comments count, milestone, and
|
|
5471
|
+
create_issue: "[GITHUB ONLY] Create a new issue in a GitHub repository. Use when user mentions owner/repo format. DO NOT use jira_create_issue for GitHub repos. Requires repository owner, repository name, issue title, and optional body, labels, and assignees.",
|
|
5472
|
+
update_issue: "[GITHUB ONLY] Update an existing GitHub issue in owner/repo format. DO NOT use jira_update_issue for GitHub - jira_update_issue is ONLY for Jira issues with keys like PROJ-123. Can modify title, body, state (open/closed), labels, assignees, and issue type. Use list_org_issue_types to see available types. Requires repository owner, repository name, and issue number. IMPORTANT: DO NOT use this tool to update GitHub Projects v2 fields like Priority, Size, Iteration, Estimate, Start Date, Target Date, or Status - those are PROJECT FIELDS and require update_project_item_fields instead. This tool is ONLY for standard issue properties (title, body, state, labels, assignees).",
|
|
5473
|
+
list_issues: "[GITHUB ONLY] List issues for a GitHub repository in owner/repo format. DO NOT use jira_search_issues for GitHub. Can filter by state, labels, assignee, type. Returns issue details including title, body, status, and metadata.",
|
|
5474
|
+
get_issue: "[GITHUB ONLY] Get detailed information about a specific GitHub issue by number. Use when user mentions owner/repo and issue #1. DO NOT use jira_get_issue. Returns full issue details including body, comments count, milestone, timestamps, node_id (for Projects v2), and associated GitHub Projects.",
|
|
5475
5475
|
search_code: "Search for code across GitHub repositories using GitHub code search syntax. Returns matching code snippets with file paths, line numbers, and repository information.",
|
|
5476
5476
|
// Repository discovery and management
|
|
5477
5477
|
list_repositories: "List all GitHub repositories accessible to the authenticated user. Supports filtering by visibility (public/private) and affiliation (owner/collaborator/organization_member). Returns repository metadata including name, description, language, stars, and activity.",
|
|
@@ -5485,6 +5485,12 @@ var MCP_PROVIDER_METADATA = {
|
|
|
5485
5485
|
list_commits: "List commit history for a GitHub repository with optional filters (branch, file path, author). Returns commit SHA, message, author, date, and statistics.",
|
|
5486
5486
|
get_commit: "Get detailed information about a specific commit including full message, author, committer, file changes, and diff statistics.",
|
|
5487
5487
|
list_org_issue_types: "List available native GitHub issue types for an organization (Bug, Feature, Task, etc.). Use this to discover what issue types can be set on issues in the organization.",
|
|
5488
|
+
// GitHub Projects v2 tools
|
|
5489
|
+
list_org_projects: "List all GitHub Projects (v2) for an organization. Returns project IDs, titles, descriptions, and URLs. Use this to discover available projects before managing project fields.",
|
|
5490
|
+
list_project_fields: "List all fields for a GitHub Project (Status, Priority, Size, Iteration, etc.). Returns field IDs, data types, and available options (for single-select fields). Required to get field IDs and option IDs before updating project item fields.",
|
|
5491
|
+
get_project_item: "Get a GitHub issue as a project item. CRITICAL: This returns the item_id (starts with PVTI_) that you MUST use for update_project_item_fields - DO NOT use the issue node_id (starts with I_) from get_issue. WORKFLOW: Always call this BEFORE update_project_item_fields to get the correct item_id. If this tool returns an error (issue not in project), you must call add_issue_to_project first. Returns current field values and the item_id (PVTI_) needed for updates.",
|
|
5492
|
+
add_issue_to_project: '\u26A0\uFE0F PREVIEW-FIRST TOOL: Add a GitHub issue to a project. CRITICAL: Call this when get_project_item fails (issue not in project yet). After adding, call get_project_item to get the item_id (PVTI_) before updating fields. Use get_issue to get the issue node_id first. IMPORTANT: Always include display parameters for human-readable preview: display_project_name (from list_org_projects), display_issue_title (from get_issue like "#2 - Login issue"), and display_repository (from get_issue like "owner/repo"). Returns the new project item ID.',
|
|
5493
|
+
update_project_item_fields: '\u26A0\uFE0F PREVIEW-FIRST TOOL: ALWAYS call TWICE. Update one or more fields on a GitHub Project item (Priority, Size, Iteration, Estimate, Start Date, Target Date, Status). USE THIS TOOL when user asks to update Priority, Size, Iteration, Estimate, Start Date, Target Date, or Status on an issue that belongs to a GitHub Project - these are PROJECT FIELDS, not issue labels or properties. Supports both single field updates and batch updates. WORKFLOW: (1) Call get_project_item to get the item_id (starts with PVTI_) - if this fails, the issue is not in the project yet, so call add_issue_to_project first. (2) Call list_project_fields to get field IDs. (3) Call update_project_item_fields with the PVTI_ item_id. CRITICAL: The item_id parameter MUST be a ProjectV2Item ID (starts with PVTI_) from get_project_item, NOT the issue node_id (starts with I_) from get_issue. Using the wrong ID will cause all updates to fail. For each field in updates array, provide: field_id, value (actual ID/number/date), field_name (human name), new_value (human-readable for preview). Example: {item_id: "PVTI_lADO...", updates: [{field_id: "PVTF_...", value: "option_id", field_name: "Priority", new_value: "P1"}]}',
|
|
5488
5494
|
// Legacy tool names (for backwards compatibility)
|
|
5489
5495
|
github_list_repositories: "List GitHub repositories accessible to the connected account.",
|
|
5490
5496
|
github_get_repository: "Fetch detailed information about a specific GitHub repository.",
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
getSettingsMap,
|
|
8
8
|
getSettingsValue,
|
|
9
9
|
secureParameters
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-R4KVFPRM.js";
|
|
11
11
|
import {
|
|
12
12
|
KnowledgeType,
|
|
13
13
|
SupportedFabFileMimeTypes
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-EN7MWHVV.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/fabFileService/create.js
|
|
17
17
|
import { z } from "zod";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
dayjsConfig_default,
|
|
17
17
|
extractSnippetMeta,
|
|
18
18
|
settingsMap
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-EN7MWHVV.js";
|
|
20
20
|
|
|
21
21
|
// ../../b4m-core/packages/utils/dist/src/storage/S3Storage.js
|
|
22
22
|
import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3";
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createFabFile,
|
|
4
4
|
createFabFileSchema
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-LLQQ6KV2.js";
|
|
6
|
+
import "./chunk-R4KVFPRM.js";
|
|
7
7
|
import "./chunk-AMDXHL6S.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-EN7MWHVV.js";
|
|
9
9
|
import "./chunk-PDX44BCA.js";
|
|
10
10
|
export {
|
|
11
11
|
createFabFile,
|
package/dist/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
getEffectiveApiKey,
|
|
5
5
|
getOpenWeatherKey,
|
|
6
6
|
getSerperKey
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-AGGKFMPH.js";
|
|
8
|
+
import "./chunk-5YF7VMO5.js";
|
|
9
|
+
import "./chunk-LLQQ6KV2.js";
|
|
10
10
|
import {
|
|
11
11
|
BFLImageService,
|
|
12
12
|
BaseStorage,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
OpenAIBackend,
|
|
16
16
|
OpenAIImageService,
|
|
17
17
|
XAIImageService
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-R4KVFPRM.js";
|
|
19
19
|
import {
|
|
20
20
|
Logger
|
|
21
21
|
} from "./chunk-AMDXHL6S.js";
|
|
@@ -73,25 +73,26 @@ import {
|
|
|
73
73
|
XAI_IMAGE_MODELS,
|
|
74
74
|
b4mLLMTools,
|
|
75
75
|
getMcpProviderMetadata
|
|
76
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-EN7MWHVV.js";
|
|
77
77
|
import {
|
|
78
78
|
__require
|
|
79
79
|
} from "./chunk-PDX44BCA.js";
|
|
80
80
|
|
|
81
81
|
// src/index.tsx
|
|
82
|
-
import
|
|
83
|
-
import { render, Box as
|
|
82
|
+
import React16, { useState as useState8, useEffect as useEffect3, useCallback, useRef } from "react";
|
|
83
|
+
import { render, Box as Box15, Text as Text15, useApp, useInput as useInput6 } from "ink";
|
|
84
|
+
import { execSync } from "child_process";
|
|
84
85
|
import { v4 as uuidv49 } from "uuid";
|
|
85
86
|
|
|
86
87
|
// src/components/App.tsx
|
|
87
|
-
import
|
|
88
|
-
import { Box as
|
|
88
|
+
import React10, { useState as useState4 } from "react";
|
|
89
|
+
import { Box as Box9, Text as Text9 } from "ink";
|
|
89
90
|
|
|
90
91
|
// src/components/StatusBar.tsx
|
|
91
92
|
import React from "react";
|
|
92
93
|
import { Box, Text } from "ink";
|
|
93
94
|
var StatusBar = React.memo(function StatusBar2({ sessionName, model, tokenUsage }) {
|
|
94
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", justifyContent: "space-between", width: "100%",
|
|
95
|
+
return /* @__PURE__ */ React.createElement(Box, { borderStyle: "single", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "row", justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "green", bold: true }, "\u{1F4DD} Session:"), /* @__PURE__ */ React.createElement(Text, null, sessionName)), /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "blue", bold: true }, "\u{1F916} Model:"), /* @__PURE__ */ React.createElement(Text, null, model)), /* @__PURE__ */ React.createElement(Box, { gap: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "yellow", bold: true }, "\u{1F4CA} Tokens:"), /* @__PURE__ */ React.createElement(Text, null, tokenUsage.toLocaleString()))));
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
// src/components/InputPrompt.tsx
|
|
@@ -732,11 +733,13 @@ function findAtTrigger(value) {
|
|
|
732
733
|
}
|
|
733
734
|
function InputPrompt({
|
|
734
735
|
onSubmit,
|
|
736
|
+
onBashCommand,
|
|
735
737
|
onImageDetected,
|
|
736
738
|
disabled = false,
|
|
737
739
|
history = [],
|
|
738
740
|
prefillInput,
|
|
739
|
-
onPrefillConsumed
|
|
741
|
+
onPrefillConsumed,
|
|
742
|
+
onBashModeChange
|
|
740
743
|
}) {
|
|
741
744
|
const [value, setValue] = useState2("");
|
|
742
745
|
const [selectedIndex, setSelectedIndex] = useState2(0);
|
|
@@ -751,6 +754,10 @@ function InputPrompt({
|
|
|
751
754
|
}, [prefillInput, onPrefillConsumed]);
|
|
752
755
|
const [fileAutocomplete, setFileAutocomplete] = useState2(null);
|
|
753
756
|
const [fileSelectedIndex, setFileSelectedIndex] = useState2(0);
|
|
757
|
+
const isBashMode = value.startsWith("!");
|
|
758
|
+
useEffect(() => {
|
|
759
|
+
onBashModeChange?.(isBashMode);
|
|
760
|
+
}, [isBashMode, onBashModeChange]);
|
|
754
761
|
const shouldShowCommandAutocomplete = value.startsWith("/") && !disabled && !fileAutocomplete?.active;
|
|
755
762
|
const commandQuery = shouldShowCommandAutocomplete ? value.slice(1) : "";
|
|
756
763
|
const filteredCommands = useMemo(() => {
|
|
@@ -857,6 +864,16 @@ function InputPrompt({
|
|
|
857
864
|
onSubmit(commandText);
|
|
858
865
|
return;
|
|
859
866
|
}
|
|
867
|
+
if (isBashMode && onBashCommand) {
|
|
868
|
+
const command = input.slice(1).trim();
|
|
869
|
+
if (command) {
|
|
870
|
+
onBashCommand(command);
|
|
871
|
+
setValue("");
|
|
872
|
+
setHistoryIndex(-1);
|
|
873
|
+
setFileAutocomplete(null);
|
|
874
|
+
}
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
860
877
|
onSubmit(input);
|
|
861
878
|
setValue("");
|
|
862
879
|
setHistoryIndex(-1);
|
|
@@ -887,14 +904,19 @@ function InputPrompt({
|
|
|
887
904
|
setFileAutocomplete(null);
|
|
888
905
|
}
|
|
889
906
|
};
|
|
890
|
-
|
|
907
|
+
const getPlaceholder = () => {
|
|
908
|
+
if (disabled) return "Thinking...";
|
|
909
|
+
if (isBashMode) return "Enter shell command to execute...";
|
|
910
|
+
return "Type your message, /help for commands, @file to reference, or ! for bash";
|
|
911
|
+
};
|
|
912
|
+
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text5, { bold: true, color: isBashMode ? "yellow" : "cyan" }, isBashMode ? "$ " : "> "), /* @__PURE__ */ React5.createElement(
|
|
891
913
|
CustomTextInput,
|
|
892
914
|
{
|
|
893
915
|
key: inputKey,
|
|
894
916
|
value,
|
|
895
917
|
onChange: handleChange,
|
|
896
918
|
onSubmit: handleSubmit,
|
|
897
|
-
placeholder:
|
|
919
|
+
placeholder: getPlaceholder(),
|
|
898
920
|
showCursor: !disabled
|
|
899
921
|
}
|
|
900
922
|
)), shouldShowCommandAutocomplete && /* @__PURE__ */ React5.createElement(CommandAutocomplete, { commands: filteredCommands, selectedIndex }), fileAutocomplete?.active && /* @__PURE__ */ React5.createElement(FileAutocomplete, { files: filteredFiles, selectedIndex: fileSelectedIndex, query: fileAutocomplete.query }));
|
|
@@ -918,25 +940,12 @@ var useCliStore = create((set) => ({
|
|
|
918
940
|
// Session state
|
|
919
941
|
session: null,
|
|
920
942
|
setSession: (session) => set({ session }),
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
addPendingMessage: (message) => set((state) => ({ pendingMessages: [...state.pendingMessages, message] })),
|
|
924
|
-
updatePendingMessage: (index, message) => set((state) => {
|
|
925
|
-
const updated = [...state.pendingMessages];
|
|
926
|
-
updated[index] = message;
|
|
927
|
-
return { pendingMessages: updated };
|
|
928
|
-
}),
|
|
929
|
-
clearPendingMessages: () => set({ pendingMessages: [] }),
|
|
930
|
-
completePendingMessage: (index, finalMessage) => set((state) => {
|
|
931
|
-
const pending = [...state.pendingMessages];
|
|
932
|
-
pending.splice(index, 1);
|
|
933
|
-
const session = state.session;
|
|
934
|
-
if (!session) return { pendingMessages: pending };
|
|
943
|
+
addMessage: (message) => set((state) => {
|
|
944
|
+
if (!state.session) return state;
|
|
935
945
|
return {
|
|
936
|
-
pendingMessages: pending,
|
|
937
946
|
session: {
|
|
938
|
-
...session,
|
|
939
|
-
messages: [...session.messages,
|
|
947
|
+
...state.session,
|
|
948
|
+
messages: [...state.session.messages, message],
|
|
940
949
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
941
950
|
}
|
|
942
951
|
};
|
|
@@ -1240,26 +1249,6 @@ function ConfigEditor({ config, availableModels, onSave, onClose }) {
|
|
|
1240
1249
|
})), /* @__PURE__ */ React9.createElement(Box8, { borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React9.createElement(Text8, { dimColor: true }, "\u2191/\u2193: Navigate | Space/\u2190/\u2192: Change | q/Esc: Save & Exit")));
|
|
1241
1250
|
}
|
|
1242
1251
|
|
|
1243
|
-
// src/components/MessageItem.tsx
|
|
1244
|
-
import React10 from "react";
|
|
1245
|
-
import { Box as Box9, Text as Text9 } from "ink";
|
|
1246
|
-
function MessageItem({ message }) {
|
|
1247
|
-
const isUser = message.role === "user";
|
|
1248
|
-
return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: isUser ? "cyan" : "green" }, isUser ? "\u{1F464} You" : "\u{1F916} Assistant"), isUser && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), isUser && message.content && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { backgroundColor: "whiteBright", color: "black" }, " ", message.content, " ")), !isUser && message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " ", "tools used, ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
1249
|
-
if (step.type === "thought") {
|
|
1250
|
-
return /* @__PURE__ */ React10.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` ${step.content.slice(0, 200)}${step.content.length > 200 ? "..." : ""}`));
|
|
1251
|
-
}
|
|
1252
|
-
if (step.type === "action") {
|
|
1253
|
-
const toolName = step.metadata?.toolName || "unknown";
|
|
1254
|
-
const toolInput = step.metadata?.toolInput;
|
|
1255
|
-
const observationStep = message.metadata.steps[idx + 1];
|
|
1256
|
-
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
1257
|
-
return /* @__PURE__ */ React10.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` Result: ${typeof result === "string" ? result.slice(0, 200) : JSON.stringify(result).slice(0, 200)}${(typeof result === "string" ? result.length : JSON.stringify(result).length) > 200 ? "..." : ""}`));
|
|
1258
|
-
}
|
|
1259
|
-
return null;
|
|
1260
|
-
}).filter(Boolean)), !isUser && message.content !== "..." && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2, marginTop: message.metadata?.steps?.length ? 1 : 0 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React10.createElement(Text9, { color: "yellow" }, "\u26A0\uFE0F ", message.content) : /* @__PURE__ */ React10.createElement(Text9, null, message.content)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)));
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
1252
|
// src/utils/processFileReferences.ts
|
|
1264
1253
|
import * as fs2 from "fs";
|
|
1265
1254
|
import * as path2 from "path";
|
|
@@ -1378,6 +1367,7 @@ function hasFileReferences(message) {
|
|
|
1378
1367
|
function App({
|
|
1379
1368
|
onMessage,
|
|
1380
1369
|
onCommand,
|
|
1370
|
+
onBashCommand,
|
|
1381
1371
|
onPermissionResponse,
|
|
1382
1372
|
onImageDetected,
|
|
1383
1373
|
commandHistory = [],
|
|
@@ -1388,7 +1378,6 @@ function App({
|
|
|
1388
1378
|
onPrefillConsumed
|
|
1389
1379
|
}) {
|
|
1390
1380
|
const messages = useCliStore((state) => state.session?.messages || []);
|
|
1391
|
-
const pendingMessages = useCliStore((state) => state.pendingMessages);
|
|
1392
1381
|
const sessionName = useCliStore((state) => state.session?.name || "New Session");
|
|
1393
1382
|
const currentModel = useCliStore((state) => state.session?.model || "claude-sonnet-4-5-20250929");
|
|
1394
1383
|
const totalTokens = useCliStore((state) => state.session?.metadata.totalTokens || 0);
|
|
@@ -1398,7 +1387,8 @@ function App({
|
|
|
1398
1387
|
const setShowConfigEditor = useCliStore((state) => state.setShowConfigEditor);
|
|
1399
1388
|
const exitRequested = useCliStore((state) => state.exitRequested);
|
|
1400
1389
|
const setIsThinking = useCliStore((state) => state.setIsThinking);
|
|
1401
|
-
const
|
|
1390
|
+
const [isBashMode, setIsBashMode] = useState4(false);
|
|
1391
|
+
const handleSubmit = React10.useCallback(
|
|
1402
1392
|
async (input) => {
|
|
1403
1393
|
const trimmed = input.trim();
|
|
1404
1394
|
if (!trimmed) return;
|
|
@@ -1427,7 +1417,7 @@ ${errorBlock}`;
|
|
|
1427
1417
|
},
|
|
1428
1418
|
[onMessage, onCommand, setIsThinking]
|
|
1429
1419
|
);
|
|
1430
|
-
return /* @__PURE__ */
|
|
1420
|
+
return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column" }, /* @__PURE__ */ React10.createElement(StatusBar, { sessionName, model: currentModel, tokenUsage: totalTokens }), showConfigEditor && config && onSaveConfig ? /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React10.createElement(
|
|
1431
1421
|
ConfigEditor,
|
|
1432
1422
|
{
|
|
1433
1423
|
config,
|
|
@@ -1435,7 +1425,7 @@ ${errorBlock}`;
|
|
|
1435
1425
|
onSave: onSaveConfig,
|
|
1436
1426
|
onClose: () => setShowConfigEditor(false)
|
|
1437
1427
|
}
|
|
1438
|
-
)) : permissionPrompt ? /* @__PURE__ */
|
|
1428
|
+
)) : permissionPrompt ? /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React10.createElement(
|
|
1439
1429
|
PermissionPrompt,
|
|
1440
1430
|
{
|
|
1441
1431
|
toolName: permissionPrompt.toolName,
|
|
@@ -1444,34 +1434,52 @@ ${errorBlock}`;
|
|
|
1444
1434
|
canBeTrusted: permissionPrompt.canBeTrusted,
|
|
1445
1435
|
onResponse: onPermissionResponse
|
|
1446
1436
|
}
|
|
1447
|
-
)) : /* @__PURE__ */
|
|
1437
|
+
)) : /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column" }, messages.map((message, index) => /* @__PURE__ */ React10.createElement(Box9, { key: `${message.timestamp}-${message.role}-${index}`, flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React10.createElement(MessageItem, { message })))), /* @__PURE__ */ React10.createElement(AgentThinking, null), exitRequested && /* @__PURE__ */ React10.createElement(Box9, { paddingX: 1, marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Text9, { color: "yellow", bold: true }, "Press Ctrl+C again to exit")), /* @__PURE__ */ React10.createElement(Box9, { borderStyle: "single", borderColor: isBashMode ? "yellow" : "cyan", paddingX: 1 }, /* @__PURE__ */ React10.createElement(
|
|
1448
1438
|
InputPrompt,
|
|
1449
1439
|
{
|
|
1450
1440
|
onSubmit: handleSubmit,
|
|
1441
|
+
onBashCommand,
|
|
1451
1442
|
onImageDetected,
|
|
1452
1443
|
disabled: isThinking,
|
|
1453
1444
|
history: commandHistory,
|
|
1454
1445
|
prefillInput,
|
|
1455
|
-
onPrefillConsumed
|
|
1446
|
+
onPrefillConsumed,
|
|
1447
|
+
onBashModeChange: setIsBashMode
|
|
1448
|
+
}
|
|
1449
|
+
))));
|
|
1450
|
+
}
|
|
1451
|
+
function MessageItem({ message }) {
|
|
1452
|
+
const isUser = message.role === "user";
|
|
1453
|
+
return /* @__PURE__ */ React10.createElement(Box9, { flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React10.createElement(Box9, null, /* @__PURE__ */ React10.createElement(Text9, { bold: true, color: isUser ? "cyan" : "green" }, isUser ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), isUser && message.content && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { backgroundColor: "whiteBright", color: "black" }, " ", message.content, " ")), !isUser && message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " ", "tools used, ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
1454
|
+
if (step.type === "thought") {
|
|
1455
|
+
return /* @__PURE__ */ React10.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` ${step.content.slice(0, 200)}${step.content.length > 200 ? "..." : ""}`));
|
|
1456
|
+
}
|
|
1457
|
+
if (step.type === "action") {
|
|
1458
|
+
const toolName = step.metadata?.toolName || "unknown";
|
|
1459
|
+
const toolInput = step.metadata?.toolInput;
|
|
1460
|
+
const observationStep = message.metadata.steps[idx + 1];
|
|
1461
|
+
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
1462
|
+
return /* @__PURE__ */ React10.createElement(Box9, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text9, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, ` Result: ${typeof result === "string" ? result.slice(0, 200) : JSON.stringify(result).slice(0, 200)}${(typeof result === "string" ? result.length : JSON.stringify(result).length) > 200 ? "..." : ""}`));
|
|
1456
1463
|
}
|
|
1457
|
-
|
|
1464
|
+
return null;
|
|
1465
|
+
}).filter(Boolean)), !isUser && message.content !== "..." && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2, marginTop: message.metadata?.steps?.length ? 1 : 0 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React10.createElement(Text9, { color: "yellow" }, "\u26A0\uFE0F ", message.content) : /* @__PURE__ */ React10.createElement(Text9, null, message.content)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React10.createElement(Box9, { paddingLeft: 2 }, /* @__PURE__ */ React10.createElement(Text9, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)));
|
|
1458
1466
|
}
|
|
1459
1467
|
|
|
1460
1468
|
// src/components/MessageList.tsx
|
|
1461
|
-
import
|
|
1462
|
-
import { Box as
|
|
1469
|
+
import React11 from "react";
|
|
1470
|
+
import { Box as Box10, Text as Text10 } from "ink";
|
|
1463
1471
|
function stripThinkingTags(content) {
|
|
1464
1472
|
return content.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
1465
1473
|
}
|
|
1466
|
-
var MessageList =
|
|
1474
|
+
var MessageList = React11.memo(
|
|
1467
1475
|
function MessageList2({ messages }) {
|
|
1468
1476
|
if (messages.length === 0) {
|
|
1469
|
-
return /* @__PURE__ */
|
|
1477
|
+
return /* @__PURE__ */ React11.createElement(Box10, { paddingY: 1 }, /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, "No messages yet. Type a message to start!"));
|
|
1470
1478
|
}
|
|
1471
|
-
return /* @__PURE__ */
|
|
1479
|
+
return /* @__PURE__ */ React11.createElement(Box10, { flexDirection: "column", gap: 1, paddingY: 1 }, messages.map((message, index) => /* @__PURE__ */ React11.createElement(Box10, { key: index, flexDirection: "column", marginBottom: 1 }, /* @__PURE__ */ React11.createElement(Box10, null, /* @__PURE__ */ React11.createElement(Text10, { bold: true, color: message.role === "user" ? "cyan" : "green" }, message.role === "user" ? "\u{1F464} You" : "\u{1F916} Assistant"), /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), /* @__PURE__ */ React11.createElement(Box10, { paddingLeft: 2 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React11.createElement(Text10, { color: "yellow" }, "\u26A0\uFE0F ", stripThinkingTags(message.content)) : /* @__PURE__ */ React11.createElement(Text10, null, stripThinkingTags(message.content))), message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React11.createElement(Box10, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text10, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " tools used,", " ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
1472
1480
|
if (step.type === "thought") {
|
|
1473
|
-
return /* @__PURE__ */
|
|
1474
|
-
|
|
1481
|
+
return /* @__PURE__ */ React11.createElement(Box10, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text10, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React11.createElement(
|
|
1482
|
+
Text10,
|
|
1475
1483
|
{
|
|
1476
1484
|
dimColor: true
|
|
1477
1485
|
},
|
|
@@ -1483,10 +1491,10 @@ var MessageList = React12.memo(
|
|
|
1483
1491
|
const toolInput = step.metadata?.toolInput;
|
|
1484
1492
|
const observationStep = message.metadata.steps[idx + 1];
|
|
1485
1493
|
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
1486
|
-
return /* @__PURE__ */
|
|
1494
|
+
return /* @__PURE__ */ React11.createElement(Box10, { key: idx, paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React11.createElement(Text10, { color: "yellow" }, "\u{1F527} Action: ", toolName), toolInput && /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, ` Input: ${typeof toolInput === "string" ? toolInput : JSON.stringify(toolInput).slice(0, 100)}`), result && /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, ` Result: ${typeof result === "string" ? result.slice(0, 200) : JSON.stringify(result).slice(0, 200)}${(typeof result === "string" ? result.length : JSON.stringify(result).length) > 200 ? "..." : ""}`));
|
|
1487
1495
|
}
|
|
1488
1496
|
return null;
|
|
1489
|
-
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */
|
|
1497
|
+
}).filter(Boolean)), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React11.createElement(Box10, { paddingLeft: 2 }, /* @__PURE__ */ React11.createElement(Text10, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)))));
|
|
1490
1498
|
},
|
|
1491
1499
|
(prevProps, nextProps) => {
|
|
1492
1500
|
if (prevProps.messages.length !== nextProps.messages.length) {
|
|
@@ -1497,8 +1505,8 @@ var MessageList = React12.memo(
|
|
|
1497
1505
|
);
|
|
1498
1506
|
|
|
1499
1507
|
// src/components/TrustLocationSelector.tsx
|
|
1500
|
-
import
|
|
1501
|
-
import { Box as
|
|
1508
|
+
import React12 from "react";
|
|
1509
|
+
import { Box as Box11, Text as Text11 } from "ink";
|
|
1502
1510
|
import SelectInput2 from "ink-select-input";
|
|
1503
1511
|
function TrustLocationSelector({ inProject, onSelect, onCancel }) {
|
|
1504
1512
|
const items = [];
|
|
@@ -1519,23 +1527,23 @@ function TrustLocationSelector({ inProject, onSelect, onCancel }) {
|
|
|
1519
1527
|
const handleSelect = (item) => {
|
|
1520
1528
|
onSelect(item.value);
|
|
1521
1529
|
};
|
|
1522
|
-
return /* @__PURE__ */
|
|
1530
|
+
return /* @__PURE__ */ React12.createElement(Box11, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React12.createElement(Box11, { marginBottom: 1 }, /* @__PURE__ */ React12.createElement(Text11, { bold: true }, "Where should this rule be saved?")), /* @__PURE__ */ React12.createElement(
|
|
1523
1531
|
SelectInput2,
|
|
1524
1532
|
{
|
|
1525
1533
|
items,
|
|
1526
1534
|
onSelect: handleSelect,
|
|
1527
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
1535
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React12.createElement(Box11, null, /* @__PURE__ */ React12.createElement(Text11, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
|
|
1528
1536
|
}
|
|
1529
|
-
), /* @__PURE__ */
|
|
1537
|
+
), /* @__PURE__ */ React12.createElement(Box11, { marginTop: 1 }, /* @__PURE__ */ React12.createElement(Text11, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Ctrl+C to cancel")));
|
|
1530
1538
|
}
|
|
1531
1539
|
|
|
1532
1540
|
// src/components/RewindSelector.tsx
|
|
1533
|
-
import
|
|
1534
|
-
import { Box as
|
|
1541
|
+
import React13, { useState as useState5 } from "react";
|
|
1542
|
+
import { Box as Box12, Text as Text12, useInput as useInput4 } from "ink";
|
|
1535
1543
|
import SelectInput3 from "ink-select-input";
|
|
1536
1544
|
function RewindSelector({ messages, onSelect, onCancel }) {
|
|
1537
|
-
const [step, setStep] =
|
|
1538
|
-
const [selectedMessageIndex, setSelectedMessageIndex] =
|
|
1545
|
+
const [step, setStep] = useState5("selection");
|
|
1546
|
+
const [selectedMessageIndex, setSelectedMessageIndex] = useState5(null);
|
|
1539
1547
|
useInput4((input, key) => {
|
|
1540
1548
|
if (key.escape) {
|
|
1541
1549
|
if (step === "confirmation") {
|
|
@@ -1573,14 +1581,14 @@ function RewindSelector({ messages, onSelect, onCancel }) {
|
|
|
1573
1581
|
return sum2 + (msg.metadata?.tokenUsage?.total || 0);
|
|
1574
1582
|
}, 0);
|
|
1575
1583
|
if (step === "selection") {
|
|
1576
|
-
return /* @__PURE__ */
|
|
1584
|
+
return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React13.createElement(Box12, { marginBottom: 1 }, /* @__PURE__ */ React13.createElement(Text12, { bold: true }, "Select a point to rewind to:")), /* @__PURE__ */ React13.createElement(
|
|
1577
1585
|
SelectInput3,
|
|
1578
1586
|
{
|
|
1579
1587
|
items,
|
|
1580
1588
|
onSelect: handleSelectionSelect,
|
|
1581
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
1589
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React13.createElement(Box12, null, /* @__PURE__ */ React13.createElement(Text12, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
|
|
1582
1590
|
}
|
|
1583
|
-
), /* @__PURE__ */
|
|
1591
|
+
), /* @__PURE__ */ React13.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to cancel")));
|
|
1584
1592
|
}
|
|
1585
1593
|
const confirmationItems = [
|
|
1586
1594
|
{ label: "Yes, rewind to this point", value: "confirm" },
|
|
@@ -1588,23 +1596,23 @@ function RewindSelector({ messages, onSelect, onCancel }) {
|
|
|
1588
1596
|
];
|
|
1589
1597
|
const selectedMessage = selectedMessageIndex !== null && selectedMessageIndex >= 0 && selectedMessageIndex < messages.length ? messages[selectedMessageIndex] : null;
|
|
1590
1598
|
const selectedPreview = selectedMessage ? selectedMessage.content.length > 50 ? selectedMessage.content.substring(0, 50) + "..." : selectedMessage.content : "";
|
|
1591
|
-
return /* @__PURE__ */
|
|
1599
|
+
return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React13.createElement(Box12, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React13.createElement(Text12, { bold: true }, "Confirm rewind operation:"), /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, "Message: ", selectedPreview), /* @__PURE__ */ React13.createElement(Text12, { color: "yellow" }, "This will remove ", messagesToRemove.length, " message(s) (", tokensToRemove.toLocaleString(), " tokens)"), /* @__PURE__ */ React13.createElement(Text12, { color: "cyan" }, "The selected message will be placed in your input for editing.")), /* @__PURE__ */ React13.createElement(
|
|
1592
1600
|
SelectInput3,
|
|
1593
1601
|
{
|
|
1594
1602
|
items: confirmationItems,
|
|
1595
1603
|
onSelect: handleConfirmationSelect,
|
|
1596
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
1604
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React13.createElement(Box12, null, /* @__PURE__ */ React13.createElement(Text12, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
|
|
1597
1605
|
}
|
|
1598
|
-
), /* @__PURE__ */
|
|
1606
|
+
), /* @__PURE__ */ React13.createElement(Box12, { marginTop: 1 }, /* @__PURE__ */ React13.createElement(Text12, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to go back")));
|
|
1599
1607
|
}
|
|
1600
1608
|
|
|
1601
1609
|
// src/components/SessionSelector.tsx
|
|
1602
|
-
import
|
|
1603
|
-
import { Box as
|
|
1610
|
+
import React14, { useState as useState6 } from "react";
|
|
1611
|
+
import { Box as Box13, Text as Text13, useInput as useInput5 } from "ink";
|
|
1604
1612
|
import SelectInput4 from "ink-select-input";
|
|
1605
1613
|
function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
|
|
1606
|
-
const [step, setStep] =
|
|
1607
|
-
const [selectedSession, setSelectedSession] =
|
|
1614
|
+
const [step, setStep] = useState6("selection");
|
|
1615
|
+
const [selectedSession, setSelectedSession] = useState6(null);
|
|
1608
1616
|
useInput5((input, key) => {
|
|
1609
1617
|
if (key.escape) {
|
|
1610
1618
|
if (step === "confirmation") {
|
|
@@ -1638,32 +1646,32 @@ function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
|
|
|
1638
1646
|
}
|
|
1639
1647
|
};
|
|
1640
1648
|
if (step === "selection") {
|
|
1641
|
-
return /* @__PURE__ */
|
|
1649
|
+
return /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React14.createElement(Box13, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text13, { bold: true }, "Select a session to resume:")), /* @__PURE__ */ React14.createElement(
|
|
1642
1650
|
SelectInput4,
|
|
1643
1651
|
{
|
|
1644
1652
|
items,
|
|
1645
1653
|
onSelect: handleSelectionSelect,
|
|
1646
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
1654
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React14.createElement(Box13, null, /* @__PURE__ */ React14.createElement(Text13, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
|
|
1647
1655
|
}
|
|
1648
|
-
), /* @__PURE__ */
|
|
1656
|
+
), /* @__PURE__ */ React14.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to cancel")));
|
|
1649
1657
|
}
|
|
1650
1658
|
const confirmationItems = [
|
|
1651
1659
|
{ label: "Yes, resume this session", value: "confirm" },
|
|
1652
1660
|
{ label: "No, go back to selection", value: "cancel" }
|
|
1653
1661
|
];
|
|
1654
|
-
return /* @__PURE__ */
|
|
1662
|
+
return /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column", marginY: 1 }, /* @__PURE__ */ React14.createElement(Box13, { marginBottom: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text13, { bold: true }, 'Resume session: "', selectedSession?.name, '"'), /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, selectedSession?.messages.length, " messages | ", selectedSession?.model, " |", " ", selectedSession?.metadata?.totalTokens?.toLocaleString() ?? 0, " tokens"), hasUnsavedWork && /* @__PURE__ */ React14.createElement(Text13, { color: "yellow" }, "Warning: Your current session has unsaved messages. Use /save first if needed.")), /* @__PURE__ */ React14.createElement(
|
|
1655
1663
|
SelectInput4,
|
|
1656
1664
|
{
|
|
1657
1665
|
items: confirmationItems,
|
|
1658
1666
|
onSelect: handleConfirmationSelect,
|
|
1659
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */
|
|
1667
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React14.createElement(Box13, null, /* @__PURE__ */ React14.createElement(Text13, { color: isSelected ? "cyan" : void 0 }, isSelected ? "\u276F " : " ", label))
|
|
1660
1668
|
}
|
|
1661
|
-
), /* @__PURE__ */
|
|
1669
|
+
), /* @__PURE__ */ React14.createElement(Box13, { marginTop: 1 }, /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to go back")));
|
|
1662
1670
|
}
|
|
1663
1671
|
|
|
1664
1672
|
// src/components/LoginFlow.tsx
|
|
1665
|
-
import
|
|
1666
|
-
import { Box as
|
|
1673
|
+
import React15, { useState as useState7, useEffect as useEffect2 } from "react";
|
|
1674
|
+
import { Box as Box14, Text as Text14 } from "ink";
|
|
1667
1675
|
import Spinner2 from "ink-spinner";
|
|
1668
1676
|
import jwt from "jsonwebtoken";
|
|
1669
1677
|
import open from "open";
|
|
@@ -1779,10 +1787,10 @@ var OAuthClient = class {
|
|
|
1779
1787
|
|
|
1780
1788
|
// src/components/LoginFlow.tsx
|
|
1781
1789
|
function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, onError }) {
|
|
1782
|
-
const [status, setStatus] =
|
|
1783
|
-
const [deviceFlow, setDeviceFlow] =
|
|
1784
|
-
const [statusMessage, setStatusMessage] =
|
|
1785
|
-
const [error, setError] =
|
|
1790
|
+
const [status, setStatus] = useState7("initiating");
|
|
1791
|
+
const [deviceFlow, setDeviceFlow] = useState7(null);
|
|
1792
|
+
const [statusMessage, setStatusMessage] = useState7("Initiating device authorization...");
|
|
1793
|
+
const [error, setError] = useState7(null);
|
|
1786
1794
|
useEffect2(() => {
|
|
1787
1795
|
const runLoginFlow = async () => {
|
|
1788
1796
|
const oauth = new OAuthClient(apiUrl);
|
|
@@ -1826,15 +1834,15 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
|
|
|
1826
1834
|
}
|
|
1827
1835
|
}, [deviceFlow, status]);
|
|
1828
1836
|
if (status === "initiating") {
|
|
1829
|
-
return /* @__PURE__ */
|
|
1837
|
+
return /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Text14, { color: "cyan" }, /* @__PURE__ */ React15.createElement(Spinner2, { type: "dots" }), " Initiating device authorization...")));
|
|
1830
1838
|
}
|
|
1831
1839
|
if (status === "error") {
|
|
1832
|
-
return /* @__PURE__ */
|
|
1840
|
+
return /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text14, { color: "red", bold: true }, "\u2716 Authentication Failed")), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Text14, { color: "red" }, error)));
|
|
1833
1841
|
}
|
|
1834
1842
|
if (status === "success") {
|
|
1835
|
-
return /* @__PURE__ */
|
|
1843
|
+
return /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text14, { color: "green", bold: true }, "\u2714 Successfully authenticated!")), /* @__PURE__ */ React15.createElement(Box14, null, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, "You can now use B4M CLI with your account.")));
|
|
1836
1844
|
}
|
|
1837
|
-
return /* @__PURE__ */
|
|
1845
|
+
return /* @__PURE__ */ React15.createElement(Box14, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "cyan" }, /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text14, { color: "cyan", bold: true }, "\u{1F510} Device Authorization")), /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text14, null, "Opening browser automatically... If it doesn't open, please visit:")), /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React15.createElement(Text14, { color: "blue", bold: true }, deviceFlow?.verification_uri)), /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text14, null, "And enter this code when prompted:")), /* @__PURE__ */ React15.createElement(Box14, { marginBottom: 1, paddingLeft: 2 }, /* @__PURE__ */ React15.createElement(Text14, { color: "yellow", bold: true }, deviceFlow?.user_code)), /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text14, { color: "cyan" }, /* @__PURE__ */ React15.createElement(Spinner2, { type: "dots" }), " ", statusMessage)), /* @__PURE__ */ React15.createElement(Box14, { marginTop: 1 }, /* @__PURE__ */ React15.createElement(Text14, { dimColor: true }, "Expires in ", deviceFlow ? Math.floor(deviceFlow.expires_in / 60) : 0, " minutes")));
|
|
1838
1846
|
}
|
|
1839
1847
|
|
|
1840
1848
|
// src/storage/SessionStore.ts
|
|
@@ -9685,7 +9693,6 @@ var Logger2 = class _Logger {
|
|
|
9685
9693
|
}
|
|
9686
9694
|
};
|
|
9687
9695
|
var logger = Logger2.getInstance();
|
|
9688
|
-
logger.setVerbose(process.env.B4M_VERBOSE === "1");
|
|
9689
9696
|
|
|
9690
9697
|
// src/llm/ServerToolExecutor.ts
|
|
9691
9698
|
var ServerToolExecutor = class {
|
|
@@ -11114,7 +11121,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
11114
11121
|
// package.json
|
|
11115
11122
|
var package_default = {
|
|
11116
11123
|
name: "@bike4mind/cli",
|
|
11117
|
-
version: "0.2.10-
|
|
11124
|
+
version: "0.2.10-github-update-projects.17240+c13cde99e",
|
|
11118
11125
|
type: "module",
|
|
11119
11126
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
11120
11127
|
license: "UNLICENSED",
|
|
@@ -11217,10 +11224,10 @@ var package_default = {
|
|
|
11217
11224
|
},
|
|
11218
11225
|
devDependencies: {
|
|
11219
11226
|
"@bike4mind/agents": "0.1.0",
|
|
11220
|
-
"@bike4mind/common": "2.39.1-
|
|
11221
|
-
"@bike4mind/mcp": "1.20.4-
|
|
11222
|
-
"@bike4mind/services": "2.34.2-
|
|
11223
|
-
"@bike4mind/utils": "2.1.4-
|
|
11227
|
+
"@bike4mind/common": "2.39.1-github-update-projects.17240+c13cde99e",
|
|
11228
|
+
"@bike4mind/mcp": "1.20.4-github-update-projects.17240+c13cde99e",
|
|
11229
|
+
"@bike4mind/services": "2.34.2-github-update-projects.17240+c13cde99e",
|
|
11230
|
+
"@bike4mind/utils": "2.1.4-github-update-projects.17240+c13cde99e",
|
|
11224
11231
|
"@types/better-sqlite3": "^7.6.13",
|
|
11225
11232
|
"@types/diff": "^5.0.9",
|
|
11226
11233
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -11233,7 +11240,7 @@ var package_default = {
|
|
|
11233
11240
|
typescript: "^5.9.3",
|
|
11234
11241
|
vitest: "^3.2.4"
|
|
11235
11242
|
},
|
|
11236
|
-
gitHead: "
|
|
11243
|
+
gitHead: "c13cde99e05500df403cc2ea0c3b4420517561dd"
|
|
11237
11244
|
};
|
|
11238
11245
|
|
|
11239
11246
|
// src/config/constants.ts
|
|
@@ -11255,7 +11262,7 @@ var usageCache = null;
|
|
|
11255
11262
|
function CliApp() {
|
|
11256
11263
|
const { exit } = useApp();
|
|
11257
11264
|
const imageRenderer = new ImageRenderer();
|
|
11258
|
-
const [state, setState] =
|
|
11265
|
+
const [state, setState] = useState8({
|
|
11259
11266
|
session: null,
|
|
11260
11267
|
sessionStore: new SessionStore(),
|
|
11261
11268
|
configStore: new ConfigStore(),
|
|
@@ -11272,9 +11279,9 @@ function CliApp() {
|
|
|
11272
11279
|
rewindSelector: null,
|
|
11273
11280
|
sessionSelector: null
|
|
11274
11281
|
});
|
|
11275
|
-
const [isInitialized, setIsInitialized] =
|
|
11276
|
-
const [initError, setInitError] =
|
|
11277
|
-
const [commandHistory, setCommandHistory] =
|
|
11282
|
+
const [isInitialized, setIsInitialized] = useState8(false);
|
|
11283
|
+
const [initError, setInitError] = useState8(null);
|
|
11284
|
+
const [commandHistory, setCommandHistory] = useState8([]);
|
|
11278
11285
|
const imageStoreInitPromise = useRef(null);
|
|
11279
11286
|
const setStoreSession = useCliStore((state2) => state2.setSession);
|
|
11280
11287
|
const setPermissionPrompt = useCliStore((state2) => state2.setPermissionPrompt);
|
|
@@ -11397,11 +11404,13 @@ function CliApp() {
|
|
|
11397
11404
|
if (models.length === 0) {
|
|
11398
11405
|
throw new Error("No models available from server.");
|
|
11399
11406
|
}
|
|
11400
|
-
|
|
11407
|
+
console.log(`\u{1F4CB} Available models: ${models.map((m) => m.id).join(", ")}`);
|
|
11401
11408
|
const modelInfo = models.find((m) => m.id === config.defaultModel) || models[0];
|
|
11402
11409
|
if (modelInfo.id !== config.defaultModel) {
|
|
11403
|
-
|
|
11404
|
-
|
|
11410
|
+
console.log(`\u26A0\uFE0F Requested model '${config.defaultModel}' not available`);
|
|
11411
|
+
console.log(`\u{1F916} Using fallback model: ${modelInfo.id}`);
|
|
11412
|
+
} else {
|
|
11413
|
+
console.log(`\u{1F916} Using model: ${modelInfo.id}`);
|
|
11405
11414
|
}
|
|
11406
11415
|
llm.currentModel = modelInfo.id;
|
|
11407
11416
|
const newSession = {
|
|
@@ -11420,6 +11429,9 @@ function CliApp() {
|
|
|
11420
11429
|
};
|
|
11421
11430
|
await logger.initialize(newSession.id);
|
|
11422
11431
|
logger.setVerbose(process.env.B4M_VERBOSE === "1");
|
|
11432
|
+
logger.info(`API: ${apiBaseURL}`);
|
|
11433
|
+
logger.info(`Environment: ${envName}`);
|
|
11434
|
+
logger.info(`Model: ${modelInfo.id}`);
|
|
11423
11435
|
logger.debug("=== Session Configuration Complete ===");
|
|
11424
11436
|
logger.cleanupOldLogs().catch(() => {
|
|
11425
11437
|
});
|
|
@@ -11468,7 +11480,7 @@ function CliApp() {
|
|
|
11468
11480
|
state.configStore,
|
|
11469
11481
|
apiClient
|
|
11470
11482
|
);
|
|
11471
|
-
console.log(`\u{1F6E0}\uFE0F
|
|
11483
|
+
console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools.length} B4M tool(s)`);
|
|
11472
11484
|
const mcpManager = new McpManager(config);
|
|
11473
11485
|
await mcpManager.initialize();
|
|
11474
11486
|
const mcpTools = mcpManager.getTools();
|
|
@@ -11479,6 +11491,7 @@ function CliApp() {
|
|
|
11479
11491
|
});
|
|
11480
11492
|
}
|
|
11481
11493
|
const allTools = [...b4mTools, ...mcpTools];
|
|
11494
|
+
console.log(`\u2705 Total: ${allTools.length} tool(s) available`);
|
|
11482
11495
|
const projectDir = state.configStore.getProjectConfigDir();
|
|
11483
11496
|
const contextResult = await loadContextFiles(projectDir);
|
|
11484
11497
|
if (contextResult.globalContext) {
|
|
@@ -11554,7 +11567,6 @@ Remember: Use context from previous messages to understand follow-up questions.$
|
|
|
11554
11567
|
}));
|
|
11555
11568
|
setStoreSession(newSession);
|
|
11556
11569
|
setIsInitialized(true);
|
|
11557
|
-
console.log("\n");
|
|
11558
11570
|
} catch (error) {
|
|
11559
11571
|
console.error("Initialization error:", error);
|
|
11560
11572
|
setInitError(error instanceof Error ? error.message : "Unknown error");
|
|
@@ -11585,16 +11597,23 @@ Remember: Use context from previous messages to understand follow-up questions.$
|
|
|
11585
11597
|
const currentSteps = [];
|
|
11586
11598
|
const stepHandler = (step) => {
|
|
11587
11599
|
currentSteps.push(step);
|
|
11588
|
-
const
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
...
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
|
|
11600
|
+
const currentSession = useCliStore.getState().session;
|
|
11601
|
+
if (currentSession) {
|
|
11602
|
+
const messages = [...currentSession.messages];
|
|
11603
|
+
const lastMessage = messages[messages.length - 1];
|
|
11604
|
+
if (lastMessage && lastMessage.role === "assistant") {
|
|
11605
|
+
messages[messages.length - 1] = {
|
|
11606
|
+
...lastMessage,
|
|
11607
|
+
metadata: {
|
|
11608
|
+
...lastMessage.metadata,
|
|
11609
|
+
steps: [...currentSteps]
|
|
11610
|
+
}
|
|
11611
|
+
};
|
|
11612
|
+
setStoreSession({
|
|
11613
|
+
...currentSession,
|
|
11614
|
+
messages
|
|
11615
|
+
});
|
|
11616
|
+
}
|
|
11598
11617
|
}
|
|
11599
11618
|
};
|
|
11600
11619
|
state.agent.on("action", stepHandler);
|
|
@@ -11619,14 +11638,13 @@ Remember: Use context from previous messages to understand follow-up questions.$
|
|
|
11619
11638
|
steps: []
|
|
11620
11639
|
}
|
|
11621
11640
|
};
|
|
11622
|
-
const
|
|
11641
|
+
const sessionWithMessages = {
|
|
11623
11642
|
...state.session,
|
|
11624
|
-
messages: [...state.session.messages, userMessage],
|
|
11643
|
+
messages: [...state.session.messages, userMessage, pendingAssistantMessage],
|
|
11625
11644
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11626
11645
|
};
|
|
11627
|
-
setState((prev) => ({ ...prev, session:
|
|
11628
|
-
setStoreSession(
|
|
11629
|
-
useCliStore.getState().addPendingMessage(pendingAssistantMessage);
|
|
11646
|
+
setState((prev) => ({ ...prev, session: sessionWithMessages }));
|
|
11647
|
+
setStoreSession(sessionWithMessages);
|
|
11630
11648
|
const recentMessages = state.session.messages.slice(-20);
|
|
11631
11649
|
const previousMessages = recentMessages.filter((msg) => msg.role === "user" || msg.role === "assistant").map((msg) => ({
|
|
11632
11650
|
role: msg.role,
|
|
@@ -11640,6 +11658,9 @@ Remember: Use context from previous messages to understand follow-up questions.$
|
|
|
11640
11658
|
console.log("\n\u26A0\uFE0F Action denied by user\n");
|
|
11641
11659
|
}
|
|
11642
11660
|
const successfulToolCalls = result.steps.filter((s) => s.type === "observation").length;
|
|
11661
|
+
const currentSession = useCliStore.getState().session;
|
|
11662
|
+
if (!currentSession) return;
|
|
11663
|
+
const finalMessages = [...currentSession.messages];
|
|
11643
11664
|
const finalAssistantMessage = {
|
|
11644
11665
|
role: "assistant",
|
|
11645
11666
|
content: result.finalAnswer,
|
|
@@ -11655,22 +11676,21 @@ Remember: Use context from previous messages to understand follow-up questions.$
|
|
|
11655
11676
|
permissionDenied
|
|
11656
11677
|
}
|
|
11657
11678
|
};
|
|
11658
|
-
|
|
11659
|
-
const currentSession = useCliStore.getState().session;
|
|
11660
|
-
if (!currentSession) return;
|
|
11679
|
+
finalMessages[finalMessages.length - 1] = finalAssistantMessage;
|
|
11661
11680
|
const updatedSession = {
|
|
11662
11681
|
...currentSession,
|
|
11682
|
+
messages: finalMessages,
|
|
11683
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11663
11684
|
metadata: {
|
|
11664
|
-
...
|
|
11665
|
-
totalTokens:
|
|
11666
|
-
toolCallCount:
|
|
11685
|
+
...state.session.metadata,
|
|
11686
|
+
totalTokens: state.session.metadata.totalTokens + result.completionInfo.totalTokens,
|
|
11687
|
+
toolCallCount: state.session.metadata.toolCallCount + successfulToolCalls
|
|
11667
11688
|
}
|
|
11668
11689
|
};
|
|
11669
11690
|
setState((prev) => ({ ...prev, session: updatedSession }));
|
|
11670
11691
|
setStoreSession(updatedSession);
|
|
11671
11692
|
await state.sessionStore.save(updatedSession);
|
|
11672
11693
|
} catch (error) {
|
|
11673
|
-
useCliStore.getState().clearPendingMessages();
|
|
11674
11694
|
if (error instanceof Error) {
|
|
11675
11695
|
if (error.message.includes("Authentication failed") || error.message.includes("Authentication expired")) {
|
|
11676
11696
|
console.log("\n\u274C Authentication failed");
|
|
@@ -11683,6 +11703,46 @@ Remember: Use context from previous messages to understand follow-up questions.$
|
|
|
11683
11703
|
state.agent.off("action", stepHandler);
|
|
11684
11704
|
}
|
|
11685
11705
|
};
|
|
11706
|
+
const handleBashCommand = useCallback(
|
|
11707
|
+
(command) => {
|
|
11708
|
+
if (!state.session) return;
|
|
11709
|
+
let output;
|
|
11710
|
+
let isError = false;
|
|
11711
|
+
try {
|
|
11712
|
+
output = execSync(command, {
|
|
11713
|
+
encoding: "utf-8",
|
|
11714
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
11715
|
+
cwd: process.cwd(),
|
|
11716
|
+
maxBuffer: 10 * 1024 * 1024
|
|
11717
|
+
// 10MB buffer
|
|
11718
|
+
});
|
|
11719
|
+
} catch (error) {
|
|
11720
|
+
const execError = error;
|
|
11721
|
+
output = execError.stderr || execError.message || "Command failed";
|
|
11722
|
+
isError = true;
|
|
11723
|
+
}
|
|
11724
|
+
const userMessage = {
|
|
11725
|
+
role: "user",
|
|
11726
|
+
content: `$ ${command}`,
|
|
11727
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
11728
|
+
};
|
|
11729
|
+
const assistantMessage = {
|
|
11730
|
+
role: "assistant",
|
|
11731
|
+
content: isError ? `\u274C Error:
|
|
11732
|
+
${output}` : output.trim() || "(no output)",
|
|
11733
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
11734
|
+
};
|
|
11735
|
+
const updatedSession = {
|
|
11736
|
+
...state.session,
|
|
11737
|
+
messages: [...state.session.messages, userMessage, assistantMessage],
|
|
11738
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
11739
|
+
};
|
|
11740
|
+
setState((prev) => ({ ...prev, session: updatedSession }));
|
|
11741
|
+
setStoreSession(updatedSession);
|
|
11742
|
+
state.sessionStore.save(updatedSession);
|
|
11743
|
+
},
|
|
11744
|
+
[state.session, state.sessionStore]
|
|
11745
|
+
);
|
|
11686
11746
|
const handleImageDetected = async (imageData) => {
|
|
11687
11747
|
try {
|
|
11688
11748
|
let imageStore = state.imageStore;
|
|
@@ -11807,7 +11867,6 @@ Project Configuration:
|
|
|
11807
11867
|
setState((prev) => ({ ...prev, session: loadedSession }));
|
|
11808
11868
|
setStoreSession(loadedSession);
|
|
11809
11869
|
useCliStore.getState().clearAgentSteps();
|
|
11810
|
-
useCliStore.getState().clearPendingMessages();
|
|
11811
11870
|
usageCache = null;
|
|
11812
11871
|
console.log(`
|
|
11813
11872
|
\u2705 Session resumed: "${loadedSession.name}"`);
|
|
@@ -12043,7 +12102,6 @@ Project Configuration:
|
|
|
12043
12102
|
setState((prev) => ({ ...prev, session: newSession }));
|
|
12044
12103
|
setStoreSession(newSession);
|
|
12045
12104
|
useCliStore.getState().clearAgentSteps();
|
|
12046
|
-
useCliStore.getState().clearPendingMessages();
|
|
12047
12105
|
usageCache = null;
|
|
12048
12106
|
console.log("New session started.");
|
|
12049
12107
|
console.log(`
|
|
@@ -12096,7 +12154,6 @@ Project Configuration:
|
|
|
12096
12154
|
prefillInput: prefillContent
|
|
12097
12155
|
}));
|
|
12098
12156
|
setStoreSession(rewindedSession);
|
|
12099
|
-
useCliStore.getState().clearPendingMessages();
|
|
12100
12157
|
await state.sessionStore.save(rewindedSession);
|
|
12101
12158
|
console.log("\u2705 Conversation rewound successfully");
|
|
12102
12159
|
console.log(`\u{1F4CA} Current state: ${rewindedMessages.length} messages, ${newMetadata.totalTokens} tokens`);
|
|
@@ -12264,12 +12321,12 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
12264
12321
|
setState((prev) => ({ ...prev, config: updatedConfig }));
|
|
12265
12322
|
};
|
|
12266
12323
|
if (initError) {
|
|
12267
|
-
return /* @__PURE__ */
|
|
12324
|
+
return /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React16.createElement(Text15, { color: "red", bold: true }, "\u274C Initialization Error"), /* @__PURE__ */ React16.createElement(Text15, null, initError), /* @__PURE__ */ React16.createElement(Text15, { dimColor: true }, "\n", "Tip: Run /config to set up your API keys"));
|
|
12268
12325
|
}
|
|
12269
12326
|
if (state.trustLocationSelector) {
|
|
12270
12327
|
const projectDir = state.configStore.getProjectConfigDir();
|
|
12271
12328
|
const inProject = projectDir !== null;
|
|
12272
|
-
return /* @__PURE__ */
|
|
12329
|
+
return /* @__PURE__ */ React16.createElement(
|
|
12273
12330
|
TrustLocationSelector,
|
|
12274
12331
|
{
|
|
12275
12332
|
inProject,
|
|
@@ -12287,7 +12344,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
12287
12344
|
);
|
|
12288
12345
|
}
|
|
12289
12346
|
if (state.rewindSelector && state.session) {
|
|
12290
|
-
return /* @__PURE__ */
|
|
12347
|
+
return /* @__PURE__ */ React16.createElement(
|
|
12291
12348
|
RewindSelector,
|
|
12292
12349
|
{
|
|
12293
12350
|
messages: state.session.messages,
|
|
@@ -12305,7 +12362,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
12305
12362
|
);
|
|
12306
12363
|
}
|
|
12307
12364
|
if (state.sessionSelector) {
|
|
12308
|
-
return /* @__PURE__ */
|
|
12365
|
+
return /* @__PURE__ */ React16.createElement(
|
|
12309
12366
|
SessionSelector,
|
|
12310
12367
|
{
|
|
12311
12368
|
sessions: state.sessionSelector.sessions,
|
|
@@ -12325,7 +12382,7 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
12325
12382
|
}
|
|
12326
12383
|
if (state.showLoginFlow) {
|
|
12327
12384
|
const loginApiUrl = getApiUrl(state.config?.apiConfig);
|
|
12328
|
-
return /* @__PURE__ */
|
|
12385
|
+
return /* @__PURE__ */ React16.createElement(
|
|
12329
12386
|
LoginFlow,
|
|
12330
12387
|
{
|
|
12331
12388
|
apiUrl: loginApiUrl,
|
|
@@ -12348,13 +12405,14 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
12348
12405
|
);
|
|
12349
12406
|
}
|
|
12350
12407
|
if (!isInitialized) {
|
|
12351
|
-
return /* @__PURE__ */
|
|
12408
|
+
return /* @__PURE__ */ React16.createElement(Box15, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React16.createElement(Text15, null, "\u{1F680} Initializing..."));
|
|
12352
12409
|
}
|
|
12353
|
-
return /* @__PURE__ */
|
|
12410
|
+
return /* @__PURE__ */ React16.createElement(
|
|
12354
12411
|
App,
|
|
12355
12412
|
{
|
|
12356
12413
|
onMessage: handleMessage,
|
|
12357
12414
|
onCommand: handleCommand,
|
|
12415
|
+
onBashCommand: handleBashCommand,
|
|
12358
12416
|
onImageDetected: handleImageDetected,
|
|
12359
12417
|
commandHistory,
|
|
12360
12418
|
config: state.config,
|
|
@@ -12383,12 +12441,12 @@ var BANNER = `
|
|
|
12383
12441
|
\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
|
|
12384
12442
|
`;
|
|
12385
12443
|
console.log("\x1B[36m\x1B[1m%s\x1B[0m", BANNER);
|
|
12386
|
-
console.log(`\x1B[2m v${package_default.version} - AI-Powered CLI\x1B[0m
|
|
12387
|
-
|
|
12444
|
+
console.log(`\x1B[2m v${package_default.version} - AI-Powered CLI\x1B[0m
|
|
12445
|
+
`);
|
|
12388
12446
|
var isDevMode = import.meta.url.includes("/src/") || process.env.NODE_ENV === "development";
|
|
12389
12447
|
if (isDevMode) {
|
|
12390
|
-
|
|
12448
|
+
console.log("\u{1F527} Running in development mode (using TypeScript source)\n");
|
|
12391
12449
|
}
|
|
12392
|
-
render(/* @__PURE__ */
|
|
12450
|
+
render(/* @__PURE__ */ React16.createElement(CliApp, null), {
|
|
12393
12451
|
exitOnCtrlC: false
|
|
12394
12452
|
});
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
findMostSimilarMemento,
|
|
4
4
|
getRelevantMementos
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-AGGKFMPH.js";
|
|
6
|
+
import "./chunk-R4KVFPRM.js";
|
|
7
7
|
import "./chunk-AMDXHL6S.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-EN7MWHVV.js";
|
|
9
9
|
import "./chunk-PDX44BCA.js";
|
|
10
10
|
export {
|
|
11
11
|
findMostSimilarMemento,
|
|
@@ -120,7 +120,7 @@ import {
|
|
|
120
120
|
validateMermaidSyntax,
|
|
121
121
|
warmUpSettingsCache,
|
|
122
122
|
withRetry
|
|
123
|
-
} from "./chunk-
|
|
123
|
+
} from "./chunk-R4KVFPRM.js";
|
|
124
124
|
import {
|
|
125
125
|
Logger,
|
|
126
126
|
NotificationDeduplicator,
|
|
@@ -129,7 +129,7 @@ import {
|
|
|
129
129
|
postLowCreditsNotificationToSlack,
|
|
130
130
|
postMessageToSlack
|
|
131
131
|
} from "./chunk-AMDXHL6S.js";
|
|
132
|
-
import "./chunk-
|
|
132
|
+
import "./chunk-EN7MWHVV.js";
|
|
133
133
|
import "./chunk-PDX44BCA.js";
|
|
134
134
|
export {
|
|
135
135
|
AWSBackend,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
SubtractCreditsSchema,
|
|
4
4
|
subtractCredits
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-5YF7VMO5.js";
|
|
6
|
+
import "./chunk-R4KVFPRM.js";
|
|
7
7
|
import "./chunk-AMDXHL6S.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-EN7MWHVV.js";
|
|
9
9
|
import "./chunk-PDX44BCA.js";
|
|
10
10
|
export {
|
|
11
11
|
SubtractCreditsSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.10-
|
|
3
|
+
"version": "0.2.10-github-update-projects.17240+c13cde99e",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -103,10 +103,10 @@
|
|
|
103
103
|
},
|
|
104
104
|
"devDependencies": {
|
|
105
105
|
"@bike4mind/agents": "0.1.0",
|
|
106
|
-
"@bike4mind/common": "2.39.1-
|
|
107
|
-
"@bike4mind/mcp": "1.20.4-
|
|
108
|
-
"@bike4mind/services": "2.34.2-
|
|
109
|
-
"@bike4mind/utils": "2.1.4-
|
|
106
|
+
"@bike4mind/common": "2.39.1-github-update-projects.17240+c13cde99e",
|
|
107
|
+
"@bike4mind/mcp": "1.20.4-github-update-projects.17240+c13cde99e",
|
|
108
|
+
"@bike4mind/services": "2.34.2-github-update-projects.17240+c13cde99e",
|
|
109
|
+
"@bike4mind/utils": "2.1.4-github-update-projects.17240+c13cde99e",
|
|
110
110
|
"@types/better-sqlite3": "^7.6.13",
|
|
111
111
|
"@types/diff": "^5.0.9",
|
|
112
112
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -119,5 +119,5 @@
|
|
|
119
119
|
"typescript": "^5.9.3",
|
|
120
120
|
"vitest": "^3.2.4"
|
|
121
121
|
},
|
|
122
|
-
"gitHead": "
|
|
122
|
+
"gitHead": "c13cde99e05500df403cc2ea0c3b4420517561dd"
|
|
123
123
|
}
|