chainlesschain 0.42.2 → 0.42.3
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/README.md +14 -0
- package/package.json +5 -2
- package/src/commands/agent.js +7 -6
- package/src/commands/ask.js +11 -9
- package/src/commands/chat.js +8 -7
- package/src/commands/update.js +33 -4
package/README.md
CHANGED
|
@@ -9,6 +9,20 @@ npm install -g chainlesschain
|
|
|
9
9
|
chainlesschain setup
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
+
After installation, three equivalent commands are available:
|
|
13
|
+
|
|
14
|
+
| Command | Description |
|
|
15
|
+
| ---------------- | ----------------------------------------------------------------- |
|
|
16
|
+
| `chainlesschain` | Full name |
|
|
17
|
+
| `cc` | Shortest alias, recommended for daily use |
|
|
18
|
+
| `clc` | ChainLessChain abbreviation, avoids `cc` conflict with C compiler |
|
|
19
|
+
| `clchain` | chainlesschain abbreviation, easy to recognize |
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cc setup # equivalent to: chainlesschain setup
|
|
23
|
+
clchain start # equivalent to: chainlesschain start
|
|
24
|
+
```
|
|
25
|
+
|
|
12
26
|
## Requirements
|
|
13
27
|
|
|
14
28
|
- **Node.js** >= 22.12.0
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chainlesschain",
|
|
3
|
-
"version": "0.42.
|
|
3
|
+
"version": "0.42.3",
|
|
4
4
|
"description": "CLI for ChainlessChain - install, configure, and manage your personal AI management system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"chainlesschain": "./bin/chainlesschain.js"
|
|
7
|
+
"chainlesschain": "./bin/chainlesschain.js",
|
|
8
|
+
"cc": "./bin/chainlesschain.js",
|
|
9
|
+
"clc": "./bin/chainlesschain.js",
|
|
10
|
+
"clchain": "./bin/chainlesschain.js"
|
|
8
11
|
},
|
|
9
12
|
"main": "src/index.js",
|
|
10
13
|
"scripts": {
|
package/src/commands/agent.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { startAgentRepl } from "../repl/agent-repl.js";
|
|
10
|
+
import { loadConfig } from "../lib/config-manager.js";
|
|
10
11
|
|
|
11
12
|
export function registerAgentCommand(program) {
|
|
12
13
|
program
|
|
@@ -15,21 +16,21 @@ export function registerAgentCommand(program) {
|
|
|
15
16
|
.description(
|
|
16
17
|
"Start an agentic AI session (reads/writes files, runs commands)",
|
|
17
18
|
)
|
|
18
|
-
.option("--model <model>", "Model name"
|
|
19
|
+
.option("--model <model>", "Model name")
|
|
19
20
|
.option(
|
|
20
21
|
"--provider <provider>",
|
|
21
22
|
"LLM provider (ollama, openai, volcengine, deepseek, ...)",
|
|
22
|
-
"ollama",
|
|
23
23
|
)
|
|
24
24
|
.option("--base-url <url>", "API base URL")
|
|
25
25
|
.option("--api-key <key>", "API key")
|
|
26
26
|
.option("--session <id>", "Resume a previous agent session")
|
|
27
27
|
.action(async (options) => {
|
|
28
|
+
const config = loadConfig();
|
|
28
29
|
await startAgentRepl({
|
|
29
|
-
model: options.model,
|
|
30
|
-
provider: options.provider,
|
|
31
|
-
baseUrl: options.baseUrl,
|
|
32
|
-
apiKey: options.apiKey,
|
|
30
|
+
model: options.model || config.llm?.model || "qwen2:7b",
|
|
31
|
+
provider: options.provider || config.llm?.provider || "ollama",
|
|
32
|
+
baseUrl: options.baseUrl || config.llm?.baseUrl,
|
|
33
|
+
apiKey: options.apiKey || config.llm?.apiKey,
|
|
33
34
|
sessionId: options.session,
|
|
34
35
|
});
|
|
35
36
|
});
|
package/src/commands/ask.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Single-shot AI question command
|
|
3
|
-
* chainlesschain ask "What is..." [--model
|
|
3
|
+
* chainlesschain ask "What is..." [--model] [--provider] [--json]
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import ora from "ora";
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
import { logger } from "../lib/logger.js";
|
|
9
9
|
import { BUILT_IN_PROVIDERS } from "../lib/llm-providers.js";
|
|
10
|
+
import { loadConfig } from "../lib/config-manager.js";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Send a single question to an LLM provider
|
|
@@ -84,24 +85,25 @@ export function registerAskCommand(program) {
|
|
|
84
85
|
.command("ask")
|
|
85
86
|
.description("Ask a question to the AI (single-shot)")
|
|
86
87
|
.argument("<question>", "The question to ask")
|
|
87
|
-
.option("--model <model>", "Model name"
|
|
88
|
+
.option("--model <model>", "Model name")
|
|
88
89
|
.option(
|
|
89
90
|
"--provider <provider>",
|
|
90
91
|
"LLM provider (ollama, openai, volcengine, deepseek, ...)",
|
|
91
|
-
"ollama",
|
|
92
92
|
)
|
|
93
93
|
.option("--base-url <url>", "API base URL")
|
|
94
94
|
.option("--api-key <key>", "API key")
|
|
95
95
|
.option("--json", "Output as JSON")
|
|
96
96
|
.action(async (question, options) => {
|
|
97
|
+
const config = loadConfig();
|
|
98
|
+
const resolvedOptions = {
|
|
99
|
+
model: options.model || config.llm?.model || "qwen2:7b",
|
|
100
|
+
provider: options.provider || config.llm?.provider || "ollama",
|
|
101
|
+
baseUrl: options.baseUrl || config.llm?.baseUrl,
|
|
102
|
+
apiKey: options.apiKey || config.llm?.apiKey,
|
|
103
|
+
};
|
|
97
104
|
const spinner = ora("Thinking...").start();
|
|
98
105
|
try {
|
|
99
|
-
const answer = await queryLLM(question,
|
|
100
|
-
model: options.model,
|
|
101
|
-
provider: options.provider,
|
|
102
|
-
baseUrl: options.baseUrl,
|
|
103
|
-
apiKey: options.apiKey,
|
|
104
|
-
});
|
|
106
|
+
const answer = await queryLLM(question, resolvedOptions);
|
|
105
107
|
|
|
106
108
|
spinner.stop();
|
|
107
109
|
|
package/src/commands/chat.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Interactive AI chat command
|
|
3
|
-
* chainlesschain chat [--model
|
|
3
|
+
* chainlesschain chat [--model] [--provider] [--agent]
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { startChatRepl } from "../repl/chat-repl.js";
|
|
7
7
|
import { startAgentRepl } from "../repl/agent-repl.js";
|
|
8
|
+
import { loadConfig } from "../lib/config-manager.js";
|
|
8
9
|
|
|
9
10
|
export function registerChatCommand(program) {
|
|
10
11
|
program
|
|
11
12
|
.command("chat")
|
|
12
13
|
.description("Start an interactive AI chat session")
|
|
13
|
-
.option("--model <model>", "Model name"
|
|
14
|
+
.option("--model <model>", "Model name")
|
|
14
15
|
.option(
|
|
15
16
|
"--provider <provider>",
|
|
16
17
|
"LLM provider (ollama, openai, volcengine, deepseek, ...)",
|
|
17
|
-
"ollama",
|
|
18
18
|
)
|
|
19
19
|
.option("--base-url <url>", "API base URL")
|
|
20
20
|
.option("--api-key <key>", "API key")
|
|
@@ -24,11 +24,12 @@ export function registerChatCommand(program) {
|
|
|
24
24
|
)
|
|
25
25
|
.option("--session <id>", "Resume a previous session (agent mode)")
|
|
26
26
|
.action(async (options) => {
|
|
27
|
+
const config = loadConfig();
|
|
27
28
|
const replOptions = {
|
|
28
|
-
model: options.model,
|
|
29
|
-
provider: options.provider,
|
|
30
|
-
baseUrl: options.baseUrl,
|
|
31
|
-
apiKey: options.apiKey,
|
|
29
|
+
model: options.model || config.llm?.model || "qwen2:7b",
|
|
30
|
+
provider: options.provider || config.llm?.provider || "ollama",
|
|
31
|
+
baseUrl: options.baseUrl || config.llm?.baseUrl,
|
|
32
|
+
apiKey: options.apiKey || config.llm?.apiKey,
|
|
32
33
|
sessionId: options.session,
|
|
33
34
|
};
|
|
34
35
|
|
package/src/commands/update.js
CHANGED
|
@@ -8,7 +8,7 @@ import logger from "../lib/logger.js";
|
|
|
8
8
|
|
|
9
9
|
async function selfUpdateCli(targetVersion) {
|
|
10
10
|
if (VERSION === targetVersion) {
|
|
11
|
-
return; // Already at the target version
|
|
11
|
+
return true; // Already at the target version
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
try {
|
|
@@ -17,12 +17,31 @@ async function selfUpdateCli(targetVersion) {
|
|
|
17
17
|
encoding: "utf-8",
|
|
18
18
|
stdio: "pipe",
|
|
19
19
|
});
|
|
20
|
-
|
|
20
|
+
// Verify the update actually took effect
|
|
21
|
+
try {
|
|
22
|
+
const newVersion = execSync("chainlesschain --version", {
|
|
23
|
+
encoding: "utf-8",
|
|
24
|
+
stdio: "pipe",
|
|
25
|
+
}).trim();
|
|
26
|
+
if (newVersion === targetVersion) {
|
|
27
|
+
logger.success(`CLI updated to v${targetVersion}`);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
logger.warn(
|
|
31
|
+
`CLI update ran but version is still ${newVersion}. Please run manually:\n npm install -g chainlesschain@${targetVersion}`,
|
|
32
|
+
);
|
|
33
|
+
return false;
|
|
34
|
+
} catch (_verifyErr) {
|
|
35
|
+
// Cannot verify, assume success
|
|
36
|
+
logger.success(`CLI updated to v${targetVersion}`);
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
21
39
|
} catch (_err) {
|
|
22
40
|
// npm global install may fail due to permissions; guide the user
|
|
23
41
|
logger.warn(
|
|
24
42
|
`CLI self-update failed. Please run manually:\n npm install -g chainlesschain@${targetVersion}`,
|
|
25
43
|
);
|
|
44
|
+
return false;
|
|
26
45
|
}
|
|
27
46
|
}
|
|
28
47
|
|
|
@@ -85,11 +104,21 @@ export function registerUpdateCommand(program) {
|
|
|
85
104
|
}
|
|
86
105
|
|
|
87
106
|
await downloadRelease(result.latestVersion, { force: options.force });
|
|
107
|
+
logger.success("Application already installed");
|
|
88
108
|
|
|
89
109
|
// Self-update the CLI npm package
|
|
90
|
-
await selfUpdateCli(result.latestVersion);
|
|
110
|
+
const cliUpdated = await selfUpdateCli(result.latestVersion);
|
|
91
111
|
|
|
92
|
-
|
|
112
|
+
if (cliUpdated) {
|
|
113
|
+
logger.success(`Updated to v${result.latestVersion}`);
|
|
114
|
+
} else {
|
|
115
|
+
logger.warn(
|
|
116
|
+
`Application binary updated, but CLI version remains at ${VERSION}.`,
|
|
117
|
+
);
|
|
118
|
+
logger.info(
|
|
119
|
+
`To complete the update, run:\n npm install -g chainlesschain@${result.latestVersion}`,
|
|
120
|
+
);
|
|
121
|
+
}
|
|
93
122
|
logger.info("Restart ChainlessChain to use the new version.");
|
|
94
123
|
} catch (err) {
|
|
95
124
|
if (err.name === "ExitPromptError") {
|