@co0ontty/wand 4.63.0 → 4.64.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.
Files changed (83) hide show
  1. package/dist/build-info.d.ts +18 -0
  2. package/dist/build-info.js +13 -0
  3. package/dist/build-info.json +3 -3
  4. package/dist/config.js +6 -11
  5. package/dist/env-utils.d.ts +5 -0
  6. package/dist/env-utils.js +4 -0
  7. package/dist/git-quick-commit.js +7 -11
  8. package/dist/ios-ota.js +8 -29
  9. package/dist/layout-tree.d.ts +6 -0
  10. package/dist/layout-tree.js +9 -0
  11. package/dist/missions.js +2 -2
  12. package/dist/models.js +2 -5
  13. package/dist/path-repair.js +2 -1
  14. package/dist/process-manager.js +10 -20
  15. package/dist/provider-cli-updater.js +3 -6
  16. package/dist/pty-shell-launch.js +3 -5
  17. package/dist/server-app-connect.js +11 -46
  18. package/dist/server-github-routes.js +12 -11
  19. package/dist/server-local-preview-routes.js +6 -1
  20. package/dist/server-request.d.ts +4 -2
  21. package/dist/server-request.js +25 -4
  22. package/dist/server-session-routes.js +14 -78
  23. package/dist/server-settings-routes.d.ts +2 -6
  24. package/dist/server-settings-routes.js +3 -8
  25. package/dist/server-task-routes.d.ts +9 -6
  26. package/dist/server-task-routes.js +50 -43
  27. package/dist/server-update-routes.d.ts +2 -5
  28. package/dist/server-update-routes.js +42 -9
  29. package/dist/server-workspace-routes.js +4 -12
  30. package/dist/server.js +33 -99
  31. package/dist/session-ai-context.js +6 -38
  32. package/dist/session-provider.d.ts +16 -0
  33. package/dist/session-provider.js +49 -0
  34. package/dist/session-registry.d.ts +10 -0
  35. package/dist/session-registry.js +41 -14
  36. package/dist/session-topic.js +3 -11
  37. package/dist/shell-quote.d.ts +9 -0
  38. package/dist/shell-quote.js +13 -0
  39. package/dist/signal-utils.d.ts +10 -0
  40. package/dist/signal-utils.js +38 -0
  41. package/dist/storage.js +17 -55
  42. package/dist/structured-client-protocol.js +4 -8
  43. package/dist/structured-codex-protocol.js +1 -6
  44. package/dist/structured-content.d.ts +2 -0
  45. package/dist/structured-content.js +6 -0
  46. package/dist/structured-exec-host.d.ts +0 -2
  47. package/dist/structured-exec-host.js +2 -11
  48. package/dist/structured-exec-pump.js +2 -12
  49. package/dist/structured-grok-adapter.js +1 -5
  50. package/dist/structured-opencode-adapter.js +1 -5
  51. package/dist/structured-pi-adapter.js +9 -11
  52. package/dist/structured-provider-common.d.ts +11 -3
  53. package/dist/structured-provider-common.js +16 -23
  54. package/dist/structured-qoder-adapter.js +3 -8
  55. package/dist/structured-session-manager.js +6 -17
  56. package/dist/task-title.js +4 -12
  57. package/dist/task-types.d.ts +23 -1
  58. package/dist/task-types.js +26 -0
  59. package/dist/terminal-daemon-protocol.d.ts +0 -6
  60. package/dist/terminal-daemon-server.js +1 -9
  61. package/dist/text-utils.d.ts +7 -0
  62. package/dist/text-utils.js +15 -0
  63. package/dist/tui/attach.js +17 -93
  64. package/dist/tui/commands.d.ts +2 -0
  65. package/dist/tui/commands.js +3 -2
  66. package/dist/tui/index.js +28 -115
  67. package/dist/tui/runtime-utils.d.ts +7 -0
  68. package/dist/tui/runtime-utils.js +33 -0
  69. package/dist/tui/service-actions.d.ts +31 -0
  70. package/dist/tui/service-actions.js +86 -0
  71. package/dist/tui/snapshot.js +1 -8
  72. package/dist/update-helper.js +6 -35
  73. package/dist/web-ui/content/scripts.js +397 -497
  74. package/dist/web-ui/content/styles.css +1 -1
  75. package/dist/web-ui/content/tailwind.css +7210 -0
  76. package/dist/web-ui/embedded-assets.js +2 -2
  77. package/dist/web-ui/index.js +3 -3
  78. package/dist/web-ui/provider-identity.d.ts +4 -0
  79. package/dist/web-ui/provider-identity.js +9 -0
  80. package/dist/web-ui/styles.js +24 -7
  81. package/dist/workspace-binding.d.ts +2 -0
  82. package/dist/workspace-binding.js +4 -3
  83. package/package.json +9 -12
@@ -21,10 +21,10 @@ export function renderApp(configPath) {
21
21
  <meta charset="utf-8" />
22
22
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover, interactive-widget=resizes-content" />
23
23
  <title>Wand Console</title>
24
- <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='16' fill='%2313110f'/%3E%3Ctext x='32' y='44' text-anchor='middle' font-size='40' font-family='Arial,sans-serif' font-weight='700' fill='%23f5f3ee'%3EW%3C/text%3E%3C/svg%3E" />
24
+ <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='18' fill='%2317120f'/%3E%3Cpath d='M13 21l9 24 10-15 10 15 9-24' fill='none' stroke='%23c5653d' stroke-width='6.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E" />
25
25
  <meta name="description" content="Local CLI Console for Vibe Coding - Manage terminal sessions from your browser" />
26
- <meta name="theme-color" content="#f5f3ee" media="(prefers-color-scheme: light)" />
27
- <meta name="theme-color" content="#13110f" media="(prefers-color-scheme: dark)" />
26
+ <meta name="theme-color" content="#f1eadf" media="(prefers-color-scheme: light)" />
27
+ <meta name="theme-color" content="#17120f" media="(prefers-color-scheme: dark)" />
28
28
  <meta name="format-detection" content="telephone=no" />
29
29
  <meta name="msapplication-tap-highlight" content="no" />
30
30
  <link rel="stylesheet" href="${xtermCssHref}" />
@@ -7,6 +7,10 @@ export declare function normalizeProviderId(value: unknown): ProviderId | null;
7
7
  * directory names must not be allowed to impersonate a different provider.
8
8
  */
9
9
  export declare function inferProviderIdFromCommand(value: unknown): ProviderId | null;
10
+ /** provider 对应的 CLI 可执行文件名(Qoder 的 CLI 叫 qodercli)。 */
11
+ export declare function providerCliCommand(provider: string): string;
12
+ /** 严格判断:只接受 6 个 provider 字面量,不做别名 / 大小写归一。 */
13
+ export declare function isProviderId(value: unknown): value is ProviderId;
10
14
  export declare function providerDisplayName(value: unknown): string;
11
15
  export declare const CLAUDE_BRAND_COLOR = "#D97757";
12
16
  export declare const CLAUDE_LOGO_PATH = "m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z";
@@ -1,4 +1,5 @@
1
1
  export const PROVIDER_IDS = ["claude", "codex", "opencode", "grok", "qoder", "pi"];
2
+ const PROVIDER_ID_SET = new Set(PROVIDER_IDS);
2
3
  const PROVIDER_LABELS = {
3
4
  claude: "Claude",
4
5
  codex: "Codex",
@@ -52,6 +53,14 @@ export function inferProviderIdFromCommand(value) {
52
53
  const executable = executablePath.split(/[\\/]/).pop()?.replace(/\.(?:cmd|exe)$/i, "") ?? "";
53
54
  return normalizeProviderId(executable);
54
55
  }
56
+ /** provider 对应的 CLI 可执行文件名(Qoder 的 CLI 叫 qodercli)。 */
57
+ export function providerCliCommand(provider) {
58
+ return provider === "qoder" ? "qodercli" : provider;
59
+ }
60
+ /** 严格判断:只接受 6 个 provider 字面量,不做别名 / 大小写归一。 */
61
+ export function isProviderId(value) {
62
+ return typeof value === "string" && PROVIDER_ID_SET.has(value);
63
+ }
55
64
  export function providerDisplayName(value) {
56
65
  if (typeof value === "string" && value.trim().toLowerCase() === "terminal")
57
66
  return "终端";
@@ -3,19 +3,36 @@ import * as path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { EMBEDDED_WEB_ASSETS } from "./embedded-assets.js";
5
5
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
- // 用 mtime 做缓存键,磁盘上 CSS 一变(npm run build / 手工 edit dist/)下次请求
6
+ // 顺序即层叠顺序:Tailwind/Appica 编译产物在前,手写 styles.css 在后。
7
+ //
8
+ // 两个原因决定这个顺序不能反过来:
9
+ //
10
+ // 1. Tailwind 的 @layer 规则永远输给无层规则,所以 styles.css 里的手写规则
11
+ // 仍然稳压 Utilities 一层(两个文件里 `*` 重置的分工见
12
+ // src/web-ui/css/appica.css 顶部说明)。这一条与先后无关。
13
+ // 2. Appica 在自己的无层 `:root` 里也声明了一批与 Wand 同名的 token
14
+ // (--success / --warning / --info / --border-strong / --radius-md /
15
+ // --shadow-sm …)。无层对无层只能靠先后裁决,styles.css 必须排在后面,
16
+ // 否则 Appica 的中性灰会悄无声息地覆盖掉整套暖色调。
17
+ const CSS_FILES = ["tailwind.css", "styles.css"];
18
+ // 用 mtime+size 做缓存键,磁盘上 CSS 一变(npm run build / 手工 edit dist/)下次请求
7
19
  // 就会自动 re-read。否则进程启动时缓存的 CSS 会粘住整个生命周期,UI 改动看不到效果,
8
20
  // 必须重启 wand 才能生效——开发 / 修 UI 的时候这点尤其难受。
9
21
  // 同步 stat 的成本:本地 fs,~几十微秒,相对一次 HTML 渲染可忽略。
10
22
  let _cssCache = EMBEDDED_WEB_ASSETS.stylesCss;
11
- let _cssCacheMtimeMs = 0;
23
+ let _cssCacheKey = "";
24
+ function cssCacheKey() {
25
+ return CSS_FILES.map((name) => {
26
+ const stat = fs.statSync(path.join(__dirname, "content", name));
27
+ return `${name}:${stat.mtimeMs}:${stat.size}`;
28
+ }).join("|");
29
+ }
12
30
  export function getCSSStyles() {
13
- const cssPath = path.join(__dirname, "content", "styles.css");
14
31
  try {
15
- const stat = fs.statSync(cssPath);
16
- if (_cssCache === null || stat.mtimeMs !== _cssCacheMtimeMs) {
17
- _cssCache = fs.readFileSync(cssPath, "utf-8");
18
- _cssCacheMtimeMs = stat.mtimeMs;
32
+ const key = cssCacheKey();
33
+ if (key !== _cssCacheKey) {
34
+ _cssCache = CSS_FILES.map((name) => fs.readFileSync(path.join(__dirname, "content", name), "utf-8")).join("\n");
35
+ _cssCacheKey = key;
19
36
  }
20
37
  }
21
38
  catch {
@@ -16,6 +16,8 @@ export declare function ensureWorkspaceForCwd(storage: WandStorage, cwd: string,
16
16
  name?: string;
17
17
  defaultProvider?: WorkspaceDefaultProvider;
18
18
  }): Workspace;
19
+ /** 全局工作空间既可能标记 `kind`,也可能是旧的固定 id。 */
20
+ export declare function isGlobalWorkspace(workspace: Pick<Workspace, "kind" | "id">): boolean;
19
21
  /**
20
22
  * 「工作区名称」和「项目名」是同一个概念:用户在任意一端改名,两端都要写。
21
23
  * name 为空表示恢复目录名(清掉自定义名)。返回最终生效的显示名。
@@ -61,7 +61,8 @@ export function ensureWorkspaceForCwd(storage, cwd, options = {}) {
61
61
  defaultProvider: options.defaultProvider,
62
62
  });
63
63
  }
64
- function isGlobalWorkspaceRecord(workspace) {
64
+ /** 全局工作空间既可能标记 `kind`,也可能是旧的固定 id。 */
65
+ export function isGlobalWorkspace(workspace) {
65
66
  return workspace.kind === "global" || workspace.id === GLOBAL_WORKSPACE_ID;
66
67
  }
67
68
  /**
@@ -76,7 +77,7 @@ export function renameWorkspaceDirectory(storage, cwd, name) {
76
77
  const resolved = trimmed || path.basename(normalized) || normalized;
77
78
  storage.setSessionDirectoryName(normalized, trimmed || null);
78
79
  for (const workspace of storage.listWorkspaces()) {
79
- if (isGlobalWorkspaceRecord(workspace))
80
+ if (isGlobalWorkspace(workspace))
80
81
  continue;
81
82
  if (normalizeProjectCwd(workspace.cwd) !== normalized)
82
83
  continue;
@@ -88,7 +89,7 @@ export function renameWorkspaceDirectory(storage, cwd, name) {
88
89
  }
89
90
  /** 项目(workspaces.name)被直接改名后,把目录自定义名同步成同一个名字。 */
90
91
  export function syncDirectoryNameForWorkspace(storage, workspace) {
91
- if (isGlobalWorkspaceRecord(workspace))
92
+ if (isGlobalWorkspace(workspace))
92
93
  return;
93
94
  const normalized = normalizeProjectCwd(workspace.cwd);
94
95
  const name = workspace.name.trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@co0ontty/wand",
3
- "version": "4.63.0",
3
+ "version": "4.64.0",
4
4
  "description": "A web console for Claude Code, Codex, OpenCode, and other local CLI tools.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,12 +18,13 @@
18
18
  "preferGlobal": true,
19
19
  "scripts": {
20
20
  "generate:web-assets": "node scripts/generate-web-assets.js",
21
- "build": "rm -rf dist && node scripts/bundle-xterm.js && node scripts/bundle-qrcode.js && node scripts/bundle-browser.js && npm run generate:web-assets && tsc -p tsconfig.json && npm run build:copy-content && node scripts/stamp-build-info.js && node scripts/fix-dist-permissions.js",
21
+ "build": "rm -rf dist && node scripts/bundle-tailwind.js && node scripts/bundle-xterm.js && node scripts/bundle-qrcode.js && node scripts/bundle-browser.js && npm run generate:web-assets && tsc -p tsconfig.json && npm run build:copy-content && node scripts/stamp-build-info.js && node scripts/fix-dist-permissions.js",
22
22
  "build:copy-content": "cp -r src/web-ui/content dist/web-ui/ && node scripts/minify-dist-content.js",
23
- "dev": "node scripts/bundle-xterm.js && node scripts/bundle-browser.js --development && npm run generate:web-assets && tsx src/cli.ts web",
24
- "check": "node scripts/bundle-xterm.js && node scripts/bundle-browser.js && npm run generate:web-assets && tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.browser.json && tsc --noEmit -p tsconfig.react.json",
23
+ "dev": "node scripts/bundle-tailwind.js && node scripts/bundle-xterm.js && node scripts/bundle-browser.js --development && npm run generate:web-assets && tsx src/cli.ts web",
24
+ "check": "node scripts/bundle-tailwind.js && node scripts/bundle-xterm.js && node scripts/bundle-browser.js && npm run generate:web-assets && tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.browser.json && tsc --noEmit -p tsconfig.react.json",
25
25
  "test": "node --test --import tsx tests/*.test.ts",
26
- "prepublishOnly": "VER=${WAND_PUBLISH_VERSION:-$(git tag --sort=-v:refname --list 'v*' | head -1)} && VER=${VER#v} && npm version \"$VER\" --no-git-tag-version --allow-same-version && npm run build"
26
+ "prepublishOnly": "VER=${WAND_PUBLISH_VERSION:-$(git tag --sort=-v:refname --list 'v*' | head -1)} && VER=${VER#v} && npm version \"$VER\" --no-git-tag-version --allow-same-version && npm run build",
27
+ "bundle:tailwind": "node scripts/bundle-tailwind.js"
27
28
  },
28
29
  "keywords": [
29
30
  "cli",
@@ -38,12 +39,7 @@
38
39
  "dependencies": {
39
40
  "@anthropic-ai/claude-agent-sdk": "^0.2.138",
40
41
  "@anthropic-ai/sdk": "^0.81.0",
41
- "@radix-ui/react-dialog": "^1.1.19",
42
- "@radix-ui/react-popover": "^1.1.19",
43
- "@radix-ui/react-select": "^2.3.3",
44
- "@radix-ui/react-switch": "^1.3.3",
45
- "@radix-ui/react-tabs": "^1.1.17",
46
- "@radix-ui/react-toast": "^1.2.19",
42
+ "@appica/ui-react": "^1.1.0",
47
43
  "@xterm/addon-fit": "^0.11.0",
48
44
  "@xterm/addon-serialize": "^0.14.0",
49
45
  "@xterm/addon-unicode11": "^0.9.0",
@@ -56,10 +52,10 @@
56
52
  "node-pty": "^1.1.0",
57
53
  "react": "^19.2.7",
58
54
  "react-dom": "^19.2.7",
59
- "smol-toml": "^1.8.0",
60
55
  "ws": "^8.19.0"
61
56
  },
62
57
  "devDependencies": {
58
+ "@tailwindcss/cli": "^4.3.3",
63
59
  "@types/compression": "^1.8.1",
64
60
  "@types/express": "^4.17.21",
65
61
  "@types/multer": "^2.1.0",
@@ -69,6 +65,7 @@
69
65
  "@types/ws": "^8.18.1",
70
66
  "esbuild": "^0.28.0",
71
67
  "qrcode": "^1.5.4",
68
+ "tailwindcss": "^4.3.3",
72
69
  "tsx": "^4.19.3",
73
70
  "typescript": "^5.8.2"
74
71
  }