mistagent 0.1.21 → 0.1.23

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.
@@ -1,7 +1,20 @@
1
- import type { AuthStatus, LoginResponse, UserInfo } from '../types/api.js';
1
+ import type { AuthStatus, UserInfo } from '../types/api.js';
2
2
  export declare const authApi: {
3
3
  getStatus(): Promise<AuthStatus>;
4
- login(username: string, password: string): Promise<LoginResponse>;
5
4
  getMe(): Promise<UserInfo>;
6
5
  };
6
+ /** Supabase 直连登录 — POST /auth/v1/token?grant_type=password */
7
+ export interface SupabaseLoginResult {
8
+ access_token: string;
9
+ refresh_token: string;
10
+ user: {
11
+ id: string;
12
+ email: string;
13
+ user_metadata: {
14
+ username?: string;
15
+ display_name?: string;
16
+ };
17
+ };
18
+ }
19
+ export declare function supabaseLogin(supabaseUrl: string, anonKey: string, email: string, password: string): Promise<SupabaseLoginResult>;
7
20
  //# sourceMappingURL=auth.d.ts.map
@@ -3,14 +3,24 @@ export const authApi = {
3
3
  getStatus() {
4
4
  return getClient().get('/api/v1/auth/status');
5
5
  },
6
- login(username, password) {
7
- return getClient().post('/api/v1/auth/login', {
8
- username,
9
- password,
10
- });
11
- },
12
6
  getMe() {
13
7
  return getClient().get('/api/v1/auth/me');
14
8
  },
15
9
  };
10
+ export async function supabaseLogin(supabaseUrl, anonKey, email, password) {
11
+ const res = await fetch(`${supabaseUrl}/auth/v1/token?grant_type=password`, {
12
+ method: 'POST',
13
+ headers: {
14
+ 'Content-Type': 'application/json',
15
+ 'apikey': anonKey,
16
+ },
17
+ body: JSON.stringify({ email, password }),
18
+ });
19
+ if (!res.ok) {
20
+ const body = await res.json().catch(() => null);
21
+ const msg = body?.error_description || body?.msg || 'Login failed';
22
+ throw new Error(msg);
23
+ }
24
+ return res.json();
25
+ }
16
26
  //# sourceMappingURL=auth.js.map
@@ -1,4 +1,5 @@
1
1
  // Base HTTP client with JWT auth support
2
+ import { VERSION } from '../utils/constants.js';
2
3
  export class ApiError extends Error {
3
4
  status;
4
5
  body;
@@ -9,6 +10,14 @@ export class ApiError extends Error {
9
10
  this.name = 'ApiError';
10
11
  }
11
12
  }
13
+ // Client-identity headers attached to every request so the backend can
14
+ // distinguish CLI sessions from the web UI and tailor the system prompt
15
+ // (e.g. expose bash_shell_run, file tunnel, etc.).
16
+ const CLIENT_HEADERS = Object.freeze({
17
+ 'X-Mist-Client': 'cli',
18
+ 'X-Mist-Client-Version': VERSION,
19
+ 'User-Agent': `mistagent-cli/${VERSION}`,
20
+ });
12
21
  export class ApiClient {
13
22
  baseUrl;
14
23
  token = null;
@@ -22,7 +31,7 @@ export class ApiClient {
22
31
  return this.token;
23
32
  }
24
33
  authHeaders() {
25
- const headers = {};
34
+ const headers = { ...CLIENT_HEADERS };
26
35
  if (this.token) {
27
36
  headers['Authorization'] = `Bearer ${this.token}`;
28
37
  }
@@ -89,11 +98,9 @@ export class ApiClient {
89
98
  for (const [k, v] of Object.entries(params)) {
90
99
  url.searchParams.set(k, v);
91
100
  }
92
- // SSE auth via query param
93
- if (this.token) {
94
- url.searchParams.set('token', this.token);
95
- }
96
- const res = await fetch(url.toString());
101
+ const res = await fetch(url.toString(), {
102
+ headers: this.authHeaders(),
103
+ });
97
104
  if (!res.ok) {
98
105
  throw new ApiError(res.status, await res.text());
99
106
  }
@@ -105,9 +112,6 @@ export class ApiClient {
105
112
  // SSE streaming via POST - for large payloads (e.g. messages with file contents)
106
113
  async streamPost(path, body) {
107
114
  const url = new URL(path, this.baseUrl);
108
- if (this.token) {
109
- url.searchParams.set('token', this.token);
110
- }
111
115
  const res = await fetch(url.toString(), {
112
116
  method: 'POST',
113
117
  headers: {
@@ -2,6 +2,8 @@ export interface QuotaBalance {
2
2
  usd_balance: number;
3
3
  usd_total_granted: number;
4
4
  usd_total_consumed: number;
5
+ }
6
+ export interface UsageSummary {
5
7
  usage_today_tokens: number;
6
8
  usage_this_month_tokens: number;
7
9
  cost_today_usd: number;
@@ -9,5 +11,6 @@ export interface QuotaBalance {
9
11
  }
10
12
  export declare const quotaApi: {
11
13
  balance(): Promise<QuotaBalance>;
14
+ usageSummary(): Promise<UsageSummary>;
12
15
  };
13
16
  //# sourceMappingURL=quota.d.ts.map
@@ -3,5 +3,8 @@ export const quotaApi = {
3
3
  balance() {
4
4
  return getClient().get('/api/v1/quota/balance');
5
5
  },
6
+ usageSummary() {
7
+ return getClient().get('/api/v1/quota/usage/summary');
8
+ },
6
9
  };
7
10
  //# sourceMappingURL=quota.js.map
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  interface LoginPromptProps {
3
- onLogin: (username: string, password: string) => Promise<void>;
3
+ onLogin: (email: string, password: string) => Promise<void>;
4
4
  error?: string | null;
5
5
  }
6
6
  export declare const LoginPrompt: React.FC<LoginPromptProps>;
@@ -46,8 +46,8 @@ const SimpleInput = ({ value, onChange, onSubmit, mask }) => {
46
46
  // ── LoginPrompt ──────────────────────────────────────────
47
47
  export const LoginPrompt = ({ onLogin, error, }) => {
48
48
  const { subscribe, unsubscribe } = useKeypressContext();
49
- const [step, setStep] = useState('username');
50
- const [username, setUsername] = useState('');
49
+ const [step, setStep] = useState('email');
50
+ const [email, setEmail] = useState('');
51
51
  const [password, setPassword] = useState('');
52
52
  const [isLoading, setIsLoading] = useState(false);
53
53
  const [ctrlCPressedOnce, setCtrlCPressedOnce] = useState(false);
@@ -72,9 +72,9 @@ export const LoginPrompt = ({ onLogin, error, }) => {
72
72
  subscribe(ctrlCHandler, KeypressPriority.Normal);
73
73
  return () => unsubscribe(ctrlCHandler);
74
74
  }, [ctrlCHandler, subscribe, unsubscribe]);
75
- const handleUsernameSubmit = useCallback((val) => {
75
+ const handleEmailSubmit = useCallback((val) => {
76
76
  if (val.trim()) {
77
- setUsername(val.trim());
77
+ setEmail(val.trim());
78
78
  setStep('password');
79
79
  }
80
80
  }, []);
@@ -83,19 +83,19 @@ export const LoginPrompt = ({ onLogin, error, }) => {
83
83
  setPassword(val.trim());
84
84
  setIsLoading(true);
85
85
  try {
86
- await onLogin(username, val.trim());
86
+ await onLogin(email, val.trim());
87
87
  }
88
- catch {
88
+ finally {
89
89
  setIsLoading(false);
90
- setStep('username');
91
- setUsername('');
90
+ setStep('email');
91
+ setEmail('');
92
92
  setPassword('');
93
93
  }
94
94
  }
95
- }, [onLogin, username]);
95
+ }, [onLogin, email]);
96
96
  return (_jsxs(Box, { flexDirection: "column", alignItems: "center", padding: 1, children: [_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [BANNER_LINES.map((line, i) => {
97
97
  const gradient = getBannerGradient();
98
98
  return (_jsx(Text, { color: gradient[i] ?? gradient[0], children: line }, i));
99
- }), _jsx(Text, { color: palette.textMuted, children: BANNER_SUBTITLE }), _jsx(Text, { color: palette.textDim, children: ' v' + VERSION })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: error ? palette.error : palette.border, paddingX: 3, paddingY: 1, width: 48, children: [error && (_jsx(Box, { marginBottom: 1, justifyContent: "center", children: _jsxs(Text, { color: palette.error, children: ['✗ ', error] }) })), isLoading ? (_jsx(Box, { justifyContent: "center", paddingY: 1, children: _jsx(Spinner, { label: "Authenticating..." }) })) : step === 'username' ? (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: palette.primary, bold: true, children: ' ❯ Username ' }), _jsx(SimpleInput, { value: username, onChange: setUsername, onSubmit: handleUsernameSubmit })] }), _jsx(Box, { children: _jsx(Text, { color: palette.textDim, children: ' ○ Password' }) })] })) : (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: palette.success, children: ' ✓ ' }), _jsx(Text, { color: palette.textMuted, children: 'Username ' }), _jsx(Text, { children: username })] }), _jsxs(Box, { children: [_jsx(Text, { color: palette.primary, bold: true, children: ' ❯ Password ' }), _jsx(SimpleInput, { value: password, onChange: setPassword, onSubmit: handlePasswordSubmit, mask: "\u2022" })] })] })), _jsx(Box, { justifyContent: "center", marginTop: 1, children: ctrlCPressedOnce ? (_jsx(Text, { color: palette.warning, bold: true, children: "Press Ctrl-C again to exit" })) : (_jsxs(Text, { color: palette.textDim, dimColor: true, children: ["Press ", _jsx(Text, { color: palette.textMuted, children: "Enter" }), " to continue"] })) })] })] }));
99
+ }), _jsx(Text, { color: palette.textMuted, children: BANNER_SUBTITLE }), _jsx(Text, { color: palette.textDim, children: ' v' + VERSION })] }), _jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: error ? palette.error : palette.border, paddingX: 3, paddingY: 1, width: 48, children: [error && (_jsx(Box, { marginBottom: 1, justifyContent: "center", children: _jsxs(Text, { color: palette.error, children: ['✗ ', error] }) })), isLoading ? (_jsx(Box, { justifyContent: "center", paddingY: 1, children: _jsx(Spinner, { label: "Authenticating..." }) })) : step === 'email' ? (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: palette.primary, bold: true, children: ' ❯ Email ' }), _jsx(SimpleInput, { value: email, onChange: setEmail, onSubmit: handleEmailSubmit })] }), _jsx(Box, { children: _jsx(Text, { color: palette.textDim, children: ' ○ Password' }) })] })) : (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: palette.success, children: ' ✓ ' }), _jsx(Text, { color: palette.textMuted, children: 'Email ' }), _jsx(Text, { children: email })] }), _jsxs(Box, { children: [_jsx(Text, { color: palette.primary, bold: true, children: ' ❯ Password ' }), _jsx(SimpleInput, { value: password, onChange: setPassword, onSubmit: handlePasswordSubmit, mask: "\u2022" })] })] })), _jsx(Box, { justifyContent: "center", marginTop: 1, children: ctrlCPressedOnce ? (_jsx(Text, { color: palette.warning, bold: true, children: "Press Ctrl-C again to exit" })) : (_jsxs(Text, { color: palette.textDim, dimColor: true, children: ["Press ", _jsx(Text, { color: palette.textMuted, children: "Enter" }), " to continue"] })) })] })] }));
100
100
  };
101
101
  //# sourceMappingURL=LoginPrompt.js.map
@@ -109,7 +109,7 @@ export function useSlashCommand() {
109
109
  if (trimmed === '/usage') {
110
110
  dispatch({ type: 'SET_BUSY', busy: true });
111
111
  try {
112
- const b = await quotaApi.balance();
112
+ const [b, u] = await Promise.all([quotaApi.balance(), quotaApi.usageSummary()]);
113
113
  const fmt = (v) => `$${v.toFixed(4)}`;
114
114
  const fmtTokens = (v) => v >= 1_000_000
115
115
  ? `${(v / 1_000_000).toFixed(1)}M`
@@ -123,12 +123,12 @@ export function useSlashCommand() {
123
123
  ` 总消耗: ${fmt(b.usd_total_consumed)}`,
124
124
  ``,
125
125
  `**今日用量**`,
126
- ` Tokens: ${fmtTokens(b.usage_today_tokens)}`,
127
- ` 费用: ${fmt(b.cost_today_usd)}`,
126
+ ` Tokens: ${fmtTokens(u.usage_today_tokens)}`,
127
+ ` 费用: ${fmt(u.cost_today_usd)}`,
128
128
  ``,
129
129
  `**本月用量**`,
130
- ` Tokens: ${fmtTokens(b.usage_this_month_tokens)}`,
131
- ` 费用: ${fmt(b.cost_this_month_usd)}`,
130
+ ` Tokens: ${fmtTokens(u.usage_this_month_tokens)}`,
131
+ ` 费用: ${fmt(u.cost_this_month_usd)}`,
132
132
  ];
133
133
  dispatch({
134
134
  type: 'ADD_ITEM',
package/dist/src/main.js CHANGED
@@ -3,7 +3,7 @@ import { render } from 'ink';
3
3
  import yargs from 'yargs';
4
4
  import { hideBin } from 'yargs/helpers';
5
5
  import { initClient } from './api/client.js';
6
- import { authApi } from './api/auth.js';
6
+ import { authApi, supabaseLogin } from './api/auth.js';
7
7
  import { modelsApi } from './api/models.js';
8
8
  import { toolsApi } from './api/tools.js';
9
9
  import { skillsApi } from './api/skills.js';
@@ -211,16 +211,24 @@ export async function main() {
211
211
  terminalHeight: process.stdout.rows || 24,
212
212
  });
213
213
  const renderApp = (overrides = {}) => (_jsx(App, { serverUrl: serverUrl, token: overrides.token ?? token, username: overrides.username ?? username, authEnabled: authStatus.auth_enabled, version: healthData?.version ?? VERSION, healthData: healthData, availableCommands: commands, availableTools: tools, initialModels: models, initialCurrentModel: currentModel, initialSessions: initialSessions, initialTheme: initialTheme, onLogin: handleLogin, onLogout: handleLogout, loginError: overrides.loginError ?? loginError, isAuthenticated: overrides.isAuthenticated ?? isAuthenticated, ...getTerminalSize() }));
214
- const handleLogin = async (user, pass) => {
214
+ const handleLogin = async (email, pass) => {
215
+ const sbUrl = authStatus.supabase_url;
216
+ const sbKey = authStatus.supabase_anon_key;
217
+ if (!sbUrl || !sbKey) {
218
+ loginError = 'Supabase not configured on server';
219
+ rerender(renderApp({ token: null, username: null, isAuthenticated: false, loginError }));
220
+ return;
221
+ }
215
222
  try {
216
- const res = await authApi.login(user, pass);
223
+ const res = await supabaseLogin(sbUrl, sbKey, email, pass);
217
224
  client.setToken(res.access_token);
218
225
  saveToken(res.access_token);
219
226
  if (res.refresh_token) {
220
227
  saveRefreshToken(res.refresh_token);
221
228
  }
222
229
  token = res.access_token;
223
- username = res.user.username;
230
+ const meta = res.user?.user_metadata ?? {};
231
+ username = meta.display_name || meta.username || email;
224
232
  isAuthenticated = true;
225
233
  loginError = null;
226
234
  startTokenRefresh();
@@ -3,6 +3,7 @@ import { loadParser, loadLanguage } from '../tree-sitter/parser-loader.js';
3
3
  import { LANGUAGE_QUERIES } from './tree-sitter-queries.js';
4
4
  import { generateId } from '../../lib/utils.js';
5
5
  import { getLanguageFromFilename, yieldToEventLoop } from './utils.js';
6
+ import { SupportedLanguages } from '../../config/supported-languages.js';
6
7
  /**
7
8
  * Node types that represent function/method definitions across languages.
8
9
  * Used to find the enclosing function for a call site.
@@ -50,8 +51,35 @@ const findEnclosingFunction = (node, filePath, symbolTable) => {
50
51
  current.type === 'generator_function_declaration' ||
51
52
  current.type === 'function_item') { // Rust function
52
53
  // Named function: function foo() {}
53
- const nameNode = current.childForFieldName?.('name') ||
54
+ // (patch-05) C/C++ function_definition has no 'name' field — the name
55
+ // lives at declarator.declarator.identifier (or .field_identifier for
56
+ // C++ qualified names). The tree-sitter query in tree-sitter-queries.ts
57
+ // does this correctly; here in the AST walker we must mirror it.
58
+ let nameNode = current.childForFieldName?.('name') ||
54
59
  current.children?.find((c) => c.type === 'identifier' || c.type === 'property_identifier');
60
+ if (!nameNode && current.type === 'function_definition') {
61
+ // C/C++ path: walk declarator → declarator → identifier|field_identifier
62
+ let decl = current.childForFieldName?.('declarator');
63
+ // Strip pointer_declarator / reference_declarator wrappers
64
+ while (decl && (decl.type === 'pointer_declarator' || decl.type === 'reference_declarator')) {
65
+ decl = decl.childForFieldName?.('declarator') || decl.children?.find((c) => c.type !== '*' && c.type !== '&');
66
+ }
67
+ if (decl?.type === 'function_declarator') {
68
+ let inner = decl.childForFieldName?.('declarator');
69
+ // Some C++ qualified names look like (qualified_identifier scope::name)
70
+ while (inner && (inner.type === 'parenthesized_declarator' || inner.type === 'pointer_declarator')) {
71
+ inner = inner.childForFieldName?.('declarator') || inner.children?.find((c) => c.type === 'identifier' || c.type === 'field_identifier' || c.type === 'qualified_identifier');
72
+ }
73
+ if (inner?.type === 'identifier' || inner?.type === 'field_identifier') {
74
+ nameNode = inner;
75
+ }
76
+ else if (inner?.type === 'qualified_identifier') {
77
+ // C++ Class::method — take rightmost identifier
78
+ nameNode = inner.descendantsOfType?.('identifier')?.pop() ||
79
+ inner.children?.find((c) => c.type === 'identifier');
80
+ }
81
+ }
82
+ }
55
83
  funcName = nameNode?.text;
56
84
  }
57
85
  else if (current.type === 'impl_item') {
@@ -136,9 +164,10 @@ export const processCalls = async (graph, files, astCache, symbolTable, importMa
136
164
  let wasReparsed = false;
137
165
  if (!tree) {
138
166
  // Cache Miss: Re-parse
139
- // Use larger bufferSize for files > 32KB
167
+ // (patch-05) 4MB buffer 覆盖 filesystem-walker 允许的 2MB 文件上限;
168
+ // 见 parsing-processor.ts 同位 comment
140
169
  try {
141
- tree = parser.parse(file.content, undefined, { bufferSize: 1024 * 256 });
170
+ tree = parser.parse(file.content, undefined, { bufferSize: 1024 * 1024 * 4 });
142
171
  }
143
172
  catch (parseError) {
144
173
  // Skip files that can't be parsed
@@ -174,7 +203,7 @@ export const processCalls = async (graph, files, astCache, symbolTable, importMa
174
203
  if (isBuiltInOrNoise(calledName))
175
204
  return;
176
205
  // 4. Resolve the target using priority strategy (returns confidence)
177
- const resolved = resolveCallTarget(calledName, file.path, symbolTable, importMap);
206
+ const resolved = resolveCallTarget(calledName, file.path, symbolTable, importMap, language);
178
207
  if (!resolved)
179
208
  return;
180
209
  // 5. Find the enclosing function (caller)
@@ -201,9 +230,23 @@ export const processCalls = async (graph, files, astCache, symbolTable, importMa
201
230
  * B. Check local file definitions
202
231
  * C. Fuzzy global search (lowest confidence)
203
232
  *
204
- * Returns confidence score so agents know what to trust.
233
+ * C/C++ special-case (patch C 2026-05-15):
234
+ * In C/C++, function symbols are linker-visible across the whole binary; the
235
+ * `#include` graph is only a compile-time convenience that conveys prototypes,
236
+ * not the actual call topology. Many C projects (vim, linux kernel) use a
237
+ * single proto.h or auto-generated <name>.pro forward-declares so callers
238
+ * never #include the implementing .c file directly. Treating those as
239
+ * fuzzy-global low-confidence (0.3-0.5) under-counts genuine cross-file
240
+ * calls and pushes them below mist-analyzer's 0.35 dfs threshold, dropping
241
+ * chains like vim's `serverSendToVim → ... → call_internal_func → f_system`.
242
+ *
243
+ * For C/C++ we promote:
244
+ * - globally-unique (1 def in project) → 'c-global-unique' @ 0.85
245
+ * (same level as same-file: the linker resolves these identically)
246
+ * - ambiguous (>1 def with same name) → keep fuzzy-global semantics
247
+ * since we can't pick the right one without preprocessor evaluation.
205
248
  */
206
- const resolveCallTarget = (calledName, currentFile, symbolTable, importMap) => {
249
+ const resolveCallTarget = (calledName, currentFile, symbolTable, importMap, language) => {
207
250
  // Strategy B first (cheapest — single map lookup): Check local file
208
251
  const localNodeId = symbolTable.lookupExact(currentFile, calledName);
209
252
  if (localNodeId) {
@@ -222,6 +265,11 @@ const resolveCallTarget = (calledName, currentFile, symbolTable, importMap) => {
222
265
  }
223
266
  }
224
267
  }
268
+ // C/C++ patch: globally-unique symbols are linker-visible; promote to high.
269
+ if ((language === SupportedLanguages.C || language === SupportedLanguages.CPlusPlus) &&
270
+ allDefs.length === 1) {
271
+ return { nodeId: allDefs[0].nodeId, confidence: 0.85, reason: 'c-global-unique' };
272
+ }
225
273
  // Strategy C: Fuzzy global (no import match found)
226
274
  const confidence = allDefs.length === 1 ? 0.5 : 0.3;
227
275
  return { nodeId: allDefs[0].nodeId, confidence, reason: 'fuzzy-global' };
@@ -309,7 +357,8 @@ export const processCallsFromExtracted = async (graph, extractedCalls, symbolTab
309
357
  await yieldToEventLoop();
310
358
  }
311
359
  for (const call of calls) {
312
- const resolved = resolveCallTarget(call.calledName, call.filePath, symbolTable, importMap);
360
+ const callLang = getLanguageFromFilename(call.filePath);
361
+ const resolved = resolveCallTarget(call.calledName, call.filePath, symbolTable, importMap, callLang);
313
362
  if (!resolved)
314
363
  continue;
315
364
  const relId = generateId('CALLS', `${call.sourceId}:${call.calledName}->${resolved.nodeId}`);
@@ -162,7 +162,11 @@ const processParsingSequential = async (graph, files, symbolTable, astCache, onF
162
162
  await loadLanguage(language, file.path);
163
163
  let tree;
164
164
  try {
165
- tree = parser.parse(file.content, undefined, { bufferSize: 1024 * 256 });
165
+ // (patch-05) bufferSize 必须 文件大小;原 256KB vim evalfunc.c (315KB)
166
+ // 这种"单一巨大 C 文件"导致 tree-sitter 静默截断 → parse 出几百个 ERROR
167
+ // + 0 函数抽出。filesystem-walker 拒 > 2MB 文件,所以 4MB buffer 覆盖
168
+ // 所有合法 input。
169
+ tree = parser.parse(file.content, undefined, { bufferSize: 1024 * 1024 * 4 });
166
170
  }
167
171
  catch (parseError) {
168
172
  console.warn(`Skipping unparseable file: ${file.path}`);
@@ -3,9 +3,9 @@ export declare const TYPESCRIPT_QUERIES = "\n(class_declaration\n name: (type_i
3
3
  export declare const JAVASCRIPT_QUERIES = "\n(class_declaration\n name: (identifier) @name) @definition.class\n\n(function_declaration\n name: (identifier) @name) @definition.function\n\n(method_definition\n name: (property_identifier) @name) @definition.method\n\n(lexical_declaration\n (variable_declarator\n name: (identifier) @name\n value: (arrow_function))) @definition.function\n\n(lexical_declaration\n (variable_declarator\n name: (identifier) @name\n value: (function_expression))) @definition.function\n\n(export_statement\n declaration: (lexical_declaration\n (variable_declarator\n name: (identifier) @name\n value: (arrow_function)))) @definition.function\n\n(export_statement\n declaration: (lexical_declaration\n (variable_declarator\n name: (identifier) @name\n value: (function_expression)))) @definition.function\n\n(import_statement\n source: (string) @import.source) @import\n\n(call_expression\n function: (identifier) @call.name) @call\n\n(call_expression\n function: (member_expression\n property: (property_identifier) @call.name)) @call\n\n; Heritage queries - class extends (JavaScript uses different AST than TypeScript)\n; In tree-sitter-javascript, class_heritage directly contains the parent identifier\n(class_declaration\n name: (identifier) @heritage.class\n (class_heritage\n (identifier) @heritage.extends)) @heritage\n";
4
4
  export declare const PYTHON_QUERIES = "\n(class_definition\n name: (identifier) @name) @definition.class\n\n(function_definition\n name: (identifier) @name) @definition.function\n\n(import_statement\n name: (dotted_name) @import.source) @import\n\n(import_from_statement\n module_name: (dotted_name) @import.source) @import\n\n(call\n function: (identifier) @call.name) @call\n\n(call\n function: (attribute\n attribute: (identifier) @call.name)) @call\n\n; Heritage queries - Python class inheritance\n(class_definition\n name: (identifier) @heritage.class\n superclasses: (argument_list\n (identifier) @heritage.extends)) @heritage\n";
5
5
  export declare const JAVA_QUERIES = "\n; Classes, Interfaces, Enums, Annotations\n(class_declaration name: (identifier) @name) @definition.class\n(interface_declaration name: (identifier) @name) @definition.interface\n(enum_declaration name: (identifier) @name) @definition.enum\n(annotation_type_declaration name: (identifier) @name) @definition.annotation\n\n; Methods & Constructors\n(method_declaration name: (identifier) @name) @definition.method\n(constructor_declaration name: (identifier) @name) @definition.constructor\n\n; Imports - capture any import declaration child as source\n(import_declaration (_) @import.source) @import\n\n; Calls\n(method_invocation name: (identifier) @call.name) @call\n(method_invocation object: (_) name: (identifier) @call.name) @call\n\n; Heritage - extends class\n(class_declaration name: (identifier) @heritage.class\n (superclass (type_identifier) @heritage.extends)) @heritage\n\n; Heritage - implements interfaces\n(class_declaration name: (identifier) @heritage.class\n (super_interfaces (type_list (type_identifier) @heritage.implements))) @heritage.impl\n";
6
- export declare const C_QUERIES = "\n; Functions\n(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function\n(declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.function\n\n; Structs, Unions, Enums, Typedefs\n(struct_specifier name: (type_identifier) @name) @definition.struct\n(union_specifier name: (type_identifier) @name) @definition.union\n(enum_specifier name: (type_identifier) @name) @definition.enum\n(type_definition declarator: (type_identifier) @name) @definition.typedef\n\n; Macros\n(preproc_function_def name: (identifier) @name) @definition.macro\n(preproc_def name: (identifier) @name) @definition.macro\n\n; Includes\n(preproc_include path: (_) @import.source) @import\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n";
6
+ export declare const C_QUERIES = "\n; Functions\n; (patch-05) cover return-by-pointer / pointer-to-pointer styles common in vim,\n; the kernel, OpenSSL, etc. AST shape for \"char *foo(...)\" is\n; function_definition\n; declarator: pointer_declarator (the leading *)\n; declarator: function_declarator\n; declarator: identifier (name)\n; Repeat for char **foo, char ***foo (pointer-of-pointer).\n(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function\n(function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function\n(function_definition declarator: (pointer_declarator declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name)))) @definition.function\n(declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.function\n(declaration declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function\n\n; Structs, Unions, Enums, Typedefs\n(struct_specifier name: (type_identifier) @name) @definition.struct\n(union_specifier name: (type_identifier) @name) @definition.union\n(enum_specifier name: (type_identifier) @name) @definition.enum\n(type_definition declarator: (type_identifier) @name) @definition.typedef\n\n; Macros\n(preproc_function_def name: (identifier) @name) @definition.macro\n(preproc_def name: (identifier) @name) @definition.macro\n\n; Includes\n(preproc_include path: (_) @import.source) @import\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n";
7
7
  export declare const GO_QUERIES = "\n; Functions & Methods\n(function_declaration name: (identifier) @name) @definition.function\n(method_declaration name: (field_identifier) @name) @definition.method\n\n; Types\n(type_declaration (type_spec name: (type_identifier) @name type: (struct_type))) @definition.struct\n(type_declaration (type_spec name: (type_identifier) @name type: (interface_type))) @definition.interface\n(type_declaration (type_spec name: (type_identifier) @name)) @definition.type\n\n; Imports\n(import_declaration (import_spec path: (interpreted_string_literal) @import.source)) @import\n(import_declaration (import_spec_list (import_spec path: (interpreted_string_literal) @import.source))) @import\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (selector_expression field: (field_identifier) @call.name)) @call\n";
8
- export declare const CPP_QUERIES = "\n; Classes, Structs, Namespaces\n(class_specifier name: (type_identifier) @name) @definition.class\n(struct_specifier name: (type_identifier) @name) @definition.struct\n(namespace_definition name: (namespace_identifier) @name) @definition.namespace\n(enum_specifier name: (type_identifier) @name) @definition.enum\n\n; Functions & Methods\n(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function\n(function_definition declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name))) @definition.method\n\n; Templates\n(template_declaration (class_specifier name: (type_identifier) @name)) @definition.template\n(template_declaration (function_definition declarator: (function_declarator declarator: (identifier) @name))) @definition.template\n\n; Includes\n(preproc_include path: (_) @import.source) @import\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n(call_expression function: (qualified_identifier name: (identifier) @call.name)) @call\n(call_expression function: (template_function name: (identifier) @call.name)) @call\n\n; Heritage\n(class_specifier name: (type_identifier) @heritage.class\n (base_class_clause (type_identifier) @heritage.extends)) @heritage\n(class_specifier name: (type_identifier) @heritage.class\n (base_class_clause (access_specifier) (type_identifier) @heritage.extends)) @heritage\n";
8
+ export declare const CPP_QUERIES = "\n; Classes, Structs, Namespaces\n(class_specifier name: (type_identifier) @name) @definition.class\n(struct_specifier name: (type_identifier) @name) @definition.struct\n(namespace_definition name: (namespace_identifier) @name) @definition.namespace\n(enum_specifier name: (type_identifier) @name) @definition.enum\n\n; Functions & Methods\n; (patch-05) same return-by-pointer/reference cases as C, plus C++ qualified names.\n(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function\n(function_definition declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name))) @definition.method\n(function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function\n(function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name)))) @definition.method\n(function_definition declarator: (reference_declarator (function_declarator declarator: (identifier) @name))) @definition.function\n(function_definition declarator: (reference_declarator (function_declarator declarator: (qualified_identifier name: (identifier) @name)))) @definition.method\n\n; Templates\n(template_declaration (class_specifier name: (type_identifier) @name)) @definition.template\n(template_declaration (function_definition declarator: (function_declarator declarator: (identifier) @name))) @definition.template\n\n; Includes\n(preproc_include path: (_) @import.source) @import\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n(call_expression function: (qualified_identifier name: (identifier) @call.name)) @call\n(call_expression function: (template_function name: (identifier) @call.name)) @call\n\n; Heritage\n(class_specifier name: (type_identifier) @heritage.class\n (base_class_clause (type_identifier) @heritage.extends)) @heritage\n(class_specifier name: (type_identifier) @heritage.class\n (base_class_clause (access_specifier) (type_identifier) @heritage.extends)) @heritage\n";
9
9
  export declare const CSHARP_QUERIES = "\n; Types\n(class_declaration name: (identifier) @name) @definition.class\n(interface_declaration name: (identifier) @name) @definition.interface\n(struct_declaration name: (identifier) @name) @definition.struct\n(enum_declaration name: (identifier) @name) @definition.enum\n(record_declaration name: (identifier) @name) @definition.record\n(delegate_declaration name: (identifier) @name) @definition.delegate\n\n; Namespaces\n(namespace_declaration name: (identifier) @name) @definition.namespace\n(namespace_declaration name: (qualified_name) @name) @definition.namespace\n\n; Methods & Properties\n(method_declaration name: (identifier) @name) @definition.method\n(local_function_statement name: (identifier) @name) @definition.function\n(constructor_declaration name: (identifier) @name) @definition.constructor\n(property_declaration name: (identifier) @name) @definition.property\n\n; Using\n(using_directive (qualified_name) @import.source) @import\n(using_directive (identifier) @import.source) @import\n\n; Calls\n(invocation_expression function: (identifier) @call.name) @call\n(invocation_expression function: (member_access_expression name: (identifier) @call.name)) @call\n\n; Heritage\n(class_declaration name: (identifier) @heritage.class\n (base_list (simple_base_type (identifier) @heritage.extends))) @heritage\n(class_declaration name: (identifier) @heritage.class\n (base_list (simple_base_type (generic_name (identifier) @heritage.extends)))) @heritage\n";
10
10
  export declare const RUST_QUERIES = "\n; Functions & Items\n(function_item name: (identifier) @name) @definition.function\n(struct_item name: (type_identifier) @name) @definition.struct\n(enum_item name: (type_identifier) @name) @definition.enum\n(trait_item name: (type_identifier) @name) @definition.trait\n(impl_item type: (type_identifier) @name) @definition.impl\n(mod_item name: (identifier) @name) @definition.module\n\n; Type aliases, const, static, macros\n(type_item name: (type_identifier) @name) @definition.type\n(const_item name: (identifier) @name) @definition.const\n(static_item name: (identifier) @name) @definition.static\n(macro_definition name: (identifier) @name) @definition.macro\n\n; Use statements\n(use_declaration argument: (_) @import.source) @import\n\n; Calls\n(call_expression function: (identifier) @call.name) @call\n(call_expression function: (field_expression field: (field_identifier) @call.name)) @call\n(call_expression function: (scoped_identifier name: (identifier) @call.name)) @call\n(call_expression function: (generic_function function: (identifier) @call.name)) @call\n\n; Heritage (trait implementation)\n(impl_item trait: (type_identifier) @heritage.trait type: (type_identifier) @heritage.class) @heritage\n(impl_item trait: (generic_type type: (type_identifier) @heritage.trait) type: (type_identifier) @heritage.class) @heritage\n";
11
11
  export declare const SOLIDITY_QUERIES = "\n; Contracts, Libraries, Interfaces\n(contract_declaration name: (identifier) @name) @definition.class\n(library_declaration name: (identifier) @name) @definition.class\n(interface_declaration name: (identifier) @name) @definition.interface\n\n; Functions, Constructors, Modifiers\n(function_definition name: (identifier) @name) @definition.function\n(modifier_definition name: (identifier) @name) @definition.function\n\n; Events, Errors\n(event_definition name: (identifier) @name) @definition.function\n(error_declaration name: (identifier) @name) @definition.function\n\n; Structs, Enums\n(struct_declaration name: (identifier) @name) @definition.struct\n(enum_declaration name: (identifier) @name) @definition.enum\n\n; Imports\n(import_directive source: (string) @import.source) @import\n\n; Calls (Solidity call_expression uses 'expression' child, not 'function' field)\n(call_expression (expression (identifier) @call.name)) @call\n(call_expression (expression (member_expression property: (identifier) @call.name))) @call\n\n; Heritage - contract inheritance (contract X is Y, Z)\n(contract_declaration\n name: (identifier) @heritage.class\n (inheritance_specifier ancestor: (user_defined_type (identifier) @heritage.extends))) @heritage\n(interface_declaration\n name: (identifier) @heritage.class\n (inheritance_specifier ancestor: (user_defined_type (identifier) @heritage.extends))) @heritage\n";
@@ -173,8 +173,18 @@ export const JAVA_QUERIES = `
173
173
  // C queries - works with tree-sitter-c
174
174
  export const C_QUERIES = `
175
175
  ; Functions
176
+ ; (patch-05) cover return-by-pointer / pointer-to-pointer styles common in vim,
177
+ ; the kernel, OpenSSL, etc. AST shape for "char *foo(...)" is
178
+ ; function_definition
179
+ ; declarator: pointer_declarator (the leading *)
180
+ ; declarator: function_declarator
181
+ ; declarator: identifier (name)
182
+ ; Repeat for char **foo, char ***foo (pointer-of-pointer).
176
183
  (function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function
184
+ (function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function
185
+ (function_definition declarator: (pointer_declarator declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name)))) @definition.function
177
186
  (declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.function
187
+ (declaration declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function
178
188
 
179
189
  ; Structs, Unions, Enums, Typedefs
180
190
  (struct_specifier name: (type_identifier) @name) @definition.struct
@@ -221,8 +231,13 @@ export const CPP_QUERIES = `
221
231
  (enum_specifier name: (type_identifier) @name) @definition.enum
222
232
 
223
233
  ; Functions & Methods
234
+ ; (patch-05) same return-by-pointer/reference cases as C, plus C++ qualified names.
224
235
  (function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function
225
236
  (function_definition declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name))) @definition.method
237
+ (function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function
238
+ (function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name)))) @definition.method
239
+ (function_definition declarator: (reference_declarator (function_declarator declarator: (identifier) @name))) @definition.function
240
+ (function_definition declarator: (reference_declarator (function_declarator declarator: (qualified_identifier name: (identifier) @name)))) @definition.method
226
241
 
227
242
  ; Templates
228
243
  (template_declaration (class_specifier name: (type_identifier) @name)) @definition.template
@@ -1,14 +1,3 @@
1
- export interface LoginResponse {
2
- success: boolean;
3
- access_token: string;
4
- refresh_token?: string;
5
- token_type: string;
6
- user: {
7
- user_id: string;
8
- username: string;
9
- display_name: string;
10
- };
11
- }
12
1
  export interface UserInfo {
13
2
  success: boolean;
14
3
  user_id: string;
@@ -1,4 +1,4 @@
1
- export declare const DEFAULT_SERVER_URL = "https://solidity.slowmist.ai";
1
+ export declare const DEFAULT_SERVER_URL = "https://agent.slowmist.ai";
2
2
  export declare function getServerUrl(cliArg?: string): string;
3
3
  export declare function saveToken(token: string): void;
4
4
  export declare function loadToken(): string | null;
@@ -9,8 +9,8 @@ const TOKEN_FILE = join(CONFIG_DIR, 'token');
9
9
  // Supabase refresh token(用于自动续期 access_token)
10
10
  const REFRESH_TOKEN_FILE = join(CONFIG_DIR, 'refresh_token');
11
11
  // 后端服务器默认地址,可通过 CLI 参数或环境变量 MISTAGENT_SERVER 覆盖
12
- // 发布时由 publish.sh 自动切换为 'https://solidity.slowmist.ai',发布后自动改回
13
- export const DEFAULT_SERVER_URL = 'https://solidity.slowmist.ai';
12
+ // 发布时由 publish.sh 自动切换为 'https://agent.slowmist.ai',发布后自动改回
13
+ export const DEFAULT_SERVER_URL = 'https://agent.slowmist.ai';
14
14
  // 获取后端服务器地址,优先级: CLI 参数 > 环境变量 > 默认值
15
15
  // 非 localhost 地址强制要求 HTTPS,防止中间人攻击导致 token 泄露
16
16
  export function getServerUrl(cliArg) {
@@ -1,4 +1,4 @@
1
- export declare const VERSION = "0.1.21";
1
+ export declare const VERSION = "0.1.23";
2
2
  export declare const BANNER_LINES: string[];
3
3
  export declare const BANNER_SUBTITLE = " A G E N T";
4
4
  export declare function getBannerGradient(): string[];
@@ -1,4 +1,4 @@
1
- export const VERSION = '0.1.21';
1
+ export const VERSION = '0.1.23';
2
2
  // Banner as line array for per-line gradient coloring
3
3
  export const BANNER_LINES = [
4
4
  ' ███╗ ███╗██╗███████╗████████╗',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mistagent",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "MistAgent - Terminal AI Assistant",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",