noiton 2.0.0 → 2.0.2
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 +2 -12
- package/package.json +2 -7
- package/src/commands/init.js +82 -30
- package/src/index.js +0 -5
- package/src/lib/agents/hermes.js +20 -1
- package/src/lib/agents/index.js +42 -12
- package/src/lib/agents/opencode.js +19 -1
- package/src/lib/detect.js +47 -107
- package/src/lib/install.js +0 -2
- package/src/octopus.js +163 -181
- package/src/ui.js +34 -0
- package/src/lib/agents/aider.js +0 -141
- package/src/lib/agents/cline.js +0 -128
- package/src/lib/agents/kilo.js +0 -140
- package/src/lib/agents/kimi.js +0 -149
- package/src/lib/agents/openclaw.js +0 -155
package/src/lib/detect.js
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* NOITON Agent Detection
|
|
3
3
|
*
|
|
4
|
-
* Detects which AI coding agents are installed on the system
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Returns a list of detected agents with metadata.
|
|
4
|
+
* Detects which AI coding agents are installed on the system.
|
|
5
|
+
* Detection requires the CLI binary to be on PATH (not just config files,
|
|
6
|
+
* which can be leftover from uninstalled tools).
|
|
9
7
|
*/
|
|
10
8
|
|
|
11
9
|
import { existsSync } from "node:fs";
|
|
12
10
|
import { join } from "node:path";
|
|
13
11
|
import { homedir } from "node:os";
|
|
14
12
|
import { execSync } from "node:child_process";
|
|
15
|
-
import { c } from "../constants.js";
|
|
16
13
|
|
|
17
14
|
const HOME = homedir();
|
|
18
15
|
const XDG = process.env.XDG_CONFIG_HOME || join(HOME, ".config");
|
|
@@ -24,7 +21,7 @@ const XDG = process.env.XDG_CONFIG_HOME || join(HOME, ".config");
|
|
|
24
21
|
*/
|
|
25
22
|
function hasBin(bin) {
|
|
26
23
|
try {
|
|
27
|
-
execSync(`
|
|
24
|
+
execSync(`command -v ${bin} 2>/dev/null`, { stdio: "ignore" });
|
|
28
25
|
return true;
|
|
29
26
|
} catch {
|
|
30
27
|
return false;
|
|
@@ -44,7 +41,6 @@ function getBinVersion(bin) {
|
|
|
44
41
|
encoding: "utf8",
|
|
45
42
|
timeout: 5000,
|
|
46
43
|
}).trim();
|
|
47
|
-
// Extract first version-like token
|
|
48
44
|
const match = out.match(/(\d+\.\d+(?:\.\d+)?(?:-\w+)?)/);
|
|
49
45
|
if (match) return match[1];
|
|
50
46
|
return out.split("\n")[0];
|
|
@@ -76,8 +72,6 @@ function getNpmLatest(pkg) {
|
|
|
76
72
|
/**
|
|
77
73
|
* Compare two semver-like version strings.
|
|
78
74
|
* Returns: 1 if a > b, -1 if a < b, 0 if equal.
|
|
79
|
-
* @param {string} a
|
|
80
|
-
* @param {string} b
|
|
81
75
|
*/
|
|
82
76
|
function compareVersions(a, b) {
|
|
83
77
|
const pa = a.split(".").map(Number);
|
|
@@ -93,10 +87,6 @@ function compareVersions(a, b) {
|
|
|
93
87
|
|
|
94
88
|
// ============= AGENT DEFINITIONS =============
|
|
95
89
|
|
|
96
|
-
/**
|
|
97
|
-
* Registry of all supported agents.
|
|
98
|
-
* Each entry describes how to detect the agent and where its config lives.
|
|
99
|
-
*/
|
|
100
90
|
export const AGENT_REGISTRY = [
|
|
101
91
|
{
|
|
102
92
|
id: "opencode",
|
|
@@ -125,109 +115,42 @@ export const AGENT_REGISTRY = [
|
|
|
125
115
|
description: "Assistente que faz tarefas e se integra com apps",
|
|
126
116
|
useCase: "assistant",
|
|
127
117
|
},
|
|
128
|
-
{
|
|
129
|
-
id: "openclaw",
|
|
130
|
-
name: "OpenClaw",
|
|
131
|
-
type: "CLI",
|
|
132
|
-
bin: "openclaw",
|
|
133
|
-
npmPkg: null,
|
|
134
|
-
installMethod: null,
|
|
135
|
-
installCmd: null,
|
|
136
|
-
configPath: join(HOME, ".openclaw", "openclaw.json"),
|
|
137
|
-
supportsMultipleModels: true,
|
|
138
|
-
description: "Agente de IA open-source com providers customizáveis",
|
|
139
|
-
useCase: "programming",
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
id: "cline",
|
|
143
|
-
name: "Cline",
|
|
144
|
-
type: "VSCode Extension",
|
|
145
|
-
bin: null,
|
|
146
|
-
npmPkg: null,
|
|
147
|
-
installMethod: null,
|
|
148
|
-
installCmd: null,
|
|
149
|
-
configPath: join(XDG, "Code", "User", "settings.json"),
|
|
150
|
-
supportsMultipleModels: true,
|
|
151
|
-
description: "Extensão VS Code para programação com IA",
|
|
152
|
-
useCase: "programming",
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
id: "aider",
|
|
156
|
-
name: "Aider",
|
|
157
|
-
type: "CLI",
|
|
158
|
-
bin: "aider",
|
|
159
|
-
npmPkg: null,
|
|
160
|
-
installMethod: "pip",
|
|
161
|
-
installCmd: "pip install aider-chat",
|
|
162
|
-
configPath: join(HOME, ".aider.conf.yml"),
|
|
163
|
-
supportsMultipleModels: false,
|
|
164
|
-
description: "Pair programmer de terminal que edita código com você",
|
|
165
|
-
useCase: "programming",
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
id: "kilo",
|
|
169
|
-
name: "Kilo Code",
|
|
170
|
-
type: "CLI + VSCode",
|
|
171
|
-
bin: "kilo",
|
|
172
|
-
npmPkg: "@kilocode/cli",
|
|
173
|
-
installMethod: "npm",
|
|
174
|
-
installCmd: "npm install -g @kilocode/cli",
|
|
175
|
-
configPath: join(XDG, "kilo", "kilo.jsonc"),
|
|
176
|
-
supportsMultipleModels: true,
|
|
177
|
-
description: "Agente de IA com CLI e extensão VS Code",
|
|
178
|
-
useCase: "programming",
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
id: "kimi",
|
|
182
|
-
name: "Kimi Code",
|
|
183
|
-
type: "CLI + VSCode",
|
|
184
|
-
bin: "kimi",
|
|
185
|
-
npmPkg: null,
|
|
186
|
-
installMethod: null,
|
|
187
|
-
installCmd: null,
|
|
188
|
-
configPath: join(HOME, ".kimi-code", "config.toml"),
|
|
189
|
-
supportsMultipleModels: false,
|
|
190
|
-
description: "Agente de IA da Moonshot com CLI e VS Code",
|
|
191
|
-
useCase: "programming",
|
|
192
|
-
},
|
|
193
118
|
];
|
|
194
119
|
|
|
195
120
|
/**
|
|
196
121
|
* Detect all installed agents.
|
|
122
|
+
* An agent is "installed" only if its binary is on PATH.
|
|
123
|
+
* Config files alone are NOT enough (could be leftover from uninstalled tools).
|
|
197
124
|
* @returns {Array} detected agents with status info
|
|
198
125
|
*/
|
|
199
126
|
export function detectAgents() {
|
|
200
127
|
const detected = [];
|
|
201
128
|
for (const agent of AGENT_REGISTRY) {
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
});
|
|
215
|
-
}
|
|
129
|
+
if (!agent.bin) continue;
|
|
130
|
+
const binFound = hasBin(agent.bin);
|
|
131
|
+
if (!binFound) continue;
|
|
132
|
+
|
|
133
|
+
const version = getBinVersion(agent.bin);
|
|
134
|
+
detected.push({
|
|
135
|
+
...agent,
|
|
136
|
+
installed: true,
|
|
137
|
+
version,
|
|
138
|
+
binFound: true,
|
|
139
|
+
configFound: existsSync(agent.configPath),
|
|
140
|
+
});
|
|
216
141
|
}
|
|
217
142
|
return detected;
|
|
218
143
|
}
|
|
219
144
|
|
|
220
145
|
/**
|
|
221
|
-
* Check if a specific agent is installed.
|
|
146
|
+
* Check if a specific agent is installed (binary on PATH).
|
|
222
147
|
* @param {string} id
|
|
223
148
|
* @returns {boolean}
|
|
224
149
|
*/
|
|
225
150
|
export function isAgentInstalled(id) {
|
|
226
151
|
const agent = AGENT_REGISTRY.find((a) => a.id === id);
|
|
227
|
-
if (!agent) return false;
|
|
228
|
-
|
|
229
|
-
const configFound = existsSync(agent.configPath);
|
|
230
|
-
return binFound || configFound;
|
|
152
|
+
if (!agent || !agent.bin) return false;
|
|
153
|
+
return hasBin(agent.bin);
|
|
231
154
|
}
|
|
232
155
|
|
|
233
156
|
/**
|
|
@@ -240,13 +163,10 @@ export function getOpenCodeStatus() {
|
|
|
240
163
|
if (!agent) return null;
|
|
241
164
|
|
|
242
165
|
const binFound = hasBin("opencode");
|
|
243
|
-
|
|
244
|
-
const installed = binFound || configFound;
|
|
166
|
+
if (!binFound) return null;
|
|
245
167
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const version = binFound ? getBinVersion("opencode") : null;
|
|
249
|
-
const latest = binFound ? getNpmLatest("opencode-ai") : null;
|
|
168
|
+
const version = getBinVersion("opencode");
|
|
169
|
+
const latest = getNpmLatest("opencode-ai");
|
|
250
170
|
const updateAvailable =
|
|
251
171
|
version && latest ? compareVersions(latest, version) > 0 : false;
|
|
252
172
|
|
|
@@ -256,8 +176,29 @@ export function getOpenCodeStatus() {
|
|
|
256
176
|
version,
|
|
257
177
|
latest,
|
|
258
178
|
updateAvailable,
|
|
259
|
-
binFound,
|
|
260
|
-
configFound,
|
|
179
|
+
binFound: true,
|
|
180
|
+
configFound: existsSync(agent.configPath),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Get the Hermes agent status.
|
|
186
|
+
* @returns {object|null}
|
|
187
|
+
*/
|
|
188
|
+
export function getHermesStatus() {
|
|
189
|
+
const agent = AGENT_REGISTRY.find((a) => a.id === "hermes");
|
|
190
|
+
if (!agent) return null;
|
|
191
|
+
|
|
192
|
+
const binFound = hasBin("hermes");
|
|
193
|
+
if (!binFound) return null;
|
|
194
|
+
|
|
195
|
+
const version = getBinVersion("hermes");
|
|
196
|
+
return {
|
|
197
|
+
...agent,
|
|
198
|
+
installed: true,
|
|
199
|
+
version,
|
|
200
|
+
binFound: true,
|
|
201
|
+
configFound: existsSync(agent.configPath),
|
|
261
202
|
};
|
|
262
203
|
}
|
|
263
204
|
|
|
@@ -275,7 +216,6 @@ export function getInstallableAgents() {
|
|
|
275
216
|
* @returns {object|null}
|
|
276
217
|
*/
|
|
277
218
|
export function getRecommendedAgent(useCase) {
|
|
278
|
-
// Prefer OpenCode for programming, Hermes for assistant
|
|
279
219
|
if (useCase === "programming") {
|
|
280
220
|
return AGENT_REGISTRY.find((a) => a.id === "opencode");
|
|
281
221
|
}
|
package/src/lib/install.js
CHANGED
|
@@ -80,8 +80,6 @@ export async function updateAgent(agentId) {
|
|
|
80
80
|
|
|
81
81
|
const updateCmds = {
|
|
82
82
|
opencode: "curl -fsSL https://opencode.ai/install | bash",
|
|
83
|
-
kilo: "npm update -g @kilocode/cli",
|
|
84
|
-
aider: "pip install --upgrade aider-chat",
|
|
85
83
|
hermes: "pip install --upgrade nous-hermes",
|
|
86
84
|
};
|
|
87
85
|
|