@chrysb/alphaclaw 0.9.0-beta.7 → 0.9.1-beta.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 (70) hide show
  1. package/bin/alphaclaw.js +26 -25
  2. package/lib/cli/git-runtime.js +97 -0
  3. package/lib/public/css/chat.css +0 -12
  4. package/lib/public/css/explorer.css +48 -0
  5. package/lib/public/css/shell.css +149 -0
  6. package/lib/public/css/tailwind.generated.css +1 -1
  7. package/lib/public/css/theme.css +265 -0
  8. package/lib/public/dist/app.bundle.js +2770 -2762
  9. package/lib/public/js/app.js +26 -14
  10. package/lib/public/js/components/agents-tab/create-channel-modal.js +259 -59
  11. package/lib/public/js/components/gateway.js +0 -286
  12. package/lib/public/js/components/general/index.js +0 -7
  13. package/lib/public/js/components/icons.js +26 -25
  14. package/lib/public/js/components/modal-shell.js +1 -1
  15. package/lib/public/js/components/models-tab/provider-auth-card.js +60 -49
  16. package/lib/public/js/components/models-tab/use-models.js +74 -9
  17. package/lib/public/js/components/models.js +52 -37
  18. package/lib/public/js/components/onboarding/use-welcome-codex.js +34 -24
  19. package/lib/public/js/components/onboarding/welcome-config.js +76 -10
  20. package/lib/public/js/components/onboarding/welcome-form-step.js +2 -7
  21. package/lib/public/js/components/onboarding/welcome-header.js +12 -14
  22. package/lib/public/js/components/onboarding/welcome-setup-step.js +3 -3
  23. package/lib/public/js/components/providers.js +53 -42
  24. package/lib/public/js/components/routes/chat-route.js +2 -9
  25. package/lib/public/js/components/routes/general-route.js +0 -6
  26. package/lib/public/js/components/routes/index.js +0 -1
  27. package/lib/public/js/components/routes/watchdog-route.js +0 -6
  28. package/lib/public/js/components/sidebar.js +21 -7
  29. package/lib/public/js/components/theme-toggle.js +113 -0
  30. package/lib/public/js/components/update-modal.js +174 -51
  31. package/lib/public/js/components/watchdog-tab/index.js +0 -6
  32. package/lib/public/js/components/welcome/index.js +0 -2
  33. package/lib/public/js/components/welcome/use-welcome.js +107 -36
  34. package/lib/public/js/hooks/use-app-shell-controller.js +16 -33
  35. package/lib/public/js/lib/api.js +0 -28
  36. package/lib/public/js/lib/app-navigation.js +0 -2
  37. package/lib/public/js/lib/channel-provider-availability.js +1 -2
  38. package/lib/public/js/lib/codex-oauth-window.js +22 -0
  39. package/lib/public/js/lib/model-catalog.js +31 -0
  40. package/lib/public/js/lib/storage-keys.js +1 -1
  41. package/lib/public/login.html +8 -4
  42. package/lib/public/setup.html +9 -0
  43. package/lib/scripts/git +110 -16
  44. package/lib/server/agents/channels.js +1 -4
  45. package/lib/server/alphaclaw-version.js +590 -132
  46. package/lib/server/constants.js +5 -0
  47. package/lib/server/db/webhooks/index.js +48 -8
  48. package/lib/server/exec-defaults-config.js +163 -0
  49. package/lib/server/gateway.js +1 -0
  50. package/lib/server/init/register-server-routes.js +0 -8
  51. package/lib/server/init/server-lifecycle.js +2 -0
  52. package/lib/server/model-catalog-cache.js +251 -0
  53. package/lib/server/onboarding/github.js +83 -2
  54. package/lib/server/onboarding/index.js +7 -0
  55. package/lib/server/routes/models.js +14 -23
  56. package/lib/server/routes/nodes.js +9 -23
  57. package/lib/server/routes/system.js +3 -16
  58. package/lib/server/routes/webhooks.js +12 -1
  59. package/lib/server/startup.js +8 -0
  60. package/lib/server/watchdog-notify.js +172 -55
  61. package/lib/server.js +17 -2
  62. package/lib/setup/core-prompts/AGENTS.md +12 -0
  63. package/lib/setup/core-prompts/TOOLS.md +12 -0
  64. package/package.json +2 -2
  65. package/patches/openclaw+2026.4.9.patch +13 -0
  66. package/lib/public/js/components/mcp-tab/index.js +0 -237
  67. package/lib/public/js/components/routes/mcp-route.js +0 -7
  68. package/lib/server/mcp-bridge.js +0 -158
  69. package/lib/server/routes/mcp.js +0 -292
  70. package/patches/openclaw+2026.3.28.patch +0 -13
@@ -23,7 +23,6 @@ export const kNavSections = [
23
23
  { id: "envars", label: "Envars" },
24
24
  { id: "webhooks", label: "Webhooks" },
25
25
  { id: "nodes", label: "Nodes" },
26
- { id: "mcp", label: "MCP" },
27
26
  ],
28
27
  },
29
28
  ];
@@ -42,6 +41,5 @@ export const getSelectedNavId = ({ isBrowseRoute = false, location = "" } = {})
42
41
  if (location.startsWith("/nodes")) return "nodes";
43
42
  if (location.startsWith("/envars")) return "envars";
44
43
  if (location.startsWith("/webhooks")) return "webhooks";
45
- if (location.startsWith("/mcp")) return "mcp";
46
44
  return kDefaultUiTab;
47
45
  };
@@ -1,4 +1,4 @@
1
- const kSingleAccountChannelProviders = new Set(["discord", "slack"]);
1
+ const kSingleAccountChannelProviders = new Set(["discord"]);
2
2
 
3
3
  const hasConfiguredAccounts = ({ configuredChannelMap, provider }) => {
4
4
  const channelEntry = configuredChannelMap instanceof Map
@@ -20,4 +20,3 @@ export const isChannelProviderDisabledForAdd = ({
20
20
  if (!isSingleAccountChannelProvider(provider)) return false;
21
21
  return hasConfiguredAccounts({ configuredChannelMap, provider });
22
22
  };
23
-
@@ -0,0 +1,22 @@
1
+ const kCodexAuthStartPath = "/auth/codex/start";
2
+ const kCodexAuthWindowName = "codex-auth";
3
+ const kCodexAuthPopupFeatures = "popup=yes,width=640,height=780";
4
+ const kCodexAuthCallbackMessageType = "callback-input";
5
+
6
+ export const openCodexAuthWindow = () => {
7
+ const popup = window.open(
8
+ kCodexAuthStartPath,
9
+ kCodexAuthWindowName,
10
+ kCodexAuthPopupFeatures,
11
+ );
12
+ if (!popup || popup.closed) {
13
+ window.location.href = kCodexAuthStartPath;
14
+ return null;
15
+ }
16
+ return popup;
17
+ };
18
+
19
+ export const isCodexAuthCallbackMessage = (value) =>
20
+ value?.codex === kCodexAuthCallbackMessageType &&
21
+ typeof value.input === "string" &&
22
+ value.input.trim().length > 0;
@@ -0,0 +1,31 @@
1
+ import { fetchModels } from "./api.js";
2
+ import { cachedFetch } from "./api-cache.js";
3
+ import { getFeaturedModels } from "./model-config.js";
4
+
5
+ export const kModelCatalogCacheKey = "/api/models";
6
+ export const kModelCatalogPollIntervalMs = 3000;
7
+
8
+ export const getModelCatalogModels = (payload) =>
9
+ Array.isArray(payload?.models) ? payload.models : [];
10
+
11
+ export const isModelCatalogRefreshing = (payload) =>
12
+ Boolean(payload?.refreshing);
13
+
14
+ export const preloadModelCatalog = ({
15
+ force = true,
16
+ maxAgeMs = 30000,
17
+ } = {}) =>
18
+ cachedFetch(kModelCatalogCacheKey, fetchModels, {
19
+ force,
20
+ maxAgeMs,
21
+ });
22
+
23
+ export const getInitialOnboardingModelKey = ({
24
+ catalog = [],
25
+ currentModelKey = "",
26
+ } = {}) => {
27
+ const normalizedCurrent = String(currentModelKey || "").trim();
28
+ if (normalizedCurrent) return normalizedCurrent;
29
+ const featuredModels = getFeaturedModels(catalog);
30
+ return String(featuredModels[0]?.key || catalog[0]?.key || "");
31
+ };
@@ -6,6 +6,7 @@
6
6
 
7
7
  // --- UI settings (single JSON blob containing sub-keys) ---
8
8
  export const kUiSettingsStorageKey = "alphaclaw.ui.settings";
9
+ export const kThemeStorageKey = "alphaclaw.ui.theme";
9
10
 
10
11
  // --- Browse / file viewer ---
11
12
  export const kFileViewerModeStorageKey = "alphaclaw.browse.viewerMode";
@@ -30,4 +31,3 @@ export const kAgentLastSessionKey = "alphaclaw.agent.lastSessionKey";
30
31
 
31
32
  // --- Chat ---
32
33
  export const kChatSessionDraftsStorageKey = "alphaclaw.chat.sessionDrafts";
33
-
@@ -11,6 +11,14 @@
11
11
  <link rel="icon" type="image/svg+xml" href="./img/logo.svg" />
12
12
  <link rel="stylesheet" href="./css/theme.css" />
13
13
  <link rel="stylesheet" href="./css/tailwind.generated.css" />
14
+ <script>
15
+ try {
16
+ var t = localStorage.getItem("alphaclaw.ui.theme");
17
+ if (t === "system") t = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
18
+ else if (t !== "dark" && t !== "light") t = "dark";
19
+ document.documentElement.dataset.theme = t;
20
+ } catch {}
21
+ </script>
14
22
  </head>
15
23
  <body class="min-h-screen flex items-center justify-center p-4">
16
24
  <div class="max-w-sm w-full relative z-10">
@@ -53,10 +61,6 @@
53
61
  </form>
54
62
  </div>
55
63
  <script>
56
- try {
57
- window.localStorage?.clear?.();
58
- } catch {}
59
-
60
64
  const formEl = document.getElementById("login-form");
61
65
  const passwordEl = document.getElementById("password");
62
66
  const submitButtonEl = document.getElementById("submit-btn");
@@ -16,6 +16,15 @@
16
16
  <link rel="stylesheet" href="./css/agents.css" />
17
17
  <link rel="stylesheet" href="./css/chat.css" />
18
18
  <link rel="stylesheet" href="./css/cron.css" />
19
+ <script>
20
+ // Apply saved theme before render to prevent flash.
21
+ try {
22
+ var t = localStorage.getItem("alphaclaw.ui.theme");
23
+ if (t === "system") t = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
24
+ else if (t !== "dark" && t !== "light") t = "dark";
25
+ document.documentElement.dataset.theme = t;
26
+ } catch {}
27
+ </script>
19
28
  </head>
20
29
  <body>
21
30
  <div id="app"></div>
package/lib/scripts/git CHANGED
@@ -2,36 +2,130 @@
2
2
  # Git auth shim -- injects GITHUB_TOKEN credentials for network operations
3
3
  # inside the configured OpenClaw repo so the agent can use plain git commands.
4
4
 
5
- REAL_GIT="@@REAL_GIT@@"
5
+ REAL_GIT_HINT="@@REAL_GIT@@"
6
6
  OPENCLAW_REPO_ROOT="@@OPENCLAW_REPO_ROOT@@"
7
7
  ASKPASS_PATH="/tmp/alphaclaw-git-askpass.sh"
8
8
 
9
- SUBCMD=""
10
- for arg in "$@"; do
11
- case "$arg" in
12
- -*) ;;
13
- *) SUBCMD="$arg"; break ;;
14
- esac
15
- done
9
+ same_path() {
10
+ local left_path right_path
11
+ left_path="$(readlink -f "$1" 2>/dev/null || printf '%s' "$1")"
12
+ right_path="$(readlink -f "$2" 2>/dev/null || printf '%s' "$2")"
13
+ [ "$left_path" = "$right_path" ]
14
+ }
16
15
 
17
- needs_auth() {
18
- case "$SUBCMD" in
19
- push|pull|fetch|clone|ls-remote) return 0 ;;
20
- *) return 1 ;;
21
- esac
16
+ resolve_real_git() {
17
+ local self_path candidate
18
+ self_path="$(readlink -f "$0" 2>/dev/null || printf '%s' "$0")"
19
+ for candidate in \
20
+ "${ALPHACLAW_REAL_GIT:-}" \
21
+ "$REAL_GIT_HINT" \
22
+ "/usr/bin/git" \
23
+ "/bin/git" \
24
+ "/usr/libexec/git-core/git" \
25
+ "/usr/local/bin/git.real"
26
+ do
27
+ [ -n "$candidate" ] || continue
28
+ [ -x "$candidate" ] || continue
29
+ same_path "$candidate" "$self_path" && continue
30
+ printf '%s\n' "$candidate"
31
+ return 0
32
+ done
33
+
34
+ if command -v which >/dev/null 2>&1; then
35
+ while IFS= read -r candidate; do
36
+ [ -n "$candidate" ] || continue
37
+ [ -x "$candidate" ] || continue
38
+ same_path "$candidate" "$self_path" && continue
39
+ printf '%s\n' "$candidate"
40
+ return 0
41
+ done <<EOF
42
+ $(which -a git 2>/dev/null || true)
43
+ EOF
44
+ fi
45
+
46
+ return 1
47
+ }
48
+
49
+ canonicalize_path() {
50
+ local target_path resolved_path
51
+ target_path="$1"
52
+ [ -n "$target_path" ] || return 1
53
+
54
+ if [ -d "$target_path" ]; then
55
+ resolved_path="$(cd "$target_path" 2>/dev/null && pwd -P)" || resolved_path=""
56
+ if [ -n "$resolved_path" ]; then
57
+ printf '%s\n' "$resolved_path"
58
+ return 0
59
+ fi
60
+ fi
61
+
62
+ resolved_path="$(readlink -f "$target_path" 2>/dev/null || true)"
63
+ if [ -n "$resolved_path" ]; then
64
+ printf '%s\n' "$resolved_path"
65
+ return 0
66
+ fi
67
+
68
+ printf '%s\n' "$target_path"
69
+ }
70
+
71
+ resolve_effective_pwd() {
72
+ local effective_pwd
73
+ effective_pwd="$(pwd)"
74
+
75
+ while [ "$#" -gt 0 ]; do
76
+ case "$1" in
77
+ -C)
78
+ shift
79
+ [ "$#" -gt 0 ] || break
80
+ case "$1" in
81
+ /*) effective_pwd="$1" ;;
82
+ *) effective_pwd="$effective_pwd/$1" ;;
83
+ esac
84
+ ;;
85
+ -c|--exec-path|--git-dir|--work-tree|--namespace|--config-env|--super-prefix|--list-cmds|--attr-source)
86
+ shift
87
+ [ "$#" -gt 0 ] || break
88
+ ;;
89
+ --exec-path=*|--git-dir=*|--work-tree=*|--namespace=*|--config-env=*|--super-prefix=*|--list-cmds=*|--attr-source=*)
90
+ ;;
91
+ --)
92
+ break
93
+ ;;
94
+ -*)
95
+ ;;
96
+ *)
97
+ break
98
+ ;;
99
+ esac
100
+ shift
101
+ done
102
+
103
+ canonicalize_path "$effective_pwd"
22
104
  }
23
105
 
24
106
  in_openclaw_root() {
107
+ local candidate_path resolved_repo_root resolved_candidate_path
108
+ candidate_path="$1"
25
109
  if [ -z "$OPENCLAW_REPO_ROOT" ]; then
26
110
  return 1
27
111
  fi
28
- case "$(pwd)" in
29
- "$OPENCLAW_REPO_ROOT"|"${OPENCLAW_REPO_ROOT}"/*) return 0 ;;
112
+ resolved_repo_root="$(canonicalize_path "$OPENCLAW_REPO_ROOT")"
113
+ resolved_candidate_path="$(canonicalize_path "$candidate_path")"
114
+ case "$resolved_candidate_path" in
115
+ "$resolved_repo_root"|"${resolved_repo_root}"/*) return 0 ;;
30
116
  *) return 1 ;;
31
117
  esac
32
118
  }
33
119
 
34
- if [ "${ALPHACLAW_GIT_NO_AUTH:-}" = "1" ] || [ -z "${GITHUB_TOKEN:-}" ] || ! needs_auth || ! in_openclaw_root; then
120
+ REAL_GIT="$(resolve_real_git || true)"
121
+ if [ -z "$REAL_GIT" ]; then
122
+ echo "alphaclaw git shim: real git binary not found" >&2
123
+ exit 127
124
+ fi
125
+
126
+ EFFECTIVE_PWD="$(resolve_effective_pwd "$@")"
127
+
128
+ if [ "${ALPHACLAW_GIT_NO_AUTH:-}" = "1" ] || [ -z "${GITHUB_TOKEN:-}" ] || ! in_openclaw_root "$EFFECTIVE_PWD"; then
35
129
  exec "$REAL_GIT" "$@"
36
130
  fi
37
131
 
@@ -143,10 +143,7 @@ const createChannelsDomain = ({
143
143
  `Channel account "${provider}/${accountId}" already exists`,
144
144
  );
145
145
  }
146
- if (
147
- (provider === "discord" || provider === "slack") &&
148
- Object.keys(existingAccounts).length > 0
149
- ) {
146
+ if (provider === "discord" && Object.keys(existingAccounts).length > 0) {
150
147
  throw new Error(
151
148
  `${kChannelLabels[provider] || "This provider"} supports a single channel account`,
152
149
  );