toolpack-cli 1.0.1 → 1.1.0-SNAPSHOT

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.
@@ -0,0 +1 @@
1
+ export declare function KnowledgeLoader(): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { useToolpack } from '../context/ToolpackContext.js';
4
+ import { useTheme } from '../theme/ThemeContext.js';
5
+ const BAR_WIDTH = 30;
6
+ export function KnowledgeLoader() {
7
+ const { knowledgeProgress } = useToolpack();
8
+ const { theme } = useTheme();
9
+ if (!knowledgeProgress || knowledgeProgress.phase === 'complete') {
10
+ return null;
11
+ }
12
+ const percentage = Math.min(knowledgeProgress.percentage ?? 0, 99);
13
+ const filled = Math.round((percentage / 100) * BAR_WIDTH);
14
+ const label = knowledgeProgress.phase === 'start'
15
+ ? 'Scanning knowledge sources...'
16
+ : `Embedding content (${percentage}%)`;
17
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.colors.border, paddingX: 2, paddingY: 1, marginBottom: 1, children: [_jsx(Text, { color: theme.colors.primary, children: "Knowledge base initializing\u2026" }), _jsx(Text, { color: theme.colors.text, children: label }), _jsxs(Text, { color: theme.colors.textSecondary, children: ["[", '#'.repeat(Math.max(0, filled)), ' '.repeat(Math.max(0, BAR_WIDTH - filled)), "] ", percentage, "%"] }), knowledgeProgress.currentSource && (_jsxs(Text, { color: theme.colors.textSecondary, children: ["Source: ", knowledgeProgress.currentSource] }))] }));
18
+ }
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { Toolpack, ModeConfig, ToolLogEvent, WorkflowProgress } from 'toolpack-sdk';
2
+ import { Toolpack, ModeConfig, ToolLogEvent, WorkflowProgress, EmbeddingProgressEvent } from 'toolpack-sdk';
3
3
  /**
4
4
  * Clean React Context wrapper for the Toolpack SDK.
5
5
  * Manages SDK-related state only: modes, models, and the toolpack instance.
@@ -47,6 +47,7 @@ interface ToolpackContextType {
47
47
  setToolsUnsupportedWarning: (msg: string) => void;
48
48
  configSource: 'local' | 'global' | 'base' | 'default';
49
49
  activeConfigPath: string | null;
50
+ knowledgeProgress: EmbeddingProgressEvent | null;
50
51
  }
51
52
  export declare function ToolpackProvider({ children }: {
52
53
  children: ReactNode;
@@ -1,11 +1,14 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useContext, useEffect, useState, useCallback, } from 'react';
3
- import { Toolpack, createMode, loadRuntimeConfig, getRuntimeConfigStatus, } from 'toolpack-sdk';
3
+ import { Toolpack, createMode, loadRuntimeConfig, getRuntimeConfigStatus, Knowledge, MemoryProvider, MarkdownSource, JSONSource, SQLiteTextSource, } from 'toolpack-sdk';
4
4
  import { XAIAdapter } from '../custom-providers/XAIAdapter.js';
5
5
  import { skillToolsProject } from '../custom-tools/skill-tools/index.js';
6
6
  import * as fs from 'fs';
7
7
  import * as os from 'os';
8
8
  import * as path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
9
12
  const ToolpackContext = createContext(undefined);
10
13
  export function ToolpackProvider({ children }) {
11
14
  const [toolpack, setToolpack] = useState(null);
@@ -21,6 +24,7 @@ export function ToolpackProvider({ children }) {
21
24
  const [toolsUnsupportedWarning, setToolsUnsupportedWarning] = useState(null);
22
25
  const [configSource, setConfigSource] = useState('default');
23
26
  const [activeConfigPath, setActiveConfigPath] = useState(null);
27
+ const [knowledgeProgress, setKnowledgeProgress] = useState(null);
24
28
  useEffect(() => {
25
29
  async function init() {
26
30
  // Get config status
@@ -41,6 +45,28 @@ export function ToolpackProvider({ children }) {
41
45
  systemPrompt: 'You are a helpful assistant. Provide clear and concise responses.',
42
46
  blockAllTools: true,
43
47
  });
48
+ const knowledgeBasePath = ensureGlobalKnowledgeAssets();
49
+ const kb = await Knowledge.create({
50
+ provider: new MemoryProvider(),
51
+ sources: [
52
+ new MarkdownSource(path.join(knowledgeBasePath, '**/*.md'), { namespace: 'docs' }),
53
+ new JSONSource(path.join(knowledgeBasePath, 'toolpack-cli.json'), {
54
+ chunkBy: 'item',
55
+ contentFields: ['title', 'description'],
56
+ metadataFields: ['id', 'category'],
57
+ namespace: 'json',
58
+ }),
59
+ new SQLiteTextSource(path.join(knowledgeBasePath, 'toolpack-guides.db'), {
60
+ table: 'guides',
61
+ contentColumns: ['title', 'body'],
62
+ metadataColumns: ['category'],
63
+ namespace: 'guides',
64
+ }),
65
+ ],
66
+ onEmbeddingProgress: event => {
67
+ setKnowledgeProgress(event);
68
+ },
69
+ });
44
70
  const instance = await Toolpack.init({
45
71
  defaultMode: 'agent',
46
72
  configPath: tempConfigPath, // Use our merged temp config
@@ -55,6 +81,7 @@ export function ToolpackProvider({ children }) {
55
81
  customModes: [simpleChat],
56
82
  customProviders: [new XAIAdapter()],
57
83
  customTools: [skillToolsProject],
84
+ knowledge: kb,
58
85
  modeOverrides: {
59
86
  agent: {
60
87
  // Override the agent mode system prompt to include skill search and read
@@ -210,6 +237,7 @@ export function ToolpackProvider({ children }) {
210
237
  setToolsUnsupportedWarning,
211
238
  configSource,
212
239
  activeConfigPath,
240
+ knowledgeProgress,
213
241
  }, children: children }));
214
242
  }
215
243
  export function useToolpack() {
@@ -219,3 +247,27 @@ export function useToolpack() {
219
247
  }
220
248
  return context;
221
249
  }
250
+ function ensureGlobalKnowledgeAssets() {
251
+ const sourceDir = path.join(__dirname, '..', '..', 'knowledge');
252
+ const globalDir = path.join(os.homedir(), '.toolpack');
253
+ const targetDir = path.join(globalDir, 'knowledge');
254
+ fs.mkdirSync(globalDir, { recursive: true });
255
+ copyDirectoryRecursive(sourceDir, targetDir);
256
+ return targetDir;
257
+ }
258
+ function copyDirectoryRecursive(source, destination) {
259
+ if (!fs.existsSync(source)) {
260
+ return;
261
+ }
262
+ const stats = fs.statSync(source);
263
+ if (stats.isDirectory()) {
264
+ fs.mkdirSync(destination, { recursive: true });
265
+ for (const entry of fs.readdirSync(source)) {
266
+ const srcPath = path.join(source, entry);
267
+ const destPath = path.join(destination, entry);
268
+ copyDirectoryRecursive(srcPath, destPath);
269
+ }
270
+ return;
271
+ }
272
+ fs.copyFileSync(source, destination);
273
+ }
@@ -10,10 +10,12 @@ import { HomeInput } from '../components/HomeInput.js';
10
10
  import { ModeSelect } from '../components/common/ModeSelect.js';
11
11
  import { ModelSelect } from '../components/common/ModelSelect.js';
12
12
  import { HistorySelect } from '../components/common/HistorySelect.js';
13
+ import { KnowledgeLoader } from '../components/KnowledgeLoader.js';
13
14
  export function HomeScreen() {
14
15
  const { theme } = useTheme();
15
16
  const { stdout } = useStdout();
16
- const { setMode, setModel, models } = useToolpack();
17
+ const { setMode, setModel, models, knowledgeProgress } = useToolpack();
18
+ const knowledgeReady = !knowledgeProgress || knowledgeProgress.phase === 'complete';
17
19
  const { loadConversation, setScreen } = useConversation();
18
20
  // 0 = TextInput, 1 = Mode, 2 = Model, 3 = History
19
21
  const [focusedIndex, setFocusedIndex] = useState(0);
@@ -37,7 +39,7 @@ export function HomeScreen() {
37
39
  setScreen('settings');
38
40
  }
39
41
  });
40
- return (_jsxs(Box, { width: stdout.columns, height: stdout.rows - 1, flexDirection: "column", position: "relative", children: [_jsxs(Box, { width: "100%", alignItems: "center", flexDirection: "column", paddingTop: 6, flexShrink: 0, children: [_jsx(Logo, {}), _jsx(AppInfo, {})] }), _jsx(Box, { flexGrow: 1, width: "100%", justifyContent: "center", alignItems: "center", flexDirection: "column", children: _jsx(Box, { width: "80%", children: _jsx(HomeInput, { focusedIndex: focusedIndex, showModeSelect: showModeSelect, setShowModeSelect: setShowModeSelect, showModelSelect: showModelSelect, setShowModelSelect: setShowModelSelect, showHistorySelect: showHistorySelect, setShowHistorySelect: setShowHistorySelect }) }) }), _jsx(Box, { width: "100%", flexDirection: "column", alignItems: "center", paddingBottom: 1, flexShrink: 0, children: _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.colors.textSecondary, children: [_jsx(Text, { color: "#eab308", bold: true, children: "\u2022 Note" }), ' ', "If you are using local models, make sure to have them downloaded and available."] }) }) }), showModeSelect && (_jsx(ModeSelect, { onSelect: val => {
42
+ return (_jsxs(Box, { width: stdout.columns, height: stdout.rows - 1, flexDirection: "column", position: "relative", children: [_jsxs(Box, { width: "100%", alignItems: "center", flexDirection: "column", paddingTop: 6, flexShrink: 0, children: [_jsx(Logo, {}), _jsx(AppInfo, {}), knowledgeProgress && knowledgeProgress.phase !== 'complete' && (_jsx(Box, { width: "100%", marginTop: 1, alignItems: "center", justifyContent: "center", children: _jsx(KnowledgeLoader, {}) }))] }), _jsx(Box, { flexGrow: 1, width: "100%", justifyContent: "center", alignItems: "center", flexDirection: "column", children: knowledgeReady ? (_jsx(Box, { width: "80%", children: _jsx(HomeInput, { focusedIndex: focusedIndex, showModeSelect: showModeSelect, setShowModeSelect: setShowModeSelect, showModelSelect: showModelSelect, setShowModelSelect: setShowModelSelect, showHistorySelect: showHistorySelect, setShowHistorySelect: setShowHistorySelect }) })) : (_jsx(Text, { color: theme.colors.textSecondary, children: "Preparing knowledge workspace\u2026" })) }), _jsx(Box, { width: "100%", flexDirection: "column", alignItems: "center", paddingBottom: 1, flexShrink: 0, children: _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.colors.textSecondary, children: [_jsx(Text, { color: "#eab308", bold: true, children: "\u2022 Note" }), ' ', "If you are using local models, make sure to have them downloaded and available."] }) }) }), showModeSelect && (_jsx(ModeSelect, { onSelect: val => {
41
43
  setMode(val);
42
44
  setShowModeSelect(false);
43
45
  setFocusedIndex(0); // Return focus to input
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolpack-cli",
3
- "version": "1.0.1",
3
+ "version": "1.1.0-SNAPSHOT",
4
4
  "description": "Rich interactive command-line interface directly powering the Toolpack SDK",
5
5
  "license": "Apache-2.0",
6
6
  "preferGlobal": true,
@@ -56,7 +56,7 @@
56
56
  "node-pty": "^1.1.0",
57
57
  "open": "^11.0.0",
58
58
  "react": "^18.2.0",
59
- "toolpack-sdk": "latest",
59
+ "toolpack-sdk": "1.1.0-SNAPSHOT",
60
60
  "uuid": "^13.0.0"
61
61
  },
62
62
  "devDependencies": {