miantiao.me 0.2.0 → 0.3.0
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/{app-YAGEJAXF.js → app-VCJ3SOSQ.js} +113 -54
- package/dist/index.js +2 -2
- package/package.json +1 -1
|
@@ -293,13 +293,6 @@ import { useRef as useRef8 } from "react";
|
|
|
293
293
|
import { ThreadPrimitive, useAuiState } from "@assistant-ui/react-ink";
|
|
294
294
|
import { Box as Box4, Text as Text4 } from "ink";
|
|
295
295
|
|
|
296
|
-
// packages/cli/src/theme.tsx
|
|
297
|
-
import { createContext, useContext, useMemo } from "react";
|
|
298
|
-
import {
|
|
299
|
-
MarkdownText,
|
|
300
|
-
useShikiHighlighter
|
|
301
|
-
} from "@assistant-ui/react-ink-markdown";
|
|
302
|
-
|
|
303
296
|
// src/theme-data.ts
|
|
304
297
|
var themes = [
|
|
305
298
|
{ id: "groknight", name: "GrokNight", description: "\u4E2D\u6027\u6697\u8272\uFF0C\u9ED8\u8BA4\u4E3B\u9898", dark: true, color: "#141414" },
|
|
@@ -331,7 +324,7 @@ function parseThemePreference(input) {
|
|
|
331
324
|
const name = input?.trim().toLowerCase();
|
|
332
325
|
if (!name)
|
|
333
326
|
return void 0;
|
|
334
|
-
return themeOptions.find((option) => option.id === name)?.id ?? aliases[name];
|
|
327
|
+
return themeOptions.find((option) => option.id === name)?.id ?? (Object.hasOwn(aliases, name) ? aliases[name] : void 0);
|
|
335
328
|
}
|
|
336
329
|
function resolveTheme(preference, prefersDark2) {
|
|
337
330
|
if (preference !== "auto")
|
|
@@ -342,7 +335,27 @@ function getThemeName(id) {
|
|
|
342
335
|
return themeOptions.find((option) => option.id === id)?.name ?? id;
|
|
343
336
|
}
|
|
344
337
|
|
|
338
|
+
// src/agent/tool-header.ts
|
|
339
|
+
function getToolHeader({ toolName, args }) {
|
|
340
|
+
switch (toolName) {
|
|
341
|
+
case "set_theme": {
|
|
342
|
+
const theme = typeof args?.theme === "string" ? args.theme : "";
|
|
343
|
+
const preference = parseThemePreference(theme);
|
|
344
|
+
return { verb: "Theme", target: preference ? getThemeName(preference) : theme };
|
|
345
|
+
}
|
|
346
|
+
case "open_page":
|
|
347
|
+
return { verb: "Open", target: typeof args?.path === "string" ? args.path : "" };
|
|
348
|
+
default:
|
|
349
|
+
return { verb: toolName, target: "" };
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
345
353
|
// packages/cli/src/theme.tsx
|
|
354
|
+
import { createContext, useContext, useMemo } from "react";
|
|
355
|
+
import {
|
|
356
|
+
MarkdownText,
|
|
357
|
+
useShikiHighlighter
|
|
358
|
+
} from "@assistant-ui/react-ink-markdown";
|
|
346
359
|
import { stripVTControlCharacters } from "node:util";
|
|
347
360
|
import { jsx } from "react/jsx-runtime";
|
|
348
361
|
function cleanText(text) {
|
|
@@ -608,7 +621,6 @@ function HomeSections({ page, ...selection }) {
|
|
|
608
621
|
|
|
609
622
|
// packages/cli/src/chat.tsx
|
|
610
623
|
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
611
|
-
var toolTitles = { set_theme: "Theme", open_page: "Open" };
|
|
612
624
|
function MessageBody({ message }) {
|
|
613
625
|
const { colors } = useTerminalStyle();
|
|
614
626
|
if (message.role === "user") {
|
|
@@ -630,12 +642,13 @@ function MessageBody({ message }) {
|
|
|
630
642
|
);
|
|
631
643
|
}
|
|
632
644
|
if (part.type === "tool-call") {
|
|
633
|
-
const
|
|
645
|
+
const { verb, target } = getToolHeader(part);
|
|
634
646
|
return /* @__PURE__ */ jsxs4(Text4, { color: colors.skill, children: [
|
|
635
647
|
"\u25C6 ",
|
|
636
|
-
cleanText(
|
|
648
|
+
cleanText(verb),
|
|
637
649
|
" ",
|
|
638
|
-
cleanText(
|
|
650
|
+
cleanText(target),
|
|
651
|
+
part.result !== void 0 && ` (${cleanText(String(part.result))})`
|
|
639
652
|
] }, part.toolCallId);
|
|
640
653
|
}
|
|
641
654
|
return null;
|
|
@@ -668,6 +681,14 @@ import { useEffect as useEffect5, useEffectEvent, useRef as useRef6 } from "reac
|
|
|
668
681
|
var composerPlaceholder = "\u95EE\u70B9\u4EC0\u4E48\uFF0C\u6216\u8F93\u5165 / \u67E5\u770B\u547D\u4EE4";
|
|
669
682
|
var composerBrand = { mark: "<MT/>", model: "V3.14 Pro" };
|
|
670
683
|
|
|
684
|
+
// src/utils/tags.ts
|
|
685
|
+
function getTagSlug(tag) {
|
|
686
|
+
return encodeURIComponent(tag);
|
|
687
|
+
}
|
|
688
|
+
function getTagPath(tag) {
|
|
689
|
+
return `/tags/${getTagSlug(tag)}/`;
|
|
690
|
+
}
|
|
691
|
+
|
|
671
692
|
// src/agent/commands.ts
|
|
672
693
|
var commands = [
|
|
673
694
|
{ id: "help", description: "\u67E5\u770B\u53EF\u7528\u547D\u4EE4" },
|
|
@@ -676,7 +697,7 @@ var commands = [
|
|
|
676
697
|
{ id: "home", description: "\u6253\u5F00\u9996\u9875" },
|
|
677
698
|
{ id: "blog", description: "\u6D4F\u89C8\u5168\u90E8\u6587\u7AE0" },
|
|
678
699
|
{ id: "projects", description: "\u67E5\u770B\u6298\u817E\u7684\u9879\u76EE" },
|
|
679
|
-
{ id: "tags", description: "\u6309\u6807\u7B7E\u6D4F\u89C8\u6587\u7AE0" },
|
|
700
|
+
{ id: "tags", args: "[\u6807\u7B7E]", description: "\u6309\u6807\u7B7E\u6D4F\u89C8\u6587\u7AE0" },
|
|
680
701
|
{ id: "search", args: "[\u5173\u952E\u8BCD]", description: "\u641C\u7D22\u6587\u7AE0" },
|
|
681
702
|
{ id: "about", description: "\u5173\u4E8E\u672C\u7AD9" },
|
|
682
703
|
{ id: "rss", description: "\u8BA2\u9605 RSS" }
|
|
@@ -688,6 +709,13 @@ var pageCommands = {
|
|
|
688
709
|
tags: "/tags/",
|
|
689
710
|
about: "/about/"
|
|
690
711
|
};
|
|
712
|
+
function getCommandPath(name, args = "") {
|
|
713
|
+
if (name === "search")
|
|
714
|
+
return getSearchPath(args);
|
|
715
|
+
if (name === "tags" && args)
|
|
716
|
+
return getTagPath(args);
|
|
717
|
+
return Object.hasOwn(pageCommands, name) ? pageCommands[name] : void 0;
|
|
718
|
+
}
|
|
691
719
|
function parseCommand(input) {
|
|
692
720
|
const match = input.trim().match(/^\/(\S+)(?:\s+([\s\S]*))?$/);
|
|
693
721
|
if (!match)
|
|
@@ -704,7 +732,7 @@ import { useEffect as useEffect2, useImperativeHandle as useImperativeHandle2, u
|
|
|
704
732
|
|
|
705
733
|
// packages/cli/src/commands.ts
|
|
706
734
|
var terminalCommands = [
|
|
707
|
-
...commands
|
|
735
|
+
...commands,
|
|
708
736
|
{ id: "read", args: "<\u7F16\u53F7\u3001slug \u6216\u8DEF\u5F84>", description: "\u9605\u8BFB\u6587\u7AE0\u5168\u6587" },
|
|
709
737
|
{ id: "open", args: "[\u7F16\u53F7\u6216 URL]", description: "\u5728\u6D4F\u89C8\u5668\u6253\u5F00\u5F53\u524D\u9875\u9762\u6216\u94FE\u63A5" },
|
|
710
738
|
{ id: "refresh", description: "\u4ECE\u5B98\u7F51\u5237\u65B0\u5F53\u524D\u9875\u9762" },
|
|
@@ -1144,28 +1172,44 @@ function TerminalPanels({
|
|
|
1144
1172
|
// packages/cli/src/run-status.tsx
|
|
1145
1173
|
import { LoadingPrimitive } from "@assistant-ui/react-ink";
|
|
1146
1174
|
import { Box as Box9, Text as Text9 } from "ink";
|
|
1175
|
+
|
|
1176
|
+
// src/agent/useElapsedTime.ts
|
|
1147
1177
|
import { useEffect as useEffect4, useState as useState7 } from "react";
|
|
1148
|
-
|
|
1149
|
-
function RunStatus({ running, loading }) {
|
|
1150
|
-
const { colors } = useTerminalStyle();
|
|
1178
|
+
function useElapsedTime(active, live = false) {
|
|
1151
1179
|
const [seconds, setSeconds] = useState7(0);
|
|
1152
1180
|
useEffect4(() => {
|
|
1153
|
-
if (!
|
|
1154
|
-
|
|
1181
|
+
if (!active)
|
|
1182
|
+
return;
|
|
1183
|
+
const startedAt = Date.now();
|
|
1184
|
+
const elapsed = () => (Date.now() - startedAt) / 1e3;
|
|
1185
|
+
const finish = () => setSeconds(elapsed());
|
|
1155
1186
|
setSeconds(0);
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1187
|
+
if (!live)
|
|
1188
|
+
return finish;
|
|
1189
|
+
const timer = setInterval(finish, 1e3);
|
|
1190
|
+
return () => {
|
|
1191
|
+
clearInterval(timer);
|
|
1192
|
+
finish();
|
|
1193
|
+
};
|
|
1194
|
+
}, [active, live]);
|
|
1195
|
+
return seconds;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
// packages/cli/src/run-status.tsx
|
|
1199
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1200
|
+
function RunStatus({ running, loading }) {
|
|
1201
|
+
const { colors } = useTerminalStyle();
|
|
1202
|
+
const seconds = useElapsedTime(running, true);
|
|
1159
1203
|
if (!running && !loading) return null;
|
|
1160
1204
|
return /* @__PURE__ */ jsxs9(Box9, { paddingLeft: 2, height: 1, children: [
|
|
1161
1205
|
/* @__PURE__ */ jsx10(LoadingPrimitive.Spinner, {}),
|
|
1162
1206
|
/* @__PURE__ */ jsxs9(Text9, { color: colors.fg, children: [
|
|
1163
1207
|
" ",
|
|
1164
|
-
loading ? "\u601D\u8003\u4E2D\u2026
|
|
1208
|
+
loading ? "\u601D\u8003\u4E2D\u2026" : "\u56DE\u590D\u4E2D\u2026"
|
|
1165
1209
|
] }),
|
|
1166
1210
|
running && /* @__PURE__ */ jsxs9(Text9, { color: colors.muted, children: [
|
|
1167
1211
|
" ",
|
|
1168
|
-
seconds,
|
|
1212
|
+
Math.floor(seconds),
|
|
1169
1213
|
"s"
|
|
1170
1214
|
] }),
|
|
1171
1215
|
/* @__PURE__ */ jsx10(Box9, { flexGrow: 1 }),
|
|
@@ -1535,6 +1579,42 @@ async function loadPage(client, path, signal) {
|
|
|
1535
1579
|
import { useApp, useInput as useInput8 } from "ink";
|
|
1536
1580
|
import { useCallback as useCallback2, useState as useState10 } from "react";
|
|
1537
1581
|
|
|
1582
|
+
// src/agent/command-actions.ts
|
|
1583
|
+
async function runSharedCommand(name, args, actions) {
|
|
1584
|
+
const path = getCommandPath(name, args);
|
|
1585
|
+
if (path) {
|
|
1586
|
+
actions.setPanel(null);
|
|
1587
|
+
await actions.navigate(path, `/${name} ${args}`.trim());
|
|
1588
|
+
return true;
|
|
1589
|
+
}
|
|
1590
|
+
switch (name) {
|
|
1591
|
+
case "help":
|
|
1592
|
+
case "rss":
|
|
1593
|
+
actions.setPanel({ type: name });
|
|
1594
|
+
return true;
|
|
1595
|
+
case "theme": {
|
|
1596
|
+
if (!args) {
|
|
1597
|
+
actions.setPanel({ type: "theme" });
|
|
1598
|
+
return true;
|
|
1599
|
+
}
|
|
1600
|
+
const preference = parseThemePreference(args);
|
|
1601
|
+
if (preference) {
|
|
1602
|
+
actions.setTheme(preference);
|
|
1603
|
+
actions.setPanel({ type: "notice", text: `\u5DF2\u5207\u6362\u5230 ${getThemeName(preference)}` });
|
|
1604
|
+
} else {
|
|
1605
|
+
actions.setPanel({ type: "notice", tone: "error", text: `\u672A\u77E5\u4E3B\u9898\uFF1A${args}\u3002\u53EF\u9009\uFF1A${themeOptions.map((option) => option.id).join("\u3001")}` });
|
|
1606
|
+
}
|
|
1607
|
+
return true;
|
|
1608
|
+
}
|
|
1609
|
+
case "clear":
|
|
1610
|
+
actions.clear();
|
|
1611
|
+
actions.setPanel(null);
|
|
1612
|
+
return true;
|
|
1613
|
+
default:
|
|
1614
|
+
return false;
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1538
1618
|
// packages/cli/src/agent.ts
|
|
1539
1619
|
import { useChatRuntime } from "@assistant-ui/ai-sdk";
|
|
1540
1620
|
import { useEffect as useEffect7, useMemo as useMemo3 } from "react";
|
|
@@ -1853,32 +1933,16 @@ function useTerminalSession(client, initial) {
|
|
|
1853
1933
|
const onCommand = async (name, args) => {
|
|
1854
1934
|
setPreviewTheme(void 0);
|
|
1855
1935
|
try {
|
|
1856
|
-
if (
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
setPanel({ type: name });
|
|
1864
|
-
break;
|
|
1865
|
-
case "theme": {
|
|
1866
|
-
const preference = parseThemePreference(args);
|
|
1867
|
-
if (!args) setPanel({ type: "theme" });
|
|
1868
|
-
else if (preference) onApplyTheme(preference);
|
|
1869
|
-
else
|
|
1870
|
-
notify(
|
|
1871
|
-
`\u672A\u77E5\u4E3B\u9898\uFF1A${args}\u3002\u53EF\u9009\uFF1A${themeOptions.map((option) => option.id).join("\u3001")}`,
|
|
1872
|
-
"error"
|
|
1873
|
-
);
|
|
1874
|
-
break;
|
|
1936
|
+
if (await runSharedCommand(name, args, {
|
|
1937
|
+
navigate: (path, prompt2) => navigate(name === "tags" && args ? resolveTagPath(args, index) : path, prompt2),
|
|
1938
|
+
setPanel,
|
|
1939
|
+
setTheme,
|
|
1940
|
+
clear: () => {
|
|
1941
|
+
stop();
|
|
1942
|
+
runtime.thread.reset();
|
|
1875
1943
|
}
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
break;
|
|
1879
|
-
case "search":
|
|
1880
|
-
await navigate(getSearchPath(args), `/search ${args}`.trim());
|
|
1881
|
-
break;
|
|
1944
|
+
})) return;
|
|
1945
|
+
switch (name) {
|
|
1882
1946
|
case "read":
|
|
1883
1947
|
await navigate(resolveReadPath(args, page), `/read ${args}`);
|
|
1884
1948
|
break;
|
|
@@ -1888,11 +1952,6 @@ function useTerminalSession(client, initial) {
|
|
|
1888
1952
|
case "open":
|
|
1889
1953
|
await openBrowser(resolveOpenTarget(args, page), client.site);
|
|
1890
1954
|
break;
|
|
1891
|
-
case "clear":
|
|
1892
|
-
stop();
|
|
1893
|
-
runtime.thread.reset();
|
|
1894
|
-
onClosePanel();
|
|
1895
|
-
break;
|
|
1896
1955
|
case "quit":
|
|
1897
1956
|
stop();
|
|
1898
1957
|
exit();
|
package/dist/index.js
CHANGED
|
@@ -16,14 +16,14 @@ try {
|
|
|
16
16
|
"miantiao.me \u2014 \u7EC8\u7AEF\u91CC\u7684\u9762\u6761\n\n\u7528\u6CD5\uFF1Anpx miantiao.me [--site <URL>]\n\n -h, --help \u67E5\u770B\u5E2E\u52A9\n -v, --version \u67E5\u770B\u7248\u672C\n --site <URL> \u5B98\u7F51\u5730\u5740\uFF0C\u4E5F\u53EF\u6307\u5411\u672C\u5730\u9884\u89C8\n\n\u8FDB\u5165\u540E\u8F93\u5165 /help \u67E5\u770B\u547D\u4EE4\uFF0CCtrl+C \u9000\u51FA\u3002\n\u9700\u8981 Node.js 22.14 \u6216\u66F4\u65B0\u7248\u672C\uFF0C\u4EE5\u53CA\u53EF\u4EA4\u4E92\u7684\u7EC8\u7AEF\u3002"
|
|
17
17
|
);
|
|
18
18
|
} else if (values.version) {
|
|
19
|
-
console.log("0.
|
|
19
|
+
console.log("0.3.0");
|
|
20
20
|
} else {
|
|
21
21
|
const site = new URL(values.site);
|
|
22
22
|
if (!["https:", "http:"].includes(site.protocol) || site.username || site.password)
|
|
23
23
|
throw new Error("--site \u5FC5\u987B\u4E3A\u4E0D\u542B\u51ED\u8BC1\u7684 HTTP \u6216 HTTPS \u5730\u5740\u3002");
|
|
24
24
|
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
25
25
|
throw new Error("\u8BF7\u5728\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\u8FD0\u884C npx miantiao.me\uFF1B\u4F7F\u7528 --help \u67E5\u770B\u5E2E\u52A9\u3002");
|
|
26
|
-
const { run } = await import("./app-
|
|
26
|
+
const { run } = await import("./app-VCJ3SOSQ.js");
|
|
27
27
|
await run(site.origin);
|
|
28
28
|
}
|
|
29
29
|
} catch (error) {
|