@tyvm/knowhow 0.0.108-dev.126b29e ā 0.0.108-dev.4a8ba55
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/package.json +2 -3
- package/src/agents/base/base.ts +9 -0
- package/src/agents/tools/index.ts +0 -1
- package/src/agents/tools/list.ts +0 -2
- package/src/chat/CliChatService.ts +7 -1
- package/src/chat/renderer/CompactRenderer.ts +20 -0
- package/src/chat/renderer/ConsoleRenderer.ts +19 -0
- package/src/chat/renderer/FancyRenderer.ts +19 -0
- package/src/chat/renderer/types.ts +11 -0
- package/src/cli.ts +79 -666
- package/src/clients/types.ts +12 -4
- package/src/commands/agent.ts +246 -0
- package/src/commands/misc.ts +169 -0
- package/src/commands/modules.ts +182 -0
- package/src/commands/services.ts +72 -0
- package/src/commands/workers.ts +160 -0
- package/src/config.ts +37 -0
- package/src/index.ts +1 -0
- package/src/plugins/plugins.ts +0 -21
- package/src/processors/JsonCompressor.ts +6 -6
- package/src/services/modules/index.ts +58 -49
- package/src/services/modules/types.ts +2 -0
- package/src/tunnel.ts +216 -0
- package/src/types.ts +0 -1
- package/src/worker.ts +65 -336
- package/src/workers/auth/WsMiddleware.ts +99 -0
- package/src/workers/auth/authMiddleware.ts +104 -0
- package/src/workers/auth/types.ts +14 -2
- package/tests/unit/modules/moduleLoading.test.ts +0 -25
- package/tests/unit/plugins/pluginLoading.test.ts +0 -85
- package/ts_build/package.json +2 -3
- package/ts_build/src/agents/base/base.js +10 -0
- package/ts_build/src/agents/base/base.js.map +1 -1
- package/ts_build/src/agents/tools/index.d.ts +0 -1
- package/ts_build/src/agents/tools/index.js +0 -1
- package/ts_build/src/agents/tools/index.js.map +1 -1
- package/ts_build/src/agents/tools/list.js +0 -2
- package/ts_build/src/agents/tools/list.js.map +1 -1
- package/ts_build/src/chat/CliChatService.js +10 -1
- package/ts_build/src/chat/CliChatService.js.map +1 -1
- package/ts_build/src/chat/renderer/CompactRenderer.d.ts +4 -0
- package/ts_build/src/chat/renderer/CompactRenderer.js +16 -0
- package/ts_build/src/chat/renderer/CompactRenderer.js.map +1 -1
- package/ts_build/src/chat/renderer/ConsoleRenderer.d.ts +4 -0
- package/ts_build/src/chat/renderer/ConsoleRenderer.js +16 -0
- package/ts_build/src/chat/renderer/ConsoleRenderer.js.map +1 -1
- package/ts_build/src/chat/renderer/FancyRenderer.d.ts +4 -0
- package/ts_build/src/chat/renderer/FancyRenderer.js +16 -0
- package/ts_build/src/chat/renderer/FancyRenderer.js.map +1 -1
- package/ts_build/src/chat/renderer/types.d.ts +2 -0
- package/ts_build/src/cli.js +40 -525
- package/ts_build/src/cli.js.map +1 -1
- package/ts_build/src/clients/types.d.ts +2 -2
- package/ts_build/src/commands/agent.d.ts +6 -0
- package/ts_build/src/commands/agent.js +229 -0
- package/ts_build/src/commands/agent.js.map +1 -0
- package/ts_build/src/commands/misc.d.ts +10 -0
- package/ts_build/src/commands/misc.js +195 -0
- package/ts_build/src/commands/misc.js.map +1 -0
- package/ts_build/src/commands/modules.d.ts +3 -0
- package/ts_build/src/commands/modules.js +160 -0
- package/ts_build/src/commands/modules.js.map +1 -0
- package/ts_build/src/commands/services.d.ts +5 -0
- package/ts_build/src/commands/services.js +86 -0
- package/ts_build/src/commands/services.js.map +1 -0
- package/ts_build/src/commands/workers.d.ts +6 -0
- package/ts_build/src/commands/workers.js +163 -0
- package/ts_build/src/commands/workers.js.map +1 -0
- package/ts_build/src/config.d.ts +1 -0
- package/ts_build/src/config.js +32 -0
- package/ts_build/src/config.js.map +1 -1
- package/ts_build/src/index.d.ts +1 -0
- package/ts_build/src/index.js +3 -1
- package/ts_build/src/index.js.map +1 -1
- package/ts_build/src/plugins/plugins.d.ts +0 -2
- package/ts_build/src/plugins/plugins.js +0 -11
- package/ts_build/src/plugins/plugins.js.map +1 -1
- package/ts_build/src/processors/JsonCompressor.js +4 -4
- package/ts_build/src/processors/JsonCompressor.js.map +1 -1
- package/ts_build/src/services/modules/index.d.ts +33 -0
- package/ts_build/src/services/modules/index.js +38 -42
- package/ts_build/src/services/modules/index.js.map +1 -1
- package/ts_build/src/services/modules/types.d.ts +2 -0
- package/ts_build/src/tunnel.d.ts +27 -0
- package/ts_build/src/tunnel.js +112 -0
- package/ts_build/src/tunnel.js.map +1 -0
- package/ts_build/src/types.d.ts +0 -1
- package/ts_build/src/types.js.map +1 -1
- package/ts_build/src/worker.d.ts +1 -4
- package/ts_build/src/worker.js +38 -244
- package/ts_build/src/worker.js.map +1 -1
- package/ts_build/src/workers/auth/WsMiddleware.d.ts +8 -0
- package/ts_build/src/workers/auth/WsMiddleware.js +65 -0
- package/ts_build/src/workers/auth/WsMiddleware.js.map +1 -0
- package/ts_build/src/workers/auth/authMiddleware.d.ts +3 -0
- package/ts_build/src/workers/auth/authMiddleware.js +60 -0
- package/ts_build/src/workers/auth/authMiddleware.js.map +1 -0
- package/ts_build/src/workers/auth/types.d.ts +8 -1
- package/ts_build/tests/unit/modules/moduleLoading.test.js +0 -19
- package/ts_build/tests/unit/modules/moduleLoading.test.js.map +1 -1
- package/ts_build/tests/unit/plugins/pluginLoading.test.js +0 -65
- package/ts_build/tests/unit/plugins/pluginLoading.test.js.map +1 -1
- package/src/agents/tools/executeScript/README.md +0 -94
- package/src/agents/tools/executeScript/definition.ts +0 -79
- package/src/agents/tools/executeScript/examples/dependency-injection-validation.ts +0 -272
- package/src/agents/tools/executeScript/examples/quick-test.ts +0 -74
- package/src/agents/tools/executeScript/examples/serialization-test.ts +0 -321
- package/src/agents/tools/executeScript/examples/test-runner.ts +0 -197
- package/src/agents/tools/executeScript/index.ts +0 -98
- package/src/services/script-execution/SandboxContext.ts +0 -282
- package/src/services/script-execution/ScriptExecutor.ts +0 -441
- package/src/services/script-execution/ScriptPolicy.ts +0 -194
- package/src/services/script-execution/ScriptTracer.ts +0 -249
- package/src/services/script-execution/types.ts +0 -134
- package/ts_build/src/agents/tools/executeScript/definition.d.ts +0 -2
- package/ts_build/src/agents/tools/executeScript/definition.js +0 -76
- package/ts_build/src/agents/tools/executeScript/definition.js.map +0 -1
- package/ts_build/src/agents/tools/executeScript/examples/dependency-injection-validation.d.ts +0 -18
- package/ts_build/src/agents/tools/executeScript/examples/dependency-injection-validation.js +0 -192
- package/ts_build/src/agents/tools/executeScript/examples/dependency-injection-validation.js.map +0 -1
- package/ts_build/src/agents/tools/executeScript/examples/quick-test.d.ts +0 -3
- package/ts_build/src/agents/tools/executeScript/examples/quick-test.js +0 -64
- package/ts_build/src/agents/tools/executeScript/examples/quick-test.js.map +0 -1
- package/ts_build/src/agents/tools/executeScript/examples/serialization-test.d.ts +0 -15
- package/ts_build/src/agents/tools/executeScript/examples/serialization-test.js +0 -266
- package/ts_build/src/agents/tools/executeScript/examples/serialization-test.js.map +0 -1
- package/ts_build/src/agents/tools/executeScript/examples/test-runner.d.ts +0 -4
- package/ts_build/src/agents/tools/executeScript/examples/test-runner.js +0 -208
- package/ts_build/src/agents/tools/executeScript/examples/test-runner.js.map +0 -1
- package/ts_build/src/agents/tools/executeScript/index.d.ts +0 -28
- package/ts_build/src/agents/tools/executeScript/index.js +0 -72
- package/ts_build/src/agents/tools/executeScript/index.js.map +0 -1
- package/ts_build/src/services/script-execution/SandboxContext.d.ts +0 -34
- package/ts_build/src/services/script-execution/SandboxContext.js +0 -189
- package/ts_build/src/services/script-execution/SandboxContext.js.map +0 -1
- package/ts_build/src/services/script-execution/ScriptExecutor.d.ts +0 -19
- package/ts_build/src/services/script-execution/ScriptExecutor.js +0 -269
- package/ts_build/src/services/script-execution/ScriptExecutor.js.map +0 -1
- package/ts_build/src/services/script-execution/ScriptPolicy.d.ts +0 -28
- package/ts_build/src/services/script-execution/ScriptPolicy.js +0 -115
- package/ts_build/src/services/script-execution/ScriptPolicy.js.map +0 -1
- package/ts_build/src/services/script-execution/ScriptTracer.d.ts +0 -19
- package/ts_build/src/services/script-execution/ScriptTracer.js +0 -186
- package/ts_build/src/services/script-execution/ScriptTracer.js.map +0 -1
- package/ts_build/src/services/script-execution/types.d.ts +0 -108
- package/ts_build/src/services/script-execution/types.js +0 -3
- package/ts_build/src/services/script-execution/types.js.map +0 -1
package/src/clients/types.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
export type ModelModality =
|
|
1
|
+
export type ModelModality =
|
|
2
|
+
| "completion"
|
|
3
|
+
| "embedding"
|
|
4
|
+
| "image"
|
|
5
|
+
| "audio"
|
|
6
|
+
| "video"
|
|
7
|
+
| "transcription";
|
|
2
8
|
|
|
3
9
|
export type MessageContent =
|
|
4
10
|
| { type: "text"; text: string }
|
|
@@ -8,7 +14,7 @@ export type MessageContent =
|
|
|
8
14
|
|
|
9
15
|
export interface Message {
|
|
10
16
|
role: "system" | "user" | "assistant" | "tool";
|
|
11
|
-
content?: string | MessageContent[];
|
|
17
|
+
content?: string | MessageContent[] | null;
|
|
12
18
|
|
|
13
19
|
name?: string;
|
|
14
20
|
tool_call_id?: string;
|
|
@@ -16,7 +22,7 @@ export interface Message {
|
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
export interface OutputMessage extends Message {
|
|
19
|
-
content
|
|
25
|
+
content?: string | null;
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
export interface ToolProp {
|
|
@@ -301,7 +307,9 @@ export interface GenericClient {
|
|
|
301
307
|
* When modality is provided, return only models for that modality (static list).
|
|
302
308
|
* When omitted, return ALL models (backward compat ā may do a live API call).
|
|
303
309
|
*/
|
|
304
|
-
getModels(
|
|
310
|
+
getModels(
|
|
311
|
+
modality?: ModelModality
|
|
312
|
+
): Promise<{ id: string; modality?: ModelModality[] }[]>;
|
|
305
313
|
/**
|
|
306
314
|
* Returns the context window limit and compression threshold for a given model,
|
|
307
315
|
* or undefined if the model is not known to this client.
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { readPromptFile } from "../ai";
|
|
3
|
+
import { AgentModule } from "../chat/modules/AgentModule";
|
|
4
|
+
import { AskModule } from "../chat/modules/AskModule";
|
|
5
|
+
import { SearchModule } from "../chat/modules/SearchModule";
|
|
6
|
+
import { SessionsModule } from "../chat/modules/SessionsModule";
|
|
7
|
+
import { SetupModule } from "../chat/modules/SetupModule";
|
|
8
|
+
|
|
9
|
+
async function readStdin(): Promise<string> {
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
let data = "";
|
|
12
|
+
process.stdin.setEncoding("utf8");
|
|
13
|
+
|
|
14
|
+
if (process.stdin.isTTY) {
|
|
15
|
+
resolve("");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
process.stdin.on("readable", () => {
|
|
20
|
+
const chunk = process.stdin.read();
|
|
21
|
+
if (chunk !== null) data += chunk;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
process.stdin.on("end", () => resolve(data.trim()));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function addAgentCommand(program: Command, getChatService: () => any): void {
|
|
29
|
+
program
|
|
30
|
+
.command("agent")
|
|
31
|
+
.description("Spin up agents directly from CLI")
|
|
32
|
+
.option(
|
|
33
|
+
"--provider <provider>",
|
|
34
|
+
"AI provider (openai, anthropic, google, xai)"
|
|
35
|
+
)
|
|
36
|
+
.option("--model <model>", "Specific model for the provider")
|
|
37
|
+
.option("--agent-name <name>", "Which agent to use", "Patcher")
|
|
38
|
+
.option(
|
|
39
|
+
"--max-time-limit <minutes>",
|
|
40
|
+
"Time limit for agent execution (minutes)",
|
|
41
|
+
"30"
|
|
42
|
+
)
|
|
43
|
+
.option(
|
|
44
|
+
"--max-spend-limit <dollars>",
|
|
45
|
+
"Cost limit for agent execution (dollars)",
|
|
46
|
+
"10"
|
|
47
|
+
)
|
|
48
|
+
.option("--message-id <messageId>", "Knowhow message ID for task tracking")
|
|
49
|
+
.option("--sync-fs", "Enable filesystem-based synchronization")
|
|
50
|
+
.option(
|
|
51
|
+
"--task-id <taskId>",
|
|
52
|
+
"Pre-generated task ID (used with --sync-fs for predictable agent directory path)"
|
|
53
|
+
)
|
|
54
|
+
.option("--prompt-file <path>", "Custom prompt template file with {text}")
|
|
55
|
+
.option("--input <text>", "Task input (fallback to stdin if not provided)")
|
|
56
|
+
.option(
|
|
57
|
+
"--resume",
|
|
58
|
+
"Resume a previously started task using the --task-id (local FS or remote)"
|
|
59
|
+
)
|
|
60
|
+
.action(async (options) => {
|
|
61
|
+
try {
|
|
62
|
+
const { setupServices } = await import("./services");
|
|
63
|
+
await setupServices();
|
|
64
|
+
const chatService = getChatService();
|
|
65
|
+
const agentModule = new AgentModule();
|
|
66
|
+
|
|
67
|
+
if (options.resume) {
|
|
68
|
+
const threads = await agentModule.loadThreadsForTask(
|
|
69
|
+
options.taskId,
|
|
70
|
+
options.messageId
|
|
71
|
+
);
|
|
72
|
+
const resumeInput =
|
|
73
|
+
options.input || "Please continue from where you left off.";
|
|
74
|
+
|
|
75
|
+
await agentModule.initialize(chatService);
|
|
76
|
+
const { taskCompleted: resumed } =
|
|
77
|
+
await agentModule.resumeFromMessages({
|
|
78
|
+
agentName: options.agentName || "Patcher",
|
|
79
|
+
input: resumeInput,
|
|
80
|
+
threads,
|
|
81
|
+
messageId: options.messageId,
|
|
82
|
+
taskId: options.taskId,
|
|
83
|
+
});
|
|
84
|
+
await resumed;
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let input = options.input;
|
|
89
|
+
|
|
90
|
+
if (!input && !options.promptFile) {
|
|
91
|
+
input = await readStdin();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
input = readPromptFile(options.promptFile, input);
|
|
95
|
+
|
|
96
|
+
if (!input) {
|
|
97
|
+
console.error(
|
|
98
|
+
"Error: No input provided. Use --input flag, pipe input via stdin, or provide --prompt-file."
|
|
99
|
+
);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
await agentModule.initialize(chatService);
|
|
104
|
+
const { taskCompleted } = await agentModule.setupAgent({
|
|
105
|
+
...options,
|
|
106
|
+
input,
|
|
107
|
+
maxTimeLimit: parseInt(options.maxTimeLimit, 10),
|
|
108
|
+
maxSpendLimit: parseFloat(options.maxSpendLimit),
|
|
109
|
+
run: true,
|
|
110
|
+
});
|
|
111
|
+
await taskCompleted;
|
|
112
|
+
} catch (error) {
|
|
113
|
+
console.error("Error running agent:", error);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function addAskCommand(program: Command, getChatService: () => any, getConfig: () => any): void {
|
|
120
|
+
program
|
|
121
|
+
.command("ask")
|
|
122
|
+
.description("Direct AI questioning without agent overhead")
|
|
123
|
+
.option("--provider <provider>", "AI provider to use")
|
|
124
|
+
.option("--model <model>", "Specific model")
|
|
125
|
+
.option("--input <text>", "Question (fallback to stdin if not provided)")
|
|
126
|
+
.option("--prompt-file <path>", "Custom prompt template file")
|
|
127
|
+
.action(async (options) => {
|
|
128
|
+
try {
|
|
129
|
+
const { setupServices } = await import("./services");
|
|
130
|
+
await setupServices();
|
|
131
|
+
const chatService = getChatService();
|
|
132
|
+
const config = getConfig();
|
|
133
|
+
let input = options.input;
|
|
134
|
+
|
|
135
|
+
if (!input && !options.promptFile) {
|
|
136
|
+
input = await readStdin();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
input = readPromptFile(options.promptFile, input);
|
|
140
|
+
|
|
141
|
+
if (!input) {
|
|
142
|
+
console.error(
|
|
143
|
+
"Error: No question provided. Use --input flag, pipe input via stdin, or provide --prompt-file."
|
|
144
|
+
);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const askModule = new AskModule();
|
|
149
|
+
await askModule.initialize(chatService);
|
|
150
|
+
await askModule.processAIQuery(input, {
|
|
151
|
+
plugins: config.plugins.enabled,
|
|
152
|
+
currentModel: options.model,
|
|
153
|
+
currentProvider: options.provider,
|
|
154
|
+
chatHistory: [],
|
|
155
|
+
});
|
|
156
|
+
} catch (error) {
|
|
157
|
+
console.error("Error asking AI:", error);
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function addSetupCommand(program: Command, getChatService: () => any): void {
|
|
164
|
+
program
|
|
165
|
+
.command("setup")
|
|
166
|
+
.description("Ask the agent to configure knowhow")
|
|
167
|
+
.action(async () => {
|
|
168
|
+
try {
|
|
169
|
+
const { setupServices } = await import("./services");
|
|
170
|
+
await setupServices();
|
|
171
|
+
const chatService = getChatService();
|
|
172
|
+
const agentModule = new AgentModule();
|
|
173
|
+
await agentModule.initialize(chatService);
|
|
174
|
+
const setupModule = new SetupModule(agentModule);
|
|
175
|
+
await setupModule.initialize(chatService);
|
|
176
|
+
await setupModule.handleSetupCommand([]);
|
|
177
|
+
} catch (error) {
|
|
178
|
+
console.error("Error running agent:", error);
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export function addSearchCommand(program: Command): void {
|
|
185
|
+
program
|
|
186
|
+
.command("search")
|
|
187
|
+
.description("Search embeddings directly from CLI")
|
|
188
|
+
.option(
|
|
189
|
+
"--input <text>",
|
|
190
|
+
"Search query (fallback to stdin if not provided)"
|
|
191
|
+
)
|
|
192
|
+
.option(
|
|
193
|
+
"-e, --embedding <path>",
|
|
194
|
+
"Specific embedding path (default: all)",
|
|
195
|
+
"all"
|
|
196
|
+
)
|
|
197
|
+
.action(async (options) => {
|
|
198
|
+
try {
|
|
199
|
+
const { setupServices } = await import("./services");
|
|
200
|
+
await setupServices();
|
|
201
|
+
let input = options.input;
|
|
202
|
+
if (!input) {
|
|
203
|
+
input = await readStdin();
|
|
204
|
+
if (!input) {
|
|
205
|
+
console.error(
|
|
206
|
+
"Error: No search query provided. Use --input flag or pipe input via stdin."
|
|
207
|
+
);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
await new SearchModule().searchEmbeddingsCLI(input, options.embedding);
|
|
213
|
+
} catch (error) {
|
|
214
|
+
console.error("Error searching embeddings:", error);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function addSessionsCommand(program: Command, getChatService: () => any): void {
|
|
221
|
+
program
|
|
222
|
+
.command("sessions")
|
|
223
|
+
.description("Manage agent sessions from CLI")
|
|
224
|
+
.option(
|
|
225
|
+
"--all",
|
|
226
|
+
"Show all historical sessions (default: current process only)"
|
|
227
|
+
)
|
|
228
|
+
.option("--csv", "Output sessions as CSV")
|
|
229
|
+
.action(async (options) => {
|
|
230
|
+
try {
|
|
231
|
+
const chatService = getChatService();
|
|
232
|
+
const agentModule = new AgentModule();
|
|
233
|
+
await agentModule.initialize(chatService);
|
|
234
|
+
const sessionsModule = new SessionsModule(agentModule);
|
|
235
|
+
await sessionsModule.initialize(chatService);
|
|
236
|
+
await sessionsModule.logSessionTable(
|
|
237
|
+
options.all || false,
|
|
238
|
+
options.csv || false,
|
|
239
|
+
true
|
|
240
|
+
);
|
|
241
|
+
} catch (error) {
|
|
242
|
+
console.error("Error listing sessions:", error);
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import { version } from "../../package.json";
|
|
4
|
+
import { generate, embed, upload, download, purge } from "../index";
|
|
5
|
+
import { init } from "../config";
|
|
6
|
+
import { login } from "../login";
|
|
7
|
+
import { KnowhowSimpleClient } from "../services/KnowhowClient";
|
|
8
|
+
import { startChat } from "../chat";
|
|
9
|
+
|
|
10
|
+
export function addInitCommand(program: Command): void {
|
|
11
|
+
program
|
|
12
|
+
.command("init")
|
|
13
|
+
.description("Initialize knowhow configuration")
|
|
14
|
+
.action(async () => {
|
|
15
|
+
await init();
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function addLoginCommand(program: Command): void {
|
|
20
|
+
program
|
|
21
|
+
.command("login")
|
|
22
|
+
.description("Login to knowhow")
|
|
23
|
+
.option("--jwt", "Use manual JWT input instead of browser login")
|
|
24
|
+
.action(async (opts) => {
|
|
25
|
+
await login(opts.jwt);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function addUpdateCommand(program: Command): void {
|
|
30
|
+
program
|
|
31
|
+
.command("update")
|
|
32
|
+
.description("Update knowhow to the latest version from npm")
|
|
33
|
+
.action(async () => {
|
|
34
|
+
try {
|
|
35
|
+
console.log("š Checking for knowhow updates...");
|
|
36
|
+
console.log(`Current version: ${version}`);
|
|
37
|
+
console.log("š¦ Installing latest version from npm...");
|
|
38
|
+
execSync("npm install -g @tyvm/knowhow@latest", {
|
|
39
|
+
stdio: "inherit",
|
|
40
|
+
encoding: "utf-8",
|
|
41
|
+
});
|
|
42
|
+
console.log("ā knowhow has been updated successfully!");
|
|
43
|
+
console.log("Run 'knowhow --version' to see the new version.");
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error("Error updating knowhow:", error.message);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function addGenerateCommand(program: Command): void {
|
|
52
|
+
program
|
|
53
|
+
.command("generate")
|
|
54
|
+
.description("Generate documentation")
|
|
55
|
+
.action(async () => {
|
|
56
|
+
const { setupServices } = await import("./services");
|
|
57
|
+
await setupServices();
|
|
58
|
+
await generate();
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function addEmbedCommands(program: Command): void {
|
|
63
|
+
program
|
|
64
|
+
.command("embed")
|
|
65
|
+
.description("Create embeddings")
|
|
66
|
+
.action(async () => {
|
|
67
|
+
const { setupServices } = await import("./services");
|
|
68
|
+
await setupServices();
|
|
69
|
+
await embed();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
program
|
|
73
|
+
.command("embed:purge")
|
|
74
|
+
.description("Purge embeddings matching a glob pattern")
|
|
75
|
+
.argument("<pattern>", "Glob pattern to match files for purging")
|
|
76
|
+
.action(async (pattern) => {
|
|
77
|
+
await purge(pattern);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function addUploadCommand(program: Command): void {
|
|
82
|
+
program
|
|
83
|
+
.command("upload")
|
|
84
|
+
.description("Upload data")
|
|
85
|
+
.action(async () => {
|
|
86
|
+
await upload();
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function addDownloadCommand(program: Command): void {
|
|
91
|
+
program
|
|
92
|
+
.command("download")
|
|
93
|
+
.description("Download data")
|
|
94
|
+
.action(async () => {
|
|
95
|
+
await download();
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function addChatCommand(program: Command): void {
|
|
100
|
+
program
|
|
101
|
+
.command("chat")
|
|
102
|
+
.description("Start new chat interface")
|
|
103
|
+
.action(async () => {
|
|
104
|
+
const { setupServices } = await import("./services");
|
|
105
|
+
await setupServices();
|
|
106
|
+
await startChat();
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function addGithubCredentialsCommand(program: Command): void {
|
|
111
|
+
program
|
|
112
|
+
.command("github-credentials [action]")
|
|
113
|
+
.description(
|
|
114
|
+
"Git credential helper for GitHub. Use as: git config credential.helper 'knowhow github-credentials'"
|
|
115
|
+
)
|
|
116
|
+
.option(
|
|
117
|
+
"--repo <repo>",
|
|
118
|
+
"Repository in owner/repo format (e.g. myorg/myrepo)"
|
|
119
|
+
)
|
|
120
|
+
.action(async (action: string | undefined, options: { repo?: string }) => {
|
|
121
|
+
const client = new KnowhowSimpleClient();
|
|
122
|
+
|
|
123
|
+
let repo = options.repo;
|
|
124
|
+
|
|
125
|
+
if (action === "get") {
|
|
126
|
+
const lines: string[] = [];
|
|
127
|
+
const readline = await import("readline");
|
|
128
|
+
const rl = readline.createInterface({
|
|
129
|
+
input: process.stdin,
|
|
130
|
+
terminal: false,
|
|
131
|
+
});
|
|
132
|
+
await new Promise<void>((resolve) => {
|
|
133
|
+
rl.on("line", (line) => {
|
|
134
|
+
if (line.trim()) lines.push(line.trim());
|
|
135
|
+
});
|
|
136
|
+
rl.on("close", resolve);
|
|
137
|
+
});
|
|
138
|
+
} else if (action === "store" || action === "erase") {
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!repo) {
|
|
143
|
+
try {
|
|
144
|
+
const remoteUrl = execSync("git remote get-url origin", {
|
|
145
|
+
encoding: "utf-8",
|
|
146
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
147
|
+
}).trim();
|
|
148
|
+
const match =
|
|
149
|
+
remoteUrl.match(/github\.com[/:]([^/]+\/[^/]+?)(?:\.git)?$/) ||
|
|
150
|
+
remoteUrl.match(/github\.com\/([^/]+\/[^/]+)/);
|
|
151
|
+
if (match) {
|
|
152
|
+
repo = match[1];
|
|
153
|
+
}
|
|
154
|
+
} catch {
|
|
155
|
+
// Not in a git repo or no remote ā proceed without repo
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
const credential = await client.getGitCredential(repo || "");
|
|
161
|
+
process.stdout.write(
|
|
162
|
+
`protocol=${credential.protocol}\nhost=${credential.host}\nusername=${credential.username}\npassword=${credential.password}\n`
|
|
163
|
+
);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error("Failed to get git credentials:", error.message);
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import { getConfig, getGlobalConfig, updateConfig, updateGlobalConfig } from "../config";
|
|
4
|
+
|
|
5
|
+
// Default built-in modules that `knowhow modules setup` adds to the config.
|
|
6
|
+
export const BUILTIN_MODULES = [
|
|
7
|
+
"@tyvm/knowhow-module-script",
|
|
8
|
+
"@tyvm/knowhow-module-terminal",
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
export function addModulesCommand(program: Command): void {
|
|
12
|
+
const modulesCmd = program
|
|
13
|
+
.command("modules")
|
|
14
|
+
.description("Manage knowhow modules (install, add to config, list)");
|
|
15
|
+
|
|
16
|
+
modulesCmd
|
|
17
|
+
.command("setup")
|
|
18
|
+
.description(
|
|
19
|
+
"Add default built-in modules to your config and install them via npm"
|
|
20
|
+
)
|
|
21
|
+
.option("--global", "Use the global config (~/.knowhow/knowhow.json)")
|
|
22
|
+
.action(async (opts) => {
|
|
23
|
+
try {
|
|
24
|
+
const isGlobal: boolean = opts.global ?? false;
|
|
25
|
+
const cfg = isGlobal ? await getGlobalConfig() : await getConfig();
|
|
26
|
+
const configLabel = isGlobal
|
|
27
|
+
? "~/.knowhow/knowhow.json"
|
|
28
|
+
: ".knowhow/knowhow.json";
|
|
29
|
+
|
|
30
|
+
if (!cfg.modules) cfg.modules = [];
|
|
31
|
+
|
|
32
|
+
const toAdd = BUILTIN_MODULES.filter(
|
|
33
|
+
(m) => !cfg.modules!.includes(m)
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
if (toAdd.length === 0) {
|
|
37
|
+
console.log(
|
|
38
|
+
`ā
All default modules are already in ${configLabel}. Nothing to do.`
|
|
39
|
+
);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Install packages that are not local file paths
|
|
44
|
+
for (const mod of toAdd) {
|
|
45
|
+
if (!mod.startsWith(".") && !mod.startsWith("/")) {
|
|
46
|
+
console.log(`š¦ Installing ${mod}...`);
|
|
47
|
+
const installFlag = isGlobal ? "-g" : "";
|
|
48
|
+
execSync(`npm install ${installFlag} ${mod}`, {
|
|
49
|
+
stdio: "inherit",
|
|
50
|
+
encoding: "utf-8",
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
cfg.modules!.push(mod);
|
|
54
|
+
console.log(`ā
Added ${mod} to ${configLabel}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (isGlobal) {
|
|
58
|
+
await updateGlobalConfig(cfg);
|
|
59
|
+
} else {
|
|
60
|
+
await updateConfig(cfg);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log(
|
|
64
|
+
`\nš Setup complete! ${toAdd.length} module(s) added to ${configLabel}`
|
|
65
|
+
);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.error("Error during modules setup:", error.message ?? error);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
modulesCmd
|
|
73
|
+
.command("install [module]")
|
|
74
|
+
.description(
|
|
75
|
+
"Install a module via npm and add it to your config. " +
|
|
76
|
+
"If no module name is given, installs all modules already in the config."
|
|
77
|
+
)
|
|
78
|
+
.option("--global", "Use the global config (~/.knowhow/knowhow.json)")
|
|
79
|
+
.action(async (moduleName: string | undefined, opts) => {
|
|
80
|
+
try {
|
|
81
|
+
const isGlobal: boolean = opts.global ?? false;
|
|
82
|
+
const cfg = isGlobal ? await getGlobalConfig() : await getConfig();
|
|
83
|
+
const configLabel = isGlobal
|
|
84
|
+
? "~/.knowhow/knowhow.json"
|
|
85
|
+
: ".knowhow/knowhow.json";
|
|
86
|
+
|
|
87
|
+
if (!cfg.modules) cfg.modules = [];
|
|
88
|
+
|
|
89
|
+
if (!moduleName) {
|
|
90
|
+
// No module specified ā install everything already in the config
|
|
91
|
+
const installable = cfg.modules.filter(
|
|
92
|
+
(m) => !m.startsWith(".") && !m.startsWith("/")
|
|
93
|
+
);
|
|
94
|
+
if (installable.length === 0) {
|
|
95
|
+
console.log(
|
|
96
|
+
`ā¹ No installable modules found in ${configLabel}.`
|
|
97
|
+
);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
console.log(
|
|
101
|
+
`š¦ Installing ${installable.length} module(s) from ${configLabel}...`
|
|
102
|
+
);
|
|
103
|
+
const installFlag = isGlobal ? "-g" : "";
|
|
104
|
+
for (const mod of installable) {
|
|
105
|
+
console.log(` š¦ Installing ${mod}...`);
|
|
106
|
+
execSync(`npm install ${installFlag} ${mod}`, {
|
|
107
|
+
stdio: "inherit",
|
|
108
|
+
encoding: "utf-8",
|
|
109
|
+
});
|
|
110
|
+
console.log(` ā
Installed ${mod}`);
|
|
111
|
+
}
|
|
112
|
+
console.log(`\nš All modules installed!`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Install the specified module
|
|
117
|
+
const installFlag = isGlobal ? "-g" : "";
|
|
118
|
+
console.log(`š¦ Installing ${moduleName}...`);
|
|
119
|
+
execSync(`npm install ${installFlag} ${moduleName}`, {
|
|
120
|
+
stdio: "inherit",
|
|
121
|
+
encoding: "utf-8",
|
|
122
|
+
});
|
|
123
|
+
console.log(`ā
Installed ${moduleName}`);
|
|
124
|
+
|
|
125
|
+
// Add to config if not already there
|
|
126
|
+
if (!cfg.modules.includes(moduleName)) {
|
|
127
|
+
cfg.modules.push(moduleName);
|
|
128
|
+
if (isGlobal) {
|
|
129
|
+
await updateGlobalConfig(cfg);
|
|
130
|
+
} else {
|
|
131
|
+
await updateConfig(cfg);
|
|
132
|
+
}
|
|
133
|
+
console.log(`ā
Added ${moduleName} to ${configLabel}`);
|
|
134
|
+
} else {
|
|
135
|
+
console.log(`ā¹ ${moduleName} is already in ${configLabel}`);
|
|
136
|
+
}
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.error("Error during module install:", error.message ?? error);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
modulesCmd
|
|
144
|
+
.command("list")
|
|
145
|
+
.description("List all modules in your config")
|
|
146
|
+
.option("--global", "Show global config modules only")
|
|
147
|
+
.action(async (opts) => {
|
|
148
|
+
try {
|
|
149
|
+
const isGlobal: boolean = opts.global ?? false;
|
|
150
|
+
const globalCfg = await getGlobalConfig();
|
|
151
|
+
const localCfg = isGlobal ? null : await getConfig();
|
|
152
|
+
|
|
153
|
+
const globalModules = globalCfg.modules || [];
|
|
154
|
+
const localModules = localCfg?.modules || [];
|
|
155
|
+
|
|
156
|
+
if (isGlobal) {
|
|
157
|
+
console.log(`\nš Global modules (~/.knowhow/knowhow.json):`);
|
|
158
|
+
if (globalModules.length === 0) {
|
|
159
|
+
console.log(" (none)");
|
|
160
|
+
} else {
|
|
161
|
+
globalModules.forEach((m, i) => console.log(` ${i + 1}. ${m}`));
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
console.log(`\nš Global modules (~/.knowhow/knowhow.json):`);
|
|
165
|
+
if (globalModules.length === 0) {
|
|
166
|
+
console.log(" (none)");
|
|
167
|
+
} else {
|
|
168
|
+
globalModules.forEach((m, i) => console.log(` ${i + 1}. ${m}`));
|
|
169
|
+
}
|
|
170
|
+
console.log(`\nš Local modules (.knowhow/knowhow.json):`);
|
|
171
|
+
if (localModules.length === 0) {
|
|
172
|
+
console.log(" (none)");
|
|
173
|
+
} else {
|
|
174
|
+
localModules.forEach((m, i) => console.log(` ${i + 1}. ${m}`));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
} catch (error) {
|
|
178
|
+
console.error("Error listing modules:", error.message ?? error);
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|