@linghun/cli 0.1.1 → 0.1.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/dist/main.js +100 -1
- package/package.json +4 -4
- package/scripts/postinstall.cjs +14 -2
package/dist/main.js
CHANGED
|
@@ -5,6 +5,7 @@ import { randomUUID } from "crypto";
|
|
|
5
5
|
import { readFile } from "fs/promises";
|
|
6
6
|
import { createRequire } from "module";
|
|
7
7
|
import { dirname, join } from "path";
|
|
8
|
+
import { Writable } from "stream";
|
|
8
9
|
import { fileURLToPath } from "url";
|
|
9
10
|
import { resolveProviderRuntimeContract } from "@linghun/providers";
|
|
10
11
|
import { LINGHUN_CLI_NAME, LINGHUN_NAME, LINGHUN_VERSION } from "@linghun/shared";
|
|
@@ -14,6 +15,7 @@ var helpText = `${LINGHUN_NAME} ${LINGHUN_VERSION}
|
|
|
14
15
|
${LINGHUN_CLI_NAME} \u8FDB\u5165\u4EA4\u4E92\u5F0F\u7EC8\u7AEF
|
|
15
16
|
${LINGHUN_CLI_NAME} --version \u663E\u793A\u7248\u672C\u53F7
|
|
16
17
|
${LINGHUN_CLI_NAME} --help \u663E\u793A\u5E2E\u52A9\u4FE1\u606F
|
|
18
|
+
${LINGHUN_CLI_NAME} run --prompt \u6587\u672C \u975E\u4EA4\u4E92\u6267\u884C\u4E00\u6B21\u4EFB\u52A1
|
|
17
19
|
${LINGHUN_CLI_NAME} sessions list [--json] \u5217\u51FA\u5F53\u524D\u9879\u76EE\u4F1A\u8BDD
|
|
18
20
|
${LINGHUN_CLI_NAME} sessions create [--message \u6587\u672C] \u65B0\u5EFA\u4F1A\u8BDD\uFF0C\u53EF\u5199\u5165\u4E00\u6761\u7528\u6237\u6D88\u606F
|
|
19
21
|
${LINGHUN_CLI_NAME} sessions append <id> --message \u6587\u672C \u8FFD\u52A0\u4E00\u6761\u7528\u6237\u6D88\u606F
|
|
@@ -71,6 +73,9 @@ async function runCli(argv) {
|
|
|
71
73
|
`, stderr: "", exitCode: 0 };
|
|
72
74
|
}
|
|
73
75
|
const normalized = normalizeSlashCommand(argv);
|
|
76
|
+
if (normalized[0] === "run") {
|
|
77
|
+
return runHeadlessCommand(normalized.slice(1));
|
|
78
|
+
}
|
|
74
79
|
if (normalized[0] === "sessions") {
|
|
75
80
|
return runSessionsCommand(normalized.slice(1));
|
|
76
81
|
}
|
|
@@ -104,7 +109,11 @@ function configurePlatformBundledRoot(kind, envName) {
|
|
|
104
109
|
const packageName = `@linghun/${kind}-${process.platform}-${process.arch}`;
|
|
105
110
|
try {
|
|
106
111
|
const require2 = createRequire(import.meta.url);
|
|
107
|
-
process.env[envName] = join(
|
|
112
|
+
process.env[envName] = join(
|
|
113
|
+
dirname(require2.resolve(`${packageName}/package.json`)),
|
|
114
|
+
"bundled",
|
|
115
|
+
kind
|
|
116
|
+
);
|
|
108
117
|
} catch {
|
|
109
118
|
}
|
|
110
119
|
}
|
|
@@ -312,6 +321,57 @@ function maskSecret(secret) {
|
|
|
312
321
|
if (secret.length <= 8) return "****";
|
|
313
322
|
return `${secret.slice(0, 3)}\u2026${secret.slice(-4)}`;
|
|
314
323
|
}
|
|
324
|
+
async function runHeadlessCommand(argv) {
|
|
325
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
326
|
+
return {
|
|
327
|
+
stdout: [
|
|
328
|
+
"\u7528\u6CD5\uFF1Alinghun run --prompt <\u6587\u672C> [--mode full-access] [--auto-approve]",
|
|
329
|
+
"",
|
|
330
|
+
"\u9009\u9879\uFF1A",
|
|
331
|
+
" --prompt, -p <\u6587\u672C> \u672C\u6B21\u4EFB\u52A1\u8BF4\u660E",
|
|
332
|
+
" --prompt-file <\u8DEF\u5F84> \u4ECE\u6587\u4EF6\u8BFB\u53D6\u4EFB\u52A1\u8BF4\u660E",
|
|
333
|
+
" --mode <\u6A21\u5F0F> default / auto-review / plan / full-access\uFF0C\u9ED8\u8BA4 full-access",
|
|
334
|
+
" --auto-approve \u81EA\u52A8\u6279\u51C6\u672C\u6B21 headless \u8FD0\u884C\u4E2D\u7684\u672C\u5730\u5DE5\u5177\u786E\u8BA4\uFF08\u9ED8\u8BA4\uFF09",
|
|
335
|
+
" --no-auto-approve \u9047\u5230\u672C\u5730\u5DE5\u5177\u786E\u8BA4\u65F6\u505C\u6B62",
|
|
336
|
+
" --max-approvals <\u6570\u91CF> \u81EA\u52A8\u6279\u51C6\u4E0A\u9650\uFF0C\u9ED8\u8BA4 32",
|
|
337
|
+
"",
|
|
338
|
+
"\u672A\u63D0\u4F9B --prompt \u6216 --prompt-file \u65F6\uFF0C\u4F1A\u4ECE stdin \u8BFB\u53D6\u4EFB\u52A1\u8BF4\u660E\u3002"
|
|
339
|
+
].join("\n") + "\n",
|
|
340
|
+
stderr: "",
|
|
341
|
+
exitCode: 0
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
const mode = readOption(argv, "--mode") ?? "full-access";
|
|
345
|
+
if (!["default", "auto-review", "plan", "full-access"].includes(mode)) {
|
|
346
|
+
return usageError("\u7528\u6CD5\uFF1Alinghun run --mode default|auto-review|plan|full-access");
|
|
347
|
+
}
|
|
348
|
+
const prompt = readOption(argv, "--prompt") ?? readOption(argv, "-p") ?? await readPromptFile(argv) ?? readPositionalPrompt(argv) ?? await readStdinPrompt();
|
|
349
|
+
if (!prompt?.trim()) {
|
|
350
|
+
return usageError("\u7528\u6CD5\uFF1Alinghun run --prompt <\u6587\u672C>\uFF0C\u6216\u901A\u8FC7 stdin \u8F93\u5165\u4EFB\u52A1\u8BF4\u660E\u3002");
|
|
351
|
+
}
|
|
352
|
+
const maxApprovalsRaw = readOption(argv, "--max-approvals");
|
|
353
|
+
let maxApprovals;
|
|
354
|
+
if (maxApprovalsRaw !== void 0) {
|
|
355
|
+
const parsed = Number.parseInt(maxApprovalsRaw, 10);
|
|
356
|
+
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
357
|
+
return usageError("\u7528\u6CD5\uFF1Alinghun run --max-approvals <\u975E\u8D1F\u6574\u6570>");
|
|
358
|
+
}
|
|
359
|
+
maxApprovals = parsed;
|
|
360
|
+
}
|
|
361
|
+
configureCliBundledRoot();
|
|
362
|
+
const stdout = new StringWritable();
|
|
363
|
+
const stderr = new StringWritable();
|
|
364
|
+
const { runHeadlessTask } = await import("@linghun/tui");
|
|
365
|
+
const exitCode = await runHeadlessTask({
|
|
366
|
+
prompt,
|
|
367
|
+
mode,
|
|
368
|
+
autoApprove: !argv.includes("--no-auto-approve"),
|
|
369
|
+
...maxApprovals !== void 0 ? { maxApprovals } : {},
|
|
370
|
+
stdout,
|
|
371
|
+
stderr
|
|
372
|
+
});
|
|
373
|
+
return { stdout: stdout.toString(), stderr: stderr.toString(), exitCode };
|
|
374
|
+
}
|
|
315
375
|
async function runSessionsCommand(argv) {
|
|
316
376
|
const [subcommand = "list", ...rest] = argv;
|
|
317
377
|
const [{ loadConfig, resolveStoragePaths }, { SessionStore }] = await Promise.all([
|
|
@@ -414,6 +474,35 @@ function normalizeSlashCommand(argv) {
|
|
|
414
474
|
}
|
|
415
475
|
return argv;
|
|
416
476
|
}
|
|
477
|
+
async function readPromptFile(argv) {
|
|
478
|
+
const path = readOption(argv, "--prompt-file");
|
|
479
|
+
if (!path) return void 0;
|
|
480
|
+
return readFile(path, "utf8");
|
|
481
|
+
}
|
|
482
|
+
function readPositionalPrompt(argv) {
|
|
483
|
+
const values = [];
|
|
484
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
485
|
+
const value = argv[i];
|
|
486
|
+
if (!value) continue;
|
|
487
|
+
if (value.startsWith("-")) {
|
|
488
|
+
if (optionTakesValue(value)) i += 1;
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
values.push(value);
|
|
492
|
+
}
|
|
493
|
+
return values.length > 0 ? values.join(" ") : void 0;
|
|
494
|
+
}
|
|
495
|
+
async function readStdinPrompt() {
|
|
496
|
+
if (process.stdin.isTTY) return void 0;
|
|
497
|
+
let text = "";
|
|
498
|
+
for await (const chunk of process.stdin) {
|
|
499
|
+
text += typeof chunk === "string" ? chunk : chunk.toString("utf8");
|
|
500
|
+
}
|
|
501
|
+
return text;
|
|
502
|
+
}
|
|
503
|
+
function optionTakesValue(option) {
|
|
504
|
+
return ["--prompt", "-p", "--prompt-file", "--mode", "--max-approvals"].includes(option);
|
|
505
|
+
}
|
|
417
506
|
function isSlashCommand(command, name) {
|
|
418
507
|
if (!command) {
|
|
419
508
|
return false;
|
|
@@ -451,6 +540,16 @@ function formatDiagnostics(diagnostics) {
|
|
|
451
540
|
return `${diagnostics.map((diagnostic) => `JSONL \u7B2C ${diagnostic.line} \u884C\u5DF2\u8DF3\u8FC7\uFF1A${diagnostic.message}`).join("\n")}
|
|
452
541
|
`;
|
|
453
542
|
}
|
|
543
|
+
var StringWritable = class extends Writable {
|
|
544
|
+
chunks = [];
|
|
545
|
+
_write(chunk, _encoding, callback) {
|
|
546
|
+
this.chunks.push(typeof chunk === "string" ? chunk : chunk.toString("utf8"));
|
|
547
|
+
callback();
|
|
548
|
+
}
|
|
549
|
+
toString() {
|
|
550
|
+
return this.chunks.join("");
|
|
551
|
+
}
|
|
552
|
+
};
|
|
454
553
|
|
|
455
554
|
// src/main.ts
|
|
456
555
|
var result = await runCli(process.argv.slice(2));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linghun/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@linghun/config": "0.1.0",
|
|
26
|
+
"@linghun/shared": "0.1.2",
|
|
27
|
+
"@linghun/providers": "0.1.1",
|
|
26
28
|
"@linghun/core": "0.1.0",
|
|
27
|
-
"@linghun/
|
|
28
|
-
"@linghun/shared": "0.1.0",
|
|
29
|
-
"@linghun/tui": "0.1.0"
|
|
29
|
+
"@linghun/tui": "0.1.1"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "tsup src/main.ts --format esm --clean",
|
package/scripts/postinstall.cjs
CHANGED
|
@@ -32,8 +32,20 @@ for (const packageName of [
|
|
|
32
32
|
const packageRoot = join(requireFromCli.resolve(`${packageName}/package.json`), "..");
|
|
33
33
|
const executable =
|
|
34
34
|
packageName.includes("codebase-memory")
|
|
35
|
-
? join(
|
|
36
|
-
|
|
35
|
+
? join(
|
|
36
|
+
packageRoot,
|
|
37
|
+
"bundled",
|
|
38
|
+
"codebase-memory",
|
|
39
|
+
packageName.replace("@linghun/codebase-memory-", ""),
|
|
40
|
+
"codebase-memory-mcp",
|
|
41
|
+
)
|
|
42
|
+
: join(
|
|
43
|
+
packageRoot,
|
|
44
|
+
"bundled",
|
|
45
|
+
"native-runner",
|
|
46
|
+
packageName.replace("@linghun/native-runner-", ""),
|
|
47
|
+
"linghun-native-runner",
|
|
48
|
+
);
|
|
37
49
|
if (existsSync(executable)) {
|
|
38
50
|
chmodSync(executable, 0o755);
|
|
39
51
|
}
|