token-goat 2.6.21 → 2.6.22
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/README.md +3 -3
- package/dist/token-goat-hook.mjs +539 -320
- package/dist/token-goat.mjs +453 -234
- package/package.json +3 -2
package/dist/token-goat-hook.mjs
CHANGED
|
@@ -49,7 +49,7 @@ var init_define_import_meta_env = __esm({
|
|
|
49
49
|
import { createRequire } from "node:module";
|
|
50
50
|
function resolveVersion() {
|
|
51
51
|
if (true) {
|
|
52
|
-
return "2.6.
|
|
52
|
+
return "2.6.22";
|
|
53
53
|
}
|
|
54
54
|
const require2 = createRequire(import.meta.url);
|
|
55
55
|
const pkg = require2("../package.json");
|
|
@@ -1907,10 +1907,12 @@ function buildGuidanceBody(fallbackToolClause) {
|
|
|
1907
1907
|
"",
|
|
1908
1908
|
`This gate decides *whether* to reach for a read tool at all. ${fallbackToolClause} only pick the *fallback* once token-goat has been ruled out for this read \u2014 they never authorize skipping the gate.`,
|
|
1909
1909
|
"",
|
|
1910
|
+
"Fallback clauses may name native tools (`Read`, `Grep`, `Glob`, `shell`, `apply_patch`, `view_image`, `edit`, `create`) or PowerShell helpers (`Get-Content`, `Select-String`); shell/editor commands like `rg`, `grep`, `fd`, `sed`, `cat`, `find`, and `ls` are commands, not tool identifiers.",
|
|
1911
|
+
"",
|
|
1910
1912
|
"Exemptions (gate passes, read directly): the file is under ~200 lines and you need all of it; it was never indexed (new, untracked, or generated this turn); it is binary or an image; the target has no symbol handle (e.g. a literal mid-function).",
|
|
1911
1913
|
"",
|
|
1912
1914
|
"Failure shapes to catch yourself in, and the command that replaces each:",
|
|
1913
|
-
'- grep
|
|
1915
|
+
'- shell `rg`/`grep` search with context flags to find a function body \u2192 `read "file::symbol"`',
|
|
1914
1916
|
'- paging one function with view/view_range \u2192 `read "file::symbol"`',
|
|
1915
1917
|
'- reading one heading of a large doc \u2192 `section "file::Heading"`',
|
|
1916
1918
|
"- searching for a symbol's callers \u2192 `refs file::symbol --callers`",
|
|
@@ -1935,6 +1937,113 @@ var init_guidance_block = __esm({
|
|
|
1935
1937
|
}
|
|
1936
1938
|
});
|
|
1937
1939
|
|
|
1940
|
+
// src/hook_registry.ts
|
|
1941
|
+
function registerHook(eventName, handler, opts) {
|
|
1942
|
+
let list = _handlers.get(eventName);
|
|
1943
|
+
if (list === void 0) {
|
|
1944
|
+
list = [];
|
|
1945
|
+
_handlers.set(eventName, list);
|
|
1946
|
+
}
|
|
1947
|
+
list.push({
|
|
1948
|
+
handler,
|
|
1949
|
+
toolName: opts?.toolName,
|
|
1950
|
+
toolPattern: opts?.toolPattern,
|
|
1951
|
+
advisory: opts?.advisory === true,
|
|
1952
|
+
followsMatcher: opts?.followsMatcher === true
|
|
1953
|
+
});
|
|
1954
|
+
}
|
|
1955
|
+
function toolMatcherFor(eventName) {
|
|
1956
|
+
const list = _handlers.get(eventName);
|
|
1957
|
+
if (list === void 0 || list.length === 0) return null;
|
|
1958
|
+
const parts = [];
|
|
1959
|
+
for (const { toolName, toolPattern, followsMatcher } of list) {
|
|
1960
|
+
if (followsMatcher) continue;
|
|
1961
|
+
if (toolName === void 0 && toolPattern === void 0) return null;
|
|
1962
|
+
for (const part of [toolName === void 0 ? void 0 : `^${toolName}$`, toolPattern]) {
|
|
1963
|
+
if (part !== void 0 && part !== "" && !parts.includes(part)) parts.push(part);
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
if (parts.length === 0) return null;
|
|
1967
|
+
return parts.join("|");
|
|
1968
|
+
}
|
|
1969
|
+
async function runHook(event) {
|
|
1970
|
+
const list = _handlers.get(event.eventName);
|
|
1971
|
+
if (list === void 0) return { hookType: "pass" };
|
|
1972
|
+
let advisoryResult;
|
|
1973
|
+
for (const { handler, toolName, advisory } of list) {
|
|
1974
|
+
if (toolName !== void 0 && toolName !== event.toolName) continue;
|
|
1975
|
+
const result = await handler(event);
|
|
1976
|
+
if (result.hookType !== "pass") {
|
|
1977
|
+
if (advisory) {
|
|
1978
|
+
advisoryResult = result;
|
|
1979
|
+
continue;
|
|
1980
|
+
}
|
|
1981
|
+
return result;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
return advisoryResult ?? { hookType: "pass" };
|
|
1985
|
+
}
|
|
1986
|
+
function clearHooks() {
|
|
1987
|
+
_handlers.clear();
|
|
1988
|
+
}
|
|
1989
|
+
function serializeOutput(output, eventName) {
|
|
1990
|
+
switch (output.hookType) {
|
|
1991
|
+
case "deny":
|
|
1992
|
+
return JSON.stringify({ decision: "block", reason: output.message });
|
|
1993
|
+
case "context":
|
|
1994
|
+
if (EVENTS_WITHOUT_ADDITIONAL_CONTEXT.has(eventName)) {
|
|
1995
|
+
return JSON.stringify({ systemMessage: output.context });
|
|
1996
|
+
}
|
|
1997
|
+
return JSON.stringify({
|
|
1998
|
+
hookSpecificOutput: {
|
|
1999
|
+
hookEventName: CLAUDE_CODE_EVENT_NAMES[eventName],
|
|
2000
|
+
additionalContext: output.context
|
|
2001
|
+
}
|
|
2002
|
+
});
|
|
2003
|
+
case "rewriteInput":
|
|
2004
|
+
return JSON.stringify({
|
|
2005
|
+
hookSpecificOutput: {
|
|
2006
|
+
hookEventName: "PreToolUse",
|
|
2007
|
+
permissionDecision: "allow",
|
|
2008
|
+
updatedInput: output.updatedInput
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
2011
|
+
case "rewriteOutput":
|
|
2012
|
+
return JSON.stringify({
|
|
2013
|
+
hookSpecificOutput: {
|
|
2014
|
+
hookEventName: "PostToolUse",
|
|
2015
|
+
updatedToolOutput: output.updatedOutput
|
|
2016
|
+
}
|
|
2017
|
+
});
|
|
2018
|
+
case "pass":
|
|
2019
|
+
return JSON.stringify({});
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
var _handlers, CLAUDE_CODE_EVENT_NAMES, EVENTS_WITHOUT_ADDITIONAL_CONTEXT;
|
|
2023
|
+
var init_hook_registry = __esm({
|
|
2024
|
+
"src/hook_registry.ts"() {
|
|
2025
|
+
"use strict";
|
|
2026
|
+
init_define_import_meta_env();
|
|
2027
|
+
init_reset();
|
|
2028
|
+
_handlers = /* @__PURE__ */ new Map();
|
|
2029
|
+
registerReset(clearHooks);
|
|
2030
|
+
CLAUDE_CODE_EVENT_NAMES = {
|
|
2031
|
+
pre_tool_use: "PreToolUse",
|
|
2032
|
+
post_tool_use: "PostToolUse",
|
|
2033
|
+
notification: "Notification",
|
|
2034
|
+
stop: "Stop",
|
|
2035
|
+
pre_compact: "PreCompact",
|
|
2036
|
+
user_prompt_submit: "UserPromptSubmit",
|
|
2037
|
+
subagent_stop: "SubagentStop",
|
|
2038
|
+
session_start: "SessionStart"
|
|
2039
|
+
};
|
|
2040
|
+
EVENTS_WITHOUT_ADDITIONAL_CONTEXT = /* @__PURE__ */ new Set([
|
|
2041
|
+
"notification",
|
|
2042
|
+
"pre_compact"
|
|
2043
|
+
]);
|
|
2044
|
+
}
|
|
2045
|
+
});
|
|
2046
|
+
|
|
1938
2047
|
// src/install.ts
|
|
1939
2048
|
import * as fs2 from "node:fs";
|
|
1940
2049
|
import * as os2 from "node:os";
|
|
@@ -2016,13 +2125,28 @@ function installHooks(scope = "user") {
|
|
|
2016
2125
|
}
|
|
2017
2126
|
}
|
|
2018
2127
|
if (groupHasTokenGoat(groups, isCurrentTokenGoatHookCommand)) {
|
|
2019
|
-
|
|
2128
|
+
const narrowed = toolMatcherFor(eventArg);
|
|
2129
|
+
let renarrowed = false;
|
|
2130
|
+
if (narrowed !== null) {
|
|
2131
|
+
for (let i = 0; i < groups.length; i++) {
|
|
2132
|
+
const group = groups[i];
|
|
2133
|
+
if (group === void 0) continue;
|
|
2134
|
+
const ownHooks = group.hooks ?? [];
|
|
2135
|
+
const isOwnGroup = ownHooks.length > 0 && ownHooks.every((h) => isCurrentTokenGoatHookCommand(h.command));
|
|
2136
|
+
if (isOwnGroup && group.matcher !== narrowed) {
|
|
2137
|
+
groups[i] = { ...group, matcher: narrowed };
|
|
2138
|
+
renarrowed = true;
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
if (strippedLegacy || renarrowed) {
|
|
2020
2143
|
hooks[eventKey] = groups;
|
|
2021
2144
|
changed = true;
|
|
2022
2145
|
}
|
|
2023
2146
|
continue;
|
|
2024
2147
|
}
|
|
2025
|
-
|
|
2148
|
+
const matcher = toolMatcherFor(eventArg) ?? "";
|
|
2149
|
+
groups.push({ matcher, hooks: [{ type: "command", command: hookCommand(eventArg) }] });
|
|
2026
2150
|
hooks[eventKey] = groups;
|
|
2027
2151
|
changed = true;
|
|
2028
2152
|
}
|
|
@@ -2155,6 +2279,7 @@ var init_install = __esm({
|
|
|
2155
2279
|
"use strict";
|
|
2156
2280
|
init_define_import_meta_env();
|
|
2157
2281
|
init_guidance_block();
|
|
2282
|
+
init_hook_registry();
|
|
2158
2283
|
init_paths();
|
|
2159
2284
|
init_util2();
|
|
2160
2285
|
HOOK_EVENT_MAP = [
|
|
@@ -2176,6 +2301,20 @@ var init_install = __esm({
|
|
|
2176
2301
|
SKILL_MD_FRONTMATTER = `---
|
|
2177
2302
|
name: token-goat
|
|
2178
2303
|
description: Use before reading whole files or grepping wide. token-goat commands (symbol, read, section, semantic, outline, skeleton, map, refs, changed, config-get, bash-output, web-output, gdrive-sections) return narrow slices of code and docs at a fraction of the token cost.
|
|
2304
|
+
allowed-tools:
|
|
2305
|
+
- symbol
|
|
2306
|
+
- read
|
|
2307
|
+
- section
|
|
2308
|
+
- semantic
|
|
2309
|
+
- outline
|
|
2310
|
+
- skeleton
|
|
2311
|
+
- map
|
|
2312
|
+
- refs
|
|
2313
|
+
- changed
|
|
2314
|
+
- config-get
|
|
2315
|
+
- bash-output
|
|
2316
|
+
- web-output
|
|
2317
|
+
- gdrive-sections
|
|
2179
2318
|
---`;
|
|
2180
2319
|
SKILL_MD_CONTENT = `${SKILL_MD_FRONTMATTER}
|
|
2181
2320
|
|
|
@@ -2330,7 +2469,7 @@ function buildAgentsBlock() {
|
|
|
2330
2469
|
return buildGuidanceBlock({
|
|
2331
2470
|
beginMarker: AGENTS_BEGIN,
|
|
2332
2471
|
endMarker: AGENTS_END,
|
|
2333
|
-
fallbackToolClause: "Codex's
|
|
2472
|
+
fallbackToolClause: "Codex's native `shell`, `apply_patch`, and `view_image` tools (shell commands like `cat`/`type` run inside `shell`)"
|
|
2334
2473
|
});
|
|
2335
2474
|
}
|
|
2336
2475
|
function writeAgentsBlock(p) {
|
|
@@ -2720,11 +2859,16 @@ function copilotCliInstructionsPath(opts = {}) {
|
|
|
2720
2859
|
return path6.join(path6.dirname(copilotCliHooksDir(opts)), "copilot-instructions.md");
|
|
2721
2860
|
}
|
|
2722
2861
|
function buildCopilotInstructionsBlock() {
|
|
2723
|
-
return
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2862
|
+
return stripInlineCodeSpans(
|
|
2863
|
+
buildGuidanceBlock({
|
|
2864
|
+
beginMarker: COPILOT_INSTRUCTIONS_BEGIN,
|
|
2865
|
+
endMarker: COPILOT_INSTRUCTIONS_END,
|
|
2866
|
+
fallbackToolClause: "Copilot CLI's native `view`, `grep`, and `glob` tools (with PowerShell commands `Get-Content`/`Select-String` as search fallbacks)"
|
|
2867
|
+
})
|
|
2868
|
+
);
|
|
2869
|
+
}
|
|
2870
|
+
function stripInlineCodeSpans(text) {
|
|
2871
|
+
return text.replace(/`([^`]+)`/g, "$1");
|
|
2728
2872
|
}
|
|
2729
2873
|
function writeCopilotInstructionsBlock(p) {
|
|
2730
2874
|
return upsertDelimitedBlock(p, COPILOT_INSTRUCTIONS_BEGIN, COPILOT_INSTRUCTIONS_END, buildCopilotInstructionsBlock());
|
|
@@ -3024,93 +3168,6 @@ var init_bridges = __esm({
|
|
|
3024
3168
|
}
|
|
3025
3169
|
});
|
|
3026
3170
|
|
|
3027
|
-
// src/hook_registry.ts
|
|
3028
|
-
function registerHook(eventName, handler, opts) {
|
|
3029
|
-
let list = _handlers.get(eventName);
|
|
3030
|
-
if (list === void 0) {
|
|
3031
|
-
list = [];
|
|
3032
|
-
_handlers.set(eventName, list);
|
|
3033
|
-
}
|
|
3034
|
-
list.push({ handler, toolName: opts?.toolName, advisory: opts?.advisory === true });
|
|
3035
|
-
}
|
|
3036
|
-
async function runHook(event) {
|
|
3037
|
-
const list = _handlers.get(event.eventName);
|
|
3038
|
-
if (list === void 0) return { hookType: "pass" };
|
|
3039
|
-
let advisoryResult;
|
|
3040
|
-
for (const { handler, toolName, advisory } of list) {
|
|
3041
|
-
if (toolName !== void 0 && toolName !== event.toolName) continue;
|
|
3042
|
-
const result = await handler(event);
|
|
3043
|
-
if (result.hookType !== "pass") {
|
|
3044
|
-
if (advisory) {
|
|
3045
|
-
advisoryResult = result;
|
|
3046
|
-
continue;
|
|
3047
|
-
}
|
|
3048
|
-
return result;
|
|
3049
|
-
}
|
|
3050
|
-
}
|
|
3051
|
-
return advisoryResult ?? { hookType: "pass" };
|
|
3052
|
-
}
|
|
3053
|
-
function clearHooks() {
|
|
3054
|
-
_handlers.clear();
|
|
3055
|
-
}
|
|
3056
|
-
function serializeOutput(output, eventName) {
|
|
3057
|
-
switch (output.hookType) {
|
|
3058
|
-
case "deny":
|
|
3059
|
-
return JSON.stringify({ decision: "block", reason: output.message });
|
|
3060
|
-
case "context":
|
|
3061
|
-
if (EVENTS_WITHOUT_ADDITIONAL_CONTEXT.has(eventName)) {
|
|
3062
|
-
return JSON.stringify({ systemMessage: output.context });
|
|
3063
|
-
}
|
|
3064
|
-
return JSON.stringify({
|
|
3065
|
-
hookSpecificOutput: {
|
|
3066
|
-
hookEventName: CLAUDE_CODE_EVENT_NAMES[eventName],
|
|
3067
|
-
additionalContext: output.context
|
|
3068
|
-
}
|
|
3069
|
-
});
|
|
3070
|
-
case "rewriteInput":
|
|
3071
|
-
return JSON.stringify({
|
|
3072
|
-
hookSpecificOutput: {
|
|
3073
|
-
hookEventName: "PreToolUse",
|
|
3074
|
-
permissionDecision: "allow",
|
|
3075
|
-
updatedInput: output.updatedInput
|
|
3076
|
-
}
|
|
3077
|
-
});
|
|
3078
|
-
case "rewriteOutput":
|
|
3079
|
-
return JSON.stringify({
|
|
3080
|
-
hookSpecificOutput: {
|
|
3081
|
-
hookEventName: "PostToolUse",
|
|
3082
|
-
updatedToolOutput: output.updatedOutput
|
|
3083
|
-
}
|
|
3084
|
-
});
|
|
3085
|
-
case "pass":
|
|
3086
|
-
return JSON.stringify({});
|
|
3087
|
-
}
|
|
3088
|
-
}
|
|
3089
|
-
var _handlers, CLAUDE_CODE_EVENT_NAMES, EVENTS_WITHOUT_ADDITIONAL_CONTEXT;
|
|
3090
|
-
var init_hook_registry = __esm({
|
|
3091
|
-
"src/hook_registry.ts"() {
|
|
3092
|
-
"use strict";
|
|
3093
|
-
init_define_import_meta_env();
|
|
3094
|
-
init_reset();
|
|
3095
|
-
_handlers = /* @__PURE__ */ new Map();
|
|
3096
|
-
registerReset(clearHooks);
|
|
3097
|
-
CLAUDE_CODE_EVENT_NAMES = {
|
|
3098
|
-
pre_tool_use: "PreToolUse",
|
|
3099
|
-
post_tool_use: "PostToolUse",
|
|
3100
|
-
notification: "Notification",
|
|
3101
|
-
stop: "Stop",
|
|
3102
|
-
pre_compact: "PreCompact",
|
|
3103
|
-
user_prompt_submit: "UserPromptSubmit",
|
|
3104
|
-
subagent_stop: "SubagentStop",
|
|
3105
|
-
session_start: "SessionStart"
|
|
3106
|
-
};
|
|
3107
|
-
EVENTS_WITHOUT_ADDITIONAL_CONTEXT = /* @__PURE__ */ new Set([
|
|
3108
|
-
"notification",
|
|
3109
|
-
"pre_compact"
|
|
3110
|
-
]);
|
|
3111
|
-
}
|
|
3112
|
-
});
|
|
3113
|
-
|
|
3114
3171
|
// src/env.ts
|
|
3115
3172
|
function envStr(key, defaultVal) {
|
|
3116
3173
|
const raw = process.env[key];
|
|
@@ -3815,6 +3872,7 @@ function _buildConfig(raw, projectRaw = {}) {
|
|
|
3815
3872
|
ix.large_file_skip_kb = validatedInt(ix_raw["large_file_skip_kb"], ix.large_file_skip_kb, ...boundsOf("indexing.large_file_skip_kb"));
|
|
3816
3873
|
ix.large_file_symbol_only_kb = Math.min(ix.large_file_symbol_only_kb, ix.large_file_skip_kb);
|
|
3817
3874
|
ix.skip_dirs = validatedStrList(ix_raw["skip_dirs"], ix.skip_dirs);
|
|
3875
|
+
ix.skip_files = validatedStrList(ix_raw["skip_files"], ix.skip_files);
|
|
3818
3876
|
ix.embeddings_enabled = validatedBool(ix_raw["embeddings_enabled"], ix.embeddings_enabled);
|
|
3819
3877
|
ix.embeddings_enabled = envBool("TOKEN_GOAT_EMBEDDINGS_ENABLED", ix.embeddings_enabled);
|
|
3820
3878
|
const cpr_raw = section(raw, "compression");
|
|
@@ -3990,6 +4048,7 @@ function saveConfig(config2) {
|
|
|
3990
4048
|
large_file_symbol_only_kb: config2.indexing.large_file_symbol_only_kb,
|
|
3991
4049
|
large_file_skip_kb: config2.indexing.large_file_skip_kb,
|
|
3992
4050
|
skip_dirs: config2.indexing.skip_dirs,
|
|
4051
|
+
skip_files: config2.indexing.skip_files,
|
|
3993
4052
|
embeddings_enabled: config2.indexing.embeddings_enabled
|
|
3994
4053
|
},
|
|
3995
4054
|
compression: {
|
|
@@ -4169,6 +4228,7 @@ var init_config = __esm({
|
|
|
4169
4228
|
large_file_symbol_only_kb: 500,
|
|
4170
4229
|
large_file_skip_kb: 2048,
|
|
4171
4230
|
skip_dirs: [],
|
|
4231
|
+
skip_files: ["coverage.json", "coverage-final.json"],
|
|
4172
4232
|
embeddings_enabled: true
|
|
4173
4233
|
},
|
|
4174
4234
|
compression: {
|
|
@@ -4525,7 +4585,8 @@ CREATE TABLE IF NOT EXISTS symbols (
|
|
|
4525
4585
|
line_start INTEGER,
|
|
4526
4586
|
line_end INTEGER,
|
|
4527
4587
|
body TEXT,
|
|
4528
|
-
docstring TEXT
|
|
4588
|
+
docstring TEXT,
|
|
4589
|
+
parent TEXT NOT NULL DEFAULT ''
|
|
4529
4590
|
);
|
|
4530
4591
|
CREATE INDEX IF NOT EXISTS idx_symbols_name ON symbols(name);
|
|
4531
4592
|
CREATE INDEX IF NOT EXISTS idx_symbols_file ON symbols(file_path);
|
|
@@ -4728,12 +4789,14 @@ CREATE TRIGGER IF NOT EXISTS cache_recall_au AFTER UPDATE ON cache_recall BEGIN
|
|
|
4728
4789
|
VALUES (new.row_id, new.label, new.content);
|
|
4729
4790
|
END;
|
|
4730
4791
|
`;
|
|
4731
|
-
SCHEMA_VERSION =
|
|
4792
|
+
SCHEMA_VERSION = 9;
|
|
4732
4793
|
MIGRATIONS = {
|
|
4733
4794
|
// v1 -> v2: adds files.embed_sha, tracked separately from files.sha so embedding freshness can be gated independently of parse freshness (see makeIndexer in worker.ts). A pre-existing v1 database's `files` table predates the column, so it needs an explicit ALTER TABLE here; a brand-new database already has the column from SCHEMA_SQL's CREATE TABLE above, so the ALTER TABLE would fail with "duplicate column name" there -- swallow exactly that error and rethrow anything else, so a genuine ALTER TABLE failure is never silently lost.
|
|
4734
4795
|
1: (conn) => alterTableIdempotent(conn, "ALTER TABLE files ADD COLUMN embed_sha TEXT"),
|
|
4735
4796
|
// v2 -> v3: adds files.retry_count, a durable per-path counter for consecutive transient-read-failure requeues (see MAX_TRANSIENT_RETRIES / requeueDirtyPath / resetTransientRetryCount in worker.ts). Previously this counter lived only in an in-memory Map inside worker.ts, which meant resetTransientRetryCount -- called from appendDirtyPath (hooks_index.ts) in the short-lived hook CLI process -- could never actually reach the long-lived detached daemon process's own copy of that Map: they are different Node processes with no shared memory, so the reset was a silent no-op in the real deployed topology. Persisting the counter in `files` makes it visible to both processes via the one thing they do share: the index DB. Same swallow-duplicate-column pattern as v1 -> v2 above.
|
|
4736
|
-
2: (conn) => alterTableIdempotent(conn, "ALTER TABLE files ADD COLUMN retry_count INTEGER NOT NULL DEFAULT 0")
|
|
4797
|
+
2: (conn) => alterTableIdempotent(conn, "ALTER TABLE files ADD COLUMN retry_count INTEGER NOT NULL DEFAULT 0"),
|
|
4798
|
+
// v8 -> v9: adds symbols.parent (see SCHEMA_VERSION comment above for why). A pre-existing v8 database's `symbols` table predates the column, so it needs an explicit ALTER TABLE here; a brand-new database already has the column from SCHEMA_SQL's CREATE TABLE above, so the ALTER TABLE would fail with "duplicate column name" there -- swallow exactly that error and rethrow anything else, same pattern as v1 -> v2 / v2 -> v3 above.
|
|
4799
|
+
8: (conn) => alterTableIdempotent(conn, "ALTER TABLE symbols ADD COLUMN parent TEXT NOT NULL DEFAULT ''")
|
|
4737
4800
|
};
|
|
4738
4801
|
registerReset(closeAllDbs);
|
|
4739
4802
|
}
|
|
@@ -7137,7 +7200,7 @@ var init_hint_stats = __esm({
|
|
|
7137
7200
|
resolvePendingHintsForEvent(event);
|
|
7138
7201
|
return passOutput();
|
|
7139
7202
|
},
|
|
7140
|
-
{ advisory: true }
|
|
7203
|
+
{ advisory: true, followsMatcher: true }
|
|
7141
7204
|
);
|
|
7142
7205
|
}
|
|
7143
7206
|
});
|
|
@@ -7420,23 +7483,23 @@ function isNoisePath(inputPath) {
|
|
|
7420
7483
|
}
|
|
7421
7484
|
}
|
|
7422
7485
|
const slashIdx = p.lastIndexOf("/");
|
|
7423
|
-
const
|
|
7424
|
-
if (NOISE_BASENAMES.has(
|
|
7486
|
+
const basename21 = slashIdx >= 0 ? p.slice(slashIdx + 1) : p;
|
|
7487
|
+
if (NOISE_BASENAMES.has(basename21)) {
|
|
7425
7488
|
return true;
|
|
7426
7489
|
}
|
|
7427
|
-
if (
|
|
7490
|
+
if (basename21.startsWith(".improve-state-") || basename21.startsWith("improve_commit_msg_")) {
|
|
7428
7491
|
return true;
|
|
7429
7492
|
}
|
|
7430
|
-
const dotIdx =
|
|
7493
|
+
const dotIdx = basename21.lastIndexOf(".");
|
|
7431
7494
|
if (dotIdx >= 0) {
|
|
7432
|
-
const ext2 =
|
|
7495
|
+
const ext2 = basename21.slice(dotIdx);
|
|
7433
7496
|
if (NOISE_EXTS.has(ext2)) {
|
|
7434
7497
|
return true;
|
|
7435
7498
|
}
|
|
7436
7499
|
}
|
|
7437
7500
|
for (const ext2 of NOISE_EXTS) {
|
|
7438
7501
|
if (ext2.includes(".") && ext2.split(".").length > 2) {
|
|
7439
|
-
if (
|
|
7502
|
+
if (basename21.endsWith(ext2)) {
|
|
7440
7503
|
return true;
|
|
7441
7504
|
}
|
|
7442
7505
|
}
|
|
@@ -8024,15 +8087,15 @@ var init_hints = __esm({
|
|
|
8024
8087
|
});
|
|
8025
8088
|
|
|
8026
8089
|
// src/hints/lang_patterns.ts
|
|
8027
|
-
function isLockFile(
|
|
8028
|
-
return LOCK_FILE_NAMES.has(
|
|
8090
|
+
function isLockFile(basename21) {
|
|
8091
|
+
return LOCK_FILE_NAMES.has(basename21.toLowerCase());
|
|
8029
8092
|
}
|
|
8030
|
-
function isManifestFile(
|
|
8031
|
-
const lower =
|
|
8093
|
+
function isManifestFile(basename21) {
|
|
8094
|
+
const lower = basename21.toLowerCase();
|
|
8032
8095
|
if (MANIFEST_FILE_NAMES.has(lower)) return true;
|
|
8033
8096
|
const dot = lower.lastIndexOf(".");
|
|
8034
8097
|
if (dot !== -1 && MANIFEST_EXTENSIONS.has(lower.slice(dot))) return true;
|
|
8035
|
-
if (MANIFEST_BASENAME_PATTERNS.some((re) => re.test(
|
|
8098
|
+
if (MANIFEST_BASENAME_PATTERNS.some((re) => re.test(basename21))) return true;
|
|
8036
8099
|
return false;
|
|
8037
8100
|
}
|
|
8038
8101
|
function pathSegments(filePath) {
|
|
@@ -8371,8 +8434,8 @@ function formatHeadingTree(headings, filePath) {
|
|
|
8371
8434
|
}
|
|
8372
8435
|
return lines2.join("\n");
|
|
8373
8436
|
}
|
|
8374
|
-
function getWellKnownSections(
|
|
8375
|
-
return WELL_KNOWN_SECTIONS[
|
|
8437
|
+
function getWellKnownSections(basename21) {
|
|
8438
|
+
return WELL_KNOWN_SECTIONS[basename21] ?? [];
|
|
8376
8439
|
}
|
|
8377
8440
|
function extractChangelogVersionHint(content, filePath) {
|
|
8378
8441
|
const lines2 = content.split("\n");
|
|
@@ -10190,6 +10253,64 @@ var init_sync = __esm({
|
|
|
10190
10253
|
}
|
|
10191
10254
|
});
|
|
10192
10255
|
|
|
10256
|
+
// src/doc_comment.ts
|
|
10257
|
+
function precedingDocComment(lines2, lineStart, style) {
|
|
10258
|
+
const aboveIdx = lineStart - 2;
|
|
10259
|
+
if (aboveIdx < 0 || aboveIdx >= lines2.length) return "";
|
|
10260
|
+
const aboveLine = lines2[aboveIdx];
|
|
10261
|
+
if (aboveLine === void 0) return "";
|
|
10262
|
+
const aboveTrimmed = aboveLine.trim();
|
|
10263
|
+
if (style === "hash") {
|
|
10264
|
+
if (!aboveTrimmed.startsWith("#")) return "";
|
|
10265
|
+
const collected = [];
|
|
10266
|
+
let i = aboveIdx;
|
|
10267
|
+
while (i >= 0) {
|
|
10268
|
+
const line = lines2[i];
|
|
10269
|
+
if (line === void 0) break;
|
|
10270
|
+
const trimmed = line.trim();
|
|
10271
|
+
if (!trimmed.startsWith("#")) break;
|
|
10272
|
+
collected.unshift(trimmed.replace(/^#+\s?/, ""));
|
|
10273
|
+
i--;
|
|
10274
|
+
}
|
|
10275
|
+
return collected.join("\n").trim();
|
|
10276
|
+
}
|
|
10277
|
+
if (aboveTrimmed.endsWith("*/")) {
|
|
10278
|
+
let blockStart = aboveIdx;
|
|
10279
|
+
while (blockStart >= 0) {
|
|
10280
|
+
const l = lines2[blockStart];
|
|
10281
|
+
if (l === void 0) break;
|
|
10282
|
+
if (l.trim().startsWith("/*")) break;
|
|
10283
|
+
blockStart--;
|
|
10284
|
+
}
|
|
10285
|
+
if (blockStart < 0) return "";
|
|
10286
|
+
const opener = lines2[blockStart];
|
|
10287
|
+
if (opener === void 0 || !opener.trim().startsWith("/*")) return "";
|
|
10288
|
+
return lines2.slice(blockStart, aboveIdx + 1).map(
|
|
10289
|
+
(l) => l.trim().replace(/^\/\*+/, "").replace(/\*+\/$/, "").replace(/^\*\s?/, "").trim()
|
|
10290
|
+
).filter((l) => l !== "").join("\n");
|
|
10291
|
+
}
|
|
10292
|
+
if (aboveTrimmed.startsWith("//")) {
|
|
10293
|
+
const collected = [];
|
|
10294
|
+
let i = aboveIdx;
|
|
10295
|
+
while (i >= 0) {
|
|
10296
|
+
const line = lines2[i];
|
|
10297
|
+
if (line === void 0) break;
|
|
10298
|
+
const trimmed = line.trim();
|
|
10299
|
+
if (!trimmed.startsWith("//")) break;
|
|
10300
|
+
collected.unshift(trimmed.replace(/^\/\/[/!]?\s?/, ""));
|
|
10301
|
+
i--;
|
|
10302
|
+
}
|
|
10303
|
+
return collected.join("\n").trim();
|
|
10304
|
+
}
|
|
10305
|
+
return "";
|
|
10306
|
+
}
|
|
10307
|
+
var init_doc_comment = __esm({
|
|
10308
|
+
"src/doc_comment.ts"() {
|
|
10309
|
+
"use strict";
|
|
10310
|
+
init_define_import_meta_env();
|
|
10311
|
+
}
|
|
10312
|
+
});
|
|
10313
|
+
|
|
10193
10314
|
// src/languages/common.ts
|
|
10194
10315
|
function buildLineIndex(text) {
|
|
10195
10316
|
const idx = [0];
|
|
@@ -10729,7 +10850,7 @@ function stripMultilineStringSpan(line, state, lang) {
|
|
|
10729
10850
|
}
|
|
10730
10851
|
return { code, state: cur };
|
|
10731
10852
|
}
|
|
10732
|
-
function makeSpanSymbol(filePath, name2, kind, span,
|
|
10853
|
+
function makeSpanSymbol(filePath, name2, kind, span, parent = "", lines2, style) {
|
|
10733
10854
|
return {
|
|
10734
10855
|
filePath,
|
|
10735
10856
|
name: name2,
|
|
@@ -10737,10 +10858,11 @@ function makeSpanSymbol(filePath, name2, kind, span, docstring = "") {
|
|
|
10737
10858
|
lineStart: span.startLine,
|
|
10738
10859
|
lineEnd: span.endLine,
|
|
10739
10860
|
body: span.body,
|
|
10740
|
-
docstring
|
|
10861
|
+
docstring: lines2 !== void 0 && style !== void 0 ? precedingDocComment(lines2, span.startLine, style) : "",
|
|
10862
|
+
parent
|
|
10741
10863
|
};
|
|
10742
10864
|
}
|
|
10743
|
-
function makeLineSymbol(filePath, name2, kind, line, sig, parent) {
|
|
10865
|
+
function makeLineSymbol(filePath, name2, kind, line, sig, parent, lines2, style) {
|
|
10744
10866
|
return {
|
|
10745
10867
|
filePath,
|
|
10746
10868
|
name: name2,
|
|
@@ -10748,7 +10870,8 @@ function makeLineSymbol(filePath, name2, kind, line, sig, parent) {
|
|
|
10748
10870
|
lineStart: line,
|
|
10749
10871
|
lineEnd: line,
|
|
10750
10872
|
body: sig ?? "",
|
|
10751
|
-
docstring:
|
|
10873
|
+
docstring: lines2 !== void 0 && style !== void 0 ? precedingDocComment(lines2, line, style) : "",
|
|
10874
|
+
parent: parent ?? ""
|
|
10752
10875
|
};
|
|
10753
10876
|
}
|
|
10754
10877
|
function makeSymbolEmitter(symbols, sections, seen, filePath, maxSymbols = 500, maxHeadingLen = 120) {
|
|
@@ -10765,7 +10888,8 @@ function makeSymbolEmitter(symbols, sections, seen, filePath, maxSymbols = 500,
|
|
|
10765
10888
|
lineStart: line,
|
|
10766
10889
|
lineEnd: line,
|
|
10767
10890
|
body: "",
|
|
10768
|
-
docstring: ""
|
|
10891
|
+
docstring: "",
|
|
10892
|
+
parent: ""
|
|
10769
10893
|
});
|
|
10770
10894
|
sections.push({ heading: name2, level: 1, line, endLine: line });
|
|
10771
10895
|
};
|
|
@@ -10829,6 +10953,7 @@ var init_common = __esm({
|
|
|
10829
10953
|
"use strict";
|
|
10830
10954
|
init_define_import_meta_env();
|
|
10831
10955
|
init_util2();
|
|
10956
|
+
init_doc_comment();
|
|
10832
10957
|
HTML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
10833
10958
|
HTML_SCRIPT_BODY_RE = /(<script\b[^>]*>)([\s\S]*?)(<\/script\s*>)/gi;
|
|
10834
10959
|
HTML_CDATA_RE = /<!\[CDATA\[[\s\S]*?\]\]>/g;
|
|
@@ -11890,19 +12015,19 @@ async function preReadImageHandler(event) {
|
|
|
11890
12015
|
}
|
|
11891
12016
|
const result = await shrinkImage(input, { sizeThresholdBytes: 0 });
|
|
11892
12017
|
if (result === null) return passOutput();
|
|
11893
|
-
const
|
|
12018
|
+
const basename21 = path16.basename(filePath);
|
|
11894
12019
|
if (loadConfig().image_shrink.ocr_enabled) {
|
|
11895
12020
|
const ocr = await ocrImage(result.data);
|
|
11896
12021
|
if (ocr !== null && isTextHeavy(ocr, loadConfig().image_shrink.ocr_min_confidence)) {
|
|
11897
12022
|
const textBytes = Buffer.byteLength(ocr.text, "utf8");
|
|
11898
12023
|
const saved2 = Math.max(0, result.shrunkBytes - textBytes);
|
|
11899
|
-
recordStat("image_ocr", saved2, Math.round(saved2 / 4), void 0,
|
|
11900
|
-
return contextOutput(formatOcrSummary(ocr,
|
|
12024
|
+
recordStat("image_ocr", saved2, Math.round(saved2 / 4), void 0, basename21);
|
|
12025
|
+
return contextOutput(formatOcrSummary(ocr, basename21, result.originalBytes));
|
|
11901
12026
|
}
|
|
11902
12027
|
}
|
|
11903
12028
|
const saved = result.originalBytes - result.shrunkBytes;
|
|
11904
|
-
const { summary, dataUrl } = formatShrinkSummary(result,
|
|
11905
|
-
recordStat("image_shrink", saved, Math.round(saved / 4), void 0,
|
|
12029
|
+
const { summary, dataUrl } = formatShrinkSummary(result, basename21);
|
|
12030
|
+
recordStat("image_shrink", saved, Math.round(saved / 4), void 0, basename21);
|
|
11906
12031
|
return contextOutput(`${summary}
|
|
11907
12032
|
${dataUrl}`);
|
|
11908
12033
|
}
|
|
@@ -12431,8 +12556,8 @@ var init_parser_types = __esm({
|
|
|
12431
12556
|
// src/hooks_read.ts
|
|
12432
12557
|
import * as fs19 from "node:fs";
|
|
12433
12558
|
import * as path20 from "node:path";
|
|
12434
|
-
function isTsConfigFile(
|
|
12435
|
-
const lower =
|
|
12559
|
+
function isTsConfigFile(basename21) {
|
|
12560
|
+
const lower = basename21.toLowerCase();
|
|
12436
12561
|
return /^tsconfig(\..+)?\.json$/i.test(lower) || lower === "jsconfig.json";
|
|
12437
12562
|
}
|
|
12438
12563
|
function largeFileDenyBytes() {
|
|
@@ -12532,18 +12657,18 @@ function describeSliceAdvice(slice, absPath) {
|
|
|
12532
12657
|
}
|
|
12533
12658
|
return "Use Read with offset/limit to sample specific sections.";
|
|
12534
12659
|
}
|
|
12535
|
-
function isSourceExtension(
|
|
12536
|
-
if (SOURCE_EXT_RE.test(
|
|
12537
|
-
const language = detectLanguage(
|
|
12660
|
+
function isSourceExtension(basename21) {
|
|
12661
|
+
if (SOURCE_EXT_RE.test(basename21)) return true;
|
|
12662
|
+
const language = detectLanguage(basename21);
|
|
12538
12663
|
return language === "apex" || language === "salesforce_metadata" || language === "salesforce_markup";
|
|
12539
12664
|
}
|
|
12540
|
-
function isDispatchedFileType(
|
|
12541
|
-
return DISPATCHED_FILE_TYPE_EXTS.has(path20.extname(
|
|
12665
|
+
function isDispatchedFileType(basename21) {
|
|
12666
|
+
return DISPATCHED_FILE_TYPE_EXTS.has(path20.extname(basename21).slice(1).toLowerCase());
|
|
12542
12667
|
}
|
|
12543
|
-
function surgicalHint(filePath,
|
|
12668
|
+
function surgicalHint(filePath, basename21, lineCount) {
|
|
12544
12669
|
if (lineCount < loadConfig().hints.min_file_lines_for_hint) return "";
|
|
12545
|
-
const isDocFile = /\.(md|mdx|rst|txt)$/i.test(
|
|
12546
|
-
const isSectionFile = /\.(json|jsonc|css|scss|sass|less|yaml|yml|toml)$/i.test(
|
|
12670
|
+
const isDocFile = /\.(md|mdx|rst|txt)$/i.test(basename21);
|
|
12671
|
+
const isSectionFile = /\.(json|jsonc|css|scss|sass|less|yaml|yml|toml)$/i.test(basename21);
|
|
12547
12672
|
if (isDocFile) {
|
|
12548
12673
|
return 'Use `token-goat section "' + filePath + '::HeadingName"` to extract a part.';
|
|
12549
12674
|
} else if (isSectionFile) {
|
|
@@ -12591,7 +12716,7 @@ function buildLineDiff(oldContent, newContent, label) {
|
|
|
12591
12716
|
}
|
|
12592
12717
|
return out2.join("\n");
|
|
12593
12718
|
}
|
|
12594
|
-
function loadSnapshotDiff(sessionId, normalized,
|
|
12719
|
+
function loadSnapshotDiff(sessionId, normalized, basename21) {
|
|
12595
12720
|
const oldSnap = load(sessionId, normalized);
|
|
12596
12721
|
if (oldSnap === null) return { kind: "none" };
|
|
12597
12722
|
try {
|
|
@@ -12603,7 +12728,7 @@ function loadSnapshotDiff(sessionId, normalized, basename20) {
|
|
|
12603
12728
|
const truncIdx = oldRaw.indexOf(TRUNC_MARKER);
|
|
12604
12729
|
const oldContent = truncIdx >= 0 ? oldRaw.slice(0, truncIdx) : oldRaw;
|
|
12605
12730
|
if (oldContent === currentContent) return { kind: "unchanged", currentContent };
|
|
12606
|
-
const diff = buildLineDiff(oldContent, currentContent,
|
|
12731
|
+
const diff = buildLineDiff(oldContent, currentContent, basename21);
|
|
12607
12732
|
if (diff === "") return { kind: "none" };
|
|
12608
12733
|
const savedBytes = Math.max(0, currentContent.length - diff.length);
|
|
12609
12734
|
return { kind: "diff", diff, savedBytes, currentContent };
|
|
@@ -12676,8 +12801,8 @@ function preReadHandlerInner(event) {
|
|
|
12676
12801
|
"node_modules is typically noise; use npm ls, npm outdated, or npm audit instead for dependency info. To force access, use: token-goat read node_modules/package/file.js::symbol-name or token-goat section node_modules/package/file.js::heading"
|
|
12677
12802
|
);
|
|
12678
12803
|
}
|
|
12679
|
-
const
|
|
12680
|
-
if (isLockFile(
|
|
12804
|
+
const basename21 = path20.basename(normalized);
|
|
12805
|
+
if (isLockFile(basename21)) {
|
|
12681
12806
|
return denyOutput(
|
|
12682
12807
|
'Lock files are rarely useful to read in full. Use `token-goat section "' + normalized + '::<section>"` to extract a specific dependency, or read the relevant manifest instead.'
|
|
12683
12808
|
);
|
|
@@ -12700,20 +12825,20 @@ function preReadHandlerInner(event) {
|
|
|
12700
12825
|
return quietContextOutput(manifestHint.text);
|
|
12701
12826
|
}
|
|
12702
12827
|
}
|
|
12703
|
-
if (isTsConfigFile(
|
|
12828
|
+
if (isTsConfigFile(basename21) && wasFileReadThisSession(normalized)) {
|
|
12704
12829
|
recordActualRead(event, normalized);
|
|
12705
12830
|
return quietContextOutput(
|
|
12706
|
-
"Already read " +
|
|
12831
|
+
"Already read " + basename21 + '. Use `token-goat section "' + normalized + '::compilerOptions"` to extract compiler options, or `token-goat config-get ' + normalized + " compilerOptions.target` for a single value."
|
|
12707
12832
|
);
|
|
12708
12833
|
}
|
|
12709
|
-
if (isManifestFile(
|
|
12834
|
+
if (isManifestFile(basename21) && wasFileReadThisSession(normalized)) {
|
|
12710
12835
|
recordActualRead(event, normalized);
|
|
12711
12836
|
return quietContextOutput(
|
|
12712
|
-
"You've already read " +
|
|
12837
|
+
"You've already read " + basename21 + '. Use `token-goat section "' + normalized + '::<field>"` or `token-goat config-get ' + normalized + " <key>` to extract just the value you need."
|
|
12713
12838
|
);
|
|
12714
12839
|
}
|
|
12715
12840
|
const skillName = detectSkillFile(normalized);
|
|
12716
|
-
if (skillName &&
|
|
12841
|
+
if (skillName && basename21 === "SKILL.md") {
|
|
12717
12842
|
try {
|
|
12718
12843
|
const body = fs19.readFileSync(normalized, "utf-8");
|
|
12719
12844
|
const bodySha = contentHash(body);
|
|
@@ -12743,7 +12868,7 @@ function preReadHandlerInner(event) {
|
|
|
12743
12868
|
}
|
|
12744
12869
|
}
|
|
12745
12870
|
}
|
|
12746
|
-
const isNotebook = /\.ipynb$/i.test(
|
|
12871
|
+
const isNotebook = /\.ipynb$/i.test(basename21);
|
|
12747
12872
|
if (event.toolName !== "Grep" && isNotebook) {
|
|
12748
12873
|
try {
|
|
12749
12874
|
const rawBytes = fs19.readFileSync(normalized);
|
|
@@ -12760,7 +12885,7 @@ function preReadHandlerInner(event) {
|
|
|
12760
12885
|
} catch {
|
|
12761
12886
|
}
|
|
12762
12887
|
}
|
|
12763
|
-
const isMarkdown = /\.(md|mdx|markdown|rst)$/i.test(
|
|
12888
|
+
const isMarkdown = /\.(md|mdx|markdown|rst)$/i.test(basename21);
|
|
12764
12889
|
if (event.toolName !== "Grep" && isMarkdown) {
|
|
12765
12890
|
let fileContent = null;
|
|
12766
12891
|
let markdownSize = null;
|
|
@@ -12778,9 +12903,9 @@ function preReadHandlerInner(event) {
|
|
|
12778
12903
|
const alreadyRead = wasFileReadThisSession(normalized);
|
|
12779
12904
|
const hintText = formatHeadingTree(headings, normalized);
|
|
12780
12905
|
const headingTextsLower = new Set(headings.map((h) => h.text.trim().toLowerCase()));
|
|
12781
|
-
const wellKnown = getWellKnownSections(
|
|
12906
|
+
const wellKnown = getWellKnownSections(basename21).filter((s) => headingTextsLower.has(s.trim().toLowerCase()));
|
|
12782
12907
|
const wellKnownText = wellKnown.length > 0 ? "\nQuick access: " + wellKnown.map((s) => 'token-goat section "' + normalized + "::" + s + '"').join(" | ") : "";
|
|
12783
|
-
const changelogExtra =
|
|
12908
|
+
const changelogExtra = basename21.toLowerCase() === "changelog.md" ? extractChangelogVersionHint(fileContent, normalized) : "";
|
|
12784
12909
|
let message = hintText + wellKnownText + changelogExtra;
|
|
12785
12910
|
const slice = estimateRequestedSlice(event, normalized);
|
|
12786
12911
|
const gateSize = slice.kind === "bytes" && markdownSize !== null ? Math.min(slice.bytes, markdownSize) : markdownSize;
|
|
@@ -12801,19 +12926,19 @@ function preReadHandlerInner(event) {
|
|
|
12801
12926
|
if (isMemoryMd && wasFileReadThisSession(normalized)) {
|
|
12802
12927
|
recordActualRead(event, normalized);
|
|
12803
12928
|
recordStat("session_hint", 0, 0);
|
|
12804
|
-
const isMainMemory =
|
|
12929
|
+
const isMainMemory = basename21.toLowerCase() === "memory.md";
|
|
12805
12930
|
return denyOutput(
|
|
12806
12931
|
isMainMemory ? "MEMORY.md was read this session. Its content is in the compact manifest as 'session memory'." : normalized + ' was already read this session. Memory files rarely change mid-session. Use `token-goat section "' + normalized + '::SectionHeading"` to extract one section.'
|
|
12807
12932
|
);
|
|
12808
12933
|
}
|
|
12809
|
-
if (/^\.improve-state-.*\.json$/.test(
|
|
12934
|
+
if (/^\.improve-state-.*\.json$/.test(basename21) && wasFileReadThisSession(normalized)) {
|
|
12810
12935
|
recordActualRead(event, normalized);
|
|
12811
12936
|
recordStat("session_hint", 0, 0);
|
|
12812
12937
|
return denyOutput(
|
|
12813
12938
|
"Orchestrator state already read this session. " + sessionArtifactRecall(normalized)
|
|
12814
12939
|
);
|
|
12815
12940
|
}
|
|
12816
|
-
if (/^\.env(\.\w+)?$/.test(
|
|
12941
|
+
if (/^\.env(\.\w+)?$/.test(basename21) && wasFileReadThisSession(normalized)) {
|
|
12817
12942
|
recordActualRead(event, normalized);
|
|
12818
12943
|
recordStat("session_hint", 0, 0);
|
|
12819
12944
|
return denyOutput(
|
|
@@ -12830,19 +12955,19 @@ function preReadHandlerInner(event) {
|
|
|
12830
12955
|
);
|
|
12831
12956
|
}
|
|
12832
12957
|
const artifactSessionId = getSessionId();
|
|
12833
|
-
const snapDiff = loadSnapshotDiff(artifactSessionId, normalized,
|
|
12958
|
+
const snapDiff = loadSnapshotDiff(artifactSessionId, normalized, basename21);
|
|
12834
12959
|
if (snapDiff.kind === "unchanged") {
|
|
12835
12960
|
recordActualRead(event, normalized);
|
|
12836
12961
|
recordStat("session_hint", 0, 0);
|
|
12837
12962
|
return denyOutput(
|
|
12838
|
-
|
|
12963
|
+
basename21 + " is unchanged since last read. " + sessionArtifactRecall(normalized)
|
|
12839
12964
|
);
|
|
12840
12965
|
}
|
|
12841
12966
|
if (snapDiff.kind === "diff") {
|
|
12842
12967
|
recordActualRead(event, normalized);
|
|
12843
12968
|
recordStat("session_hint", snapDiff.savedBytes, Math.round(snapDiff.savedBytes / 4));
|
|
12844
12969
|
return denyOutput(
|
|
12845
|
-
"Content changed since last read of " +
|
|
12970
|
+
"Content changed since last read of " + basename21 + ". Here is what changed:\n\n```diff\n" + snapDiff.diff + "\n```\n\n" + sessionArtifactRecall(normalized)
|
|
12846
12971
|
);
|
|
12847
12972
|
}
|
|
12848
12973
|
recordActualRead(event, normalized);
|
|
@@ -12865,8 +12990,8 @@ function preReadHandlerInner(event) {
|
|
|
12865
12990
|
return quietContextOutput(label + ": " + sessionArtifactRecall(normalized));
|
|
12866
12991
|
}
|
|
12867
12992
|
}
|
|
12868
|
-
const isDocDiffable = /\.(md|mdx|markdown|rst|txt)$/i.test(
|
|
12869
|
-
const isSourceDiffable = loadConfig().hints.serve_diff_on_reread && DIFFABLE_SOURCE_RE.test(
|
|
12993
|
+
const isDocDiffable = /\.(md|mdx|markdown|rst|txt)$/i.test(basename21);
|
|
12994
|
+
const isSourceDiffable = loadConfig().hints.serve_diff_on_reread && DIFFABLE_SOURCE_RE.test(basename21);
|
|
12870
12995
|
if ((isDocDiffable || isSourceDiffable) && wasFileReadThisSession(normalized) && !isProtectedRecentRead(normalized, loadConfig().hints.protect_recent_reads)) {
|
|
12871
12996
|
if (wasFileTruncatedThisSession(normalized)) {
|
|
12872
12997
|
if (estimateTruncatedLineCount(normalized) >= loadConfig().hints.truncated_read_min_lines) {
|
|
@@ -12876,12 +13001,12 @@ function preReadHandlerInner(event) {
|
|
|
12876
13001
|
}
|
|
12877
13002
|
}
|
|
12878
13003
|
const sessionId = getSessionId();
|
|
12879
|
-
const snapDiff = loadSnapshotDiff(sessionId, normalized,
|
|
13004
|
+
const snapDiff = loadSnapshotDiff(sessionId, normalized, basename21);
|
|
12880
13005
|
if (snapDiff.kind === "unchanged") {
|
|
12881
13006
|
recordActualRead(event, normalized);
|
|
12882
13007
|
recordStat("session_hint", 0, 0);
|
|
12883
13008
|
return denyOutput(
|
|
12884
|
-
(
|
|
13009
|
+
(basename21 + " is unchanged since last read. " + surgicalHint(normalized, basename21, countTextLines(snapDiff.currentContent))).trimEnd()
|
|
12885
13010
|
);
|
|
12886
13011
|
}
|
|
12887
13012
|
if (snapDiff.kind === "diff") {
|
|
@@ -12889,7 +13014,7 @@ function preReadHandlerInner(event) {
|
|
|
12889
13014
|
recordActualRead(event, normalized);
|
|
12890
13015
|
recordStat("diff_hint", snapDiff.savedBytes, Math.round(snapDiff.savedBytes / 4));
|
|
12891
13016
|
return denyOutput(
|
|
12892
|
-
("Content changed since last read of " +
|
|
13017
|
+
("Content changed since last read of " + basename21 + ". Here is what changed:\n\n```diff\n" + snapDiff.diff + "\n```\n\n" + surgicalHint(normalized, basename21, countTextLines(snapDiff.currentContent))).trimEnd()
|
|
12893
13018
|
);
|
|
12894
13019
|
}
|
|
12895
13020
|
}
|
|
@@ -12935,13 +13060,13 @@ function preReadHandlerInner(event) {
|
|
|
12935
13060
|
return denyOutput(truncatedReadDenyMessage(normalized));
|
|
12936
13061
|
}
|
|
12937
13062
|
}
|
|
12938
|
-
if (/\.(md|mdx|markdown|rst)$/i.test(
|
|
13063
|
+
if (/\.(md|mdx|markdown|rst)$/i.test(basename21)) {
|
|
12939
13064
|
recordStat("session_hint", rereadBytes, Math.round(rereadBytes / 4));
|
|
12940
13065
|
return denyOutput(
|
|
12941
13066
|
'Markdown file already read this session. Use `token-goat section "' + normalized + '::HeadingName"` to read one section. ' + editAnywayHint(normalized)
|
|
12942
13067
|
);
|
|
12943
13068
|
}
|
|
12944
|
-
const isSourceExt = isSourceExtension(
|
|
13069
|
+
const isSourceExt = isSourceExtension(basename21);
|
|
12945
13070
|
if (isSourceExt && reads >= 2) {
|
|
12946
13071
|
recordStat("read_count_deny", rereadBytes, Math.round(rereadBytes / 4));
|
|
12947
13072
|
recordStat("session_hint", rereadBytes, Math.round(rereadBytes / 4));
|
|
@@ -14610,7 +14735,8 @@ function toSymbolEntry(row) {
|
|
|
14610
14735
|
lineStart: row.line_start,
|
|
14611
14736
|
lineEnd: row.line_end,
|
|
14612
14737
|
body: row.body ?? "",
|
|
14613
|
-
docstring: row.docstring ?? ""
|
|
14738
|
+
docstring: row.docstring ?? "",
|
|
14739
|
+
parent: row.parent ?? ""
|
|
14614
14740
|
};
|
|
14615
14741
|
}
|
|
14616
14742
|
function toRefEntry(row) {
|
|
@@ -14649,7 +14775,7 @@ function buildSymbolWhere(opts) {
|
|
|
14649
14775
|
function querySymbols(opts = {}, dbPath = globalDbPath()) {
|
|
14650
14776
|
const { clause, params } = buildSymbolWhere(opts);
|
|
14651
14777
|
const limit = opts.limit ?? 100;
|
|
14652
|
-
const sql = `SELECT file_path, name, kind, line_start, line_end, body, docstring FROM symbols ${clause} ORDER BY file_path, line_start LIMIT ?`;
|
|
14778
|
+
const sql = `SELECT file_path, name, kind, line_start, line_end, body, docstring, parent FROM symbols ${clause} ORDER BY file_path, line_start LIMIT ?`;
|
|
14653
14779
|
const db = getDb(dbPath);
|
|
14654
14780
|
const rows = db.prepare(sql).all(...params, limit);
|
|
14655
14781
|
return rows.map(toSymbolEntry);
|
|
@@ -14728,7 +14854,7 @@ function sanitizeFtsQuery(query, join46 = "AND") {
|
|
|
14728
14854
|
return terms.join(join46 === "OR" ? " OR " : " ");
|
|
14729
14855
|
}
|
|
14730
14856
|
function runFtsQuery(db, match2, limit, scope, rootDir) {
|
|
14731
|
-
const sql = `SELECT s.file_path, s.name, s.kind, s.line_start, s.line_end, s.body, s.docstring FROM symbols_fts JOIN symbols s ON s.id = symbols_fts.rowid WHERE symbols_fts MATCH ?${scope !== void 0 ? ` AND ${scope.clause}` : ""} ORDER BY bm25(symbols_fts) LIMIT ?`;
|
|
14857
|
+
const sql = `SELECT s.file_path, s.name, s.kind, s.line_start, s.line_end, s.body, s.docstring, s.parent FROM symbols_fts JOIN symbols s ON s.id = symbols_fts.rowid WHERE symbols_fts MATCH ?${scope !== void 0 ? ` AND ${scope.clause}` : ""} ORDER BY bm25(symbols_fts) LIMIT ?`;
|
|
14732
14858
|
const params = [match2];
|
|
14733
14859
|
if (scope !== void 0 && rootDir !== void 0) {
|
|
14734
14860
|
params.push(scope.param(rootDir));
|
|
@@ -14797,12 +14923,12 @@ function extractCsharp(content, filePath) {
|
|
|
14797
14923
|
}
|
|
14798
14924
|
const nsM = NAMESPACE_RE.exec(stripped);
|
|
14799
14925
|
if (nsM) {
|
|
14800
|
-
symbols.push(makeLineSymbol(filePath, nsM[1] ?? "", "namespace", lineNum, stripped.slice(0, 200)));
|
|
14926
|
+
symbols.push(makeLineSymbol(filePath, nsM[1] ?? "", "namespace", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
14801
14927
|
}
|
|
14802
14928
|
const delM = DELEGATE_RE.exec(stripLeadingAttributes(stripped));
|
|
14803
14929
|
if (delM) {
|
|
14804
14930
|
const delegateParent = classStack.length > 0 ? classStack[classStack.length - 1].name : void 0;
|
|
14805
|
-
symbols.push(makeLineSymbol(filePath, delM[1] ?? "", "interface", lineNum, stripped.slice(0, 200), delegateParent));
|
|
14931
|
+
symbols.push(makeLineSymbol(filePath, delM[1] ?? "", "interface", lineNum, stripped.slice(0, 200), delegateParent, lines2, "c"));
|
|
14806
14932
|
}
|
|
14807
14933
|
const cm = CLASS_HEADER_RE.exec(stripLeadingAttributes(stripped));
|
|
14808
14934
|
if (cm) {
|
|
@@ -14810,7 +14936,7 @@ function extractCsharp(content, filePath) {
|
|
|
14810
14936
|
const cname = cm[2] ?? "";
|
|
14811
14937
|
const kind = keyword === "struct" ? "struct" : keyword === "interface" ? "interface" : keyword === "enum" ? "enum" : "class";
|
|
14812
14938
|
const parent = classStack.length > 0 ? classStack[classStack.length - 1].name : void 0;
|
|
14813
|
-
symbols.push(makeLineSymbol(filePath, cname, kind, lineNum, stripped.slice(0, 200), parent));
|
|
14939
|
+
symbols.push(makeLineSymbol(filePath, cname, kind, lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
14814
14940
|
classStack.push({ name: cname, startDepth: braceDepth, bodyEntered: false });
|
|
14815
14941
|
}
|
|
14816
14942
|
const frame = classStack.length > 0 ? classStack[classStack.length - 1] : null;
|
|
@@ -14822,13 +14948,13 @@ function extractCsharp(content, filePath) {
|
|
|
14822
14948
|
if (ctorM && ctorM[1] === frame.name) {
|
|
14823
14949
|
const sigEnd = line.indexOf("{");
|
|
14824
14950
|
const sig = sigEnd >= 0 ? line.slice(0, sigEnd).trimEnd() : line.trimEnd();
|
|
14825
|
-
symbols.push(makeLineSymbol(filePath, frame.name, "method", lineNum, sig.slice(0, 200), frame.name));
|
|
14951
|
+
symbols.push(makeLineSymbol(filePath, frame.name, "method", lineNum, sig.slice(0, 200), frame.name, lines2, "c"));
|
|
14826
14952
|
}
|
|
14827
14953
|
let isPropertyLine = false;
|
|
14828
14954
|
const propM = PROPERTY_RE.exec(lineNoAttr);
|
|
14829
14955
|
if (propM) {
|
|
14830
14956
|
isPropertyLine = true;
|
|
14831
|
-
symbols.push(makeLineSymbol(filePath, propM[1] ?? "", "var", lineNum, stripped.slice(0, 200), frame.name));
|
|
14957
|
+
symbols.push(makeLineSymbol(filePath, propM[1] ?? "", "var", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
14832
14958
|
} else {
|
|
14833
14959
|
const headerM = PROPERTY_HEADER_RE.exec(lineNoAttr);
|
|
14834
14960
|
if (headerM) {
|
|
@@ -14836,13 +14962,13 @@ function extractCsharp(content, filePath) {
|
|
|
14836
14962
|
const accessorLine = (lines2[i + 2] ?? "").trim();
|
|
14837
14963
|
if (braceLineNext === "{" && (ALLMAN_ACCESSOR_RE.test(accessorLine) || ALLMAN_ACCESSOR_BODY_RE.test(accessorLine))) {
|
|
14838
14964
|
isPropertyLine = true;
|
|
14839
|
-
symbols.push(makeLineSymbol(filePath, headerM[1] ?? "", "var", lineNum, stripped.slice(0, 200), frame.name));
|
|
14965
|
+
symbols.push(makeLineSymbol(filePath, headerM[1] ?? "", "var", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
14840
14966
|
}
|
|
14841
14967
|
} else {
|
|
14842
14968
|
const arrowM = PROPERTY_ARROW_RE.exec(lineNoAttr);
|
|
14843
14969
|
if (arrowM) {
|
|
14844
14970
|
isPropertyLine = true;
|
|
14845
|
-
symbols.push(makeLineSymbol(filePath, arrowM[1] ?? "", "var", lineNum, stripped.slice(0, 200), frame.name));
|
|
14971
|
+
symbols.push(makeLineSymbol(filePath, arrowM[1] ?? "", "var", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
14846
14972
|
}
|
|
14847
14973
|
}
|
|
14848
14974
|
}
|
|
@@ -14852,7 +14978,7 @@ function extractCsharp(content, filePath) {
|
|
|
14852
14978
|
if (mname && mname !== frame.name) {
|
|
14853
14979
|
const sigEnd = line.indexOf("{");
|
|
14854
14980
|
const sig = sigEnd >= 0 ? line.slice(0, sigEnd).trimEnd() : line.trimEnd();
|
|
14855
|
-
symbols.push(makeLineSymbol(filePath, mname, "method", lineNum, sig.slice(0, 200), frame.name));
|
|
14981
|
+
symbols.push(makeLineSymbol(filePath, mname, "method", lineNum, sig.slice(0, 200), frame.name, lines2, "c"));
|
|
14856
14982
|
}
|
|
14857
14983
|
}
|
|
14858
14984
|
}
|
|
@@ -14957,7 +15083,7 @@ function extractPhp(content, filePath) {
|
|
|
14957
15083
|
}
|
|
14958
15084
|
const nsM = NAMESPACE_RE2.exec(stripped);
|
|
14959
15085
|
if (nsM) {
|
|
14960
|
-
symbols.push(makeLineSymbol(filePath, nsM[1] ?? "", "namespace", lineNum, stripped.slice(0, 200)));
|
|
15086
|
+
symbols.push(makeLineSymbol(filePath, nsM[1] ?? "", "namespace", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
14961
15087
|
continue;
|
|
14962
15088
|
}
|
|
14963
15089
|
if (contextStack.length === 0) {
|
|
@@ -14991,7 +15117,7 @@ function extractPhp(content, filePath) {
|
|
|
14991
15117
|
const preLineDepth = braceDepth - openB + closeB;
|
|
14992
15118
|
const topFrame2 = contextStack.length > 0 ? contextStack[contextStack.length - 1] : void 0;
|
|
14993
15119
|
const parent = topFrame2 !== void 0 && preLineDepth === topFrame2[1] + 1 ? topFrame2[0] : null;
|
|
14994
|
-
symbols.push(makeLineSymbol(filePath, name2, kind, lineNum, stripped.slice(0, 200), parent ?? void 0));
|
|
15120
|
+
symbols.push(makeLineSymbol(filePath, name2, kind, lineNum, stripped.slice(0, 200), parent ?? void 0, lines2, "c"));
|
|
14995
15121
|
contextStack.push([name2, braceDepth - openB + closeB, false]);
|
|
14996
15122
|
if (openB > 0 && openB === closeB) {
|
|
14997
15123
|
contextStack.pop();
|
|
@@ -15008,7 +15134,7 @@ function extractPhp(content, filePath) {
|
|
|
15008
15134
|
const kind = parent ? "method" : "function";
|
|
15009
15135
|
const sigEnd = stripped.indexOf(")");
|
|
15010
15136
|
const sig = sigEnd >= 0 ? stripped.slice(0, sigEnd + 1) : stripped;
|
|
15011
|
-
symbols.push(makeLineSymbol(filePath, name2, kind, lineNum, sig.slice(0, 200), parent ?? void 0));
|
|
15137
|
+
symbols.push(makeLineSymbol(filePath, name2, kind, lineNum, sig.slice(0, 200), parent ?? void 0, lines2, "c"));
|
|
15012
15138
|
continue;
|
|
15013
15139
|
}
|
|
15014
15140
|
const propM = PROP_RE.exec(stripped);
|
|
@@ -15017,7 +15143,7 @@ function extractPhp(content, filePath) {
|
|
|
15017
15143
|
const preLineDepth = braceDepth - openB + closeB;
|
|
15018
15144
|
const topFrame2 = contextStack.length > 0 ? contextStack[contextStack.length - 1] : void 0;
|
|
15019
15145
|
if (topFrame2 !== void 0 && preLineDepth === topFrame2[1] + 1) {
|
|
15020
|
-
symbols.push(makeLineSymbol(filePath, name2, "var", lineNum, stripped.slice(0, 200), topFrame2[0]));
|
|
15146
|
+
symbols.push(makeLineSymbol(filePath, name2, "var", lineNum, stripped.slice(0, 200), topFrame2[0], lines2, "c"));
|
|
15021
15147
|
}
|
|
15022
15148
|
continue;
|
|
15023
15149
|
}
|
|
@@ -15027,12 +15153,12 @@ function extractPhp(content, filePath) {
|
|
|
15027
15153
|
const preLineDepth = braceDepth - openB + closeB;
|
|
15028
15154
|
const topFrame2 = contextStack.length > 0 ? contextStack[contextStack.length - 1] : void 0;
|
|
15029
15155
|
const parent = topFrame2 !== void 0 && preLineDepth === topFrame2[1] + 1 ? topFrame2[0] : void 0;
|
|
15030
|
-
symbols.push(makeLineSymbol(filePath, name2, "const", lineNum, stripped.slice(0, 200), parent));
|
|
15156
|
+
symbols.push(makeLineSymbol(filePath, name2, "const", lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15031
15157
|
continue;
|
|
15032
15158
|
}
|
|
15033
15159
|
const defineM = DEFINE_RE.exec(stripped);
|
|
15034
15160
|
if (defineM) {
|
|
15035
|
-
symbols.push(makeLineSymbol(filePath, defineM[1] ?? "", "const", lineNum, stripped.slice(0, 200)));
|
|
15161
|
+
symbols.push(makeLineSymbol(filePath, defineM[1] ?? "", "const", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
15036
15162
|
}
|
|
15037
15163
|
}
|
|
15038
15164
|
return { symbols, imports };
|
|
@@ -15097,7 +15223,7 @@ function extractHtml(content, filePath) {
|
|
|
15097
15223
|
const key = `${idVal}\0${line}`;
|
|
15098
15224
|
if (!seenId.has(key)) {
|
|
15099
15225
|
seenId.add(key);
|
|
15100
|
-
symbols.push({ filePath, name: idVal, kind: "html_id", lineStart: line, lineEnd: line, body: "", docstring: "" });
|
|
15226
|
+
symbols.push({ filePath, name: idVal, kind: "html_id", lineStart: line, lineEnd: line, body: "", docstring: "", parent: "" });
|
|
15101
15227
|
}
|
|
15102
15228
|
}
|
|
15103
15229
|
}
|
|
@@ -15112,7 +15238,7 @@ function extractHtml(content, filePath) {
|
|
|
15112
15238
|
const key = `${cls}\0${line}`;
|
|
15113
15239
|
if (!seenClass.has(key)) {
|
|
15114
15240
|
seenClass.add(key);
|
|
15115
|
-
symbols.push({ filePath, name: cls, kind: "html_class", lineStart: line, lineEnd: line, body: "", docstring: "" });
|
|
15241
|
+
symbols.push({ filePath, name: cls, kind: "html_class", lineStart: line, lineEnd: line, body: "", docstring: "", parent: "" });
|
|
15116
15242
|
}
|
|
15117
15243
|
}
|
|
15118
15244
|
}
|
|
@@ -15215,7 +15341,7 @@ function extractLiquid(content, filePath, relPath) {
|
|
|
15215
15341
|
if (name2) {
|
|
15216
15342
|
const line = offsetToLine(lineIndex, m.index ?? 0);
|
|
15217
15343
|
const endLine = offsetToLine(lineIndex, (m.index ?? 0) + (m[0]?.length ?? 0));
|
|
15218
|
-
symbols.push({ filePath, name: name2, kind: "liquid_schema", lineStart: line, lineEnd: endLine, body: "", docstring: "" });
|
|
15344
|
+
symbols.push({ filePath, name: name2, kind: "liquid_schema", lineStart: line, lineEnd: endLine, body: "", docstring: "", parent: "" });
|
|
15219
15345
|
}
|
|
15220
15346
|
}
|
|
15221
15347
|
} catch {
|
|
@@ -15225,7 +15351,7 @@ function extractLiquid(content, filePath, relPath) {
|
|
|
15225
15351
|
const relPosix = resolvedRel.replace(/\\/g, "/");
|
|
15226
15352
|
if (relPosix.startsWith("sections/") || relPosix.includes("/sections/")) {
|
|
15227
15353
|
const stem = path22.basename(resolvedRel, path22.extname(resolvedRel));
|
|
15228
|
-
symbols.push({ filePath, name: stem, kind: "liquid_section_file", lineStart: 1, lineEnd: 1, body: "", docstring: "" });
|
|
15354
|
+
symbols.push({ filePath, name: stem, kind: "liquid_section_file", lineStart: 1, lineEnd: 1, body: "", docstring: "", parent: "" });
|
|
15229
15355
|
}
|
|
15230
15356
|
const totalLines = content.split("\n").length;
|
|
15231
15357
|
for (const hm of findHtmlHeadingMatches(content)) {
|
|
@@ -15316,14 +15442,14 @@ function extractKotlin(content, filePath) {
|
|
|
15316
15442
|
if (companionM) {
|
|
15317
15443
|
const cname = companionM[1] ?? "Companion";
|
|
15318
15444
|
const parent = classStack.length > 0 ? classStack[classStack.length - 1].name : void 0;
|
|
15319
|
-
symbols.push(makeLineSymbol(filePath, cname, "object", lineNum, line.trimEnd().slice(0, 200), parent));
|
|
15445
|
+
symbols.push(makeLineSymbol(filePath, cname, "object", lineNum, line.trimEnd().slice(0, 200), parent, lines2, "c"));
|
|
15320
15446
|
classStack.push({ name: cname, braceDepth, bodyEntered: false, parenBalance: 0, pendingPop: false });
|
|
15321
15447
|
} else if (cm) {
|
|
15322
15448
|
const ckeyword = cm[1] ?? "class";
|
|
15323
15449
|
const cname = cm[2] ?? "";
|
|
15324
15450
|
const ckind = ckeyword === "interface" ? "interface" : ckeyword === "object" ? "object" : "class";
|
|
15325
15451
|
const parent = classStack.length > 0 ? classStack[classStack.length - 1].name : void 0;
|
|
15326
|
-
symbols.push(makeLineSymbol(filePath, cname, ckind, lineNum, line.trimEnd().slice(0, 200), parent));
|
|
15452
|
+
symbols.push(makeLineSymbol(filePath, cname, ckind, lineNum, line.trimEnd().slice(0, 200), parent, lines2, "c"));
|
|
15327
15453
|
classStack.push({ name: cname, braceDepth, bodyEntered: false, parenBalance: 0, pendingPop: false });
|
|
15328
15454
|
}
|
|
15329
15455
|
const frame = classStack.length > 0 ? classStack[classStack.length - 1] : null;
|
|
@@ -15336,11 +15462,11 @@ function extractKotlin(content, filePath) {
|
|
|
15336
15462
|
const fname = fm[1] ?? "";
|
|
15337
15463
|
const sigEnd = line.indexOf("{");
|
|
15338
15464
|
const sig = sigEnd >= 0 ? line.slice(0, sigEnd).trim() : line.trimEnd();
|
|
15339
|
-
symbols.push(makeLineSymbol(filePath, fname, "method", lineNum, sig.slice(0, 200), frame.name));
|
|
15465
|
+
symbols.push(makeLineSymbol(filePath, fname, "method", lineNum, sig.slice(0, 200), frame.name, lines2, "c"));
|
|
15340
15466
|
}
|
|
15341
15467
|
const constM = CONST_RE2.exec(lineNoAnn);
|
|
15342
15468
|
if (constM) {
|
|
15343
|
-
symbols.push(makeLineSymbol(filePath, constM[1] ?? "", "const", lineNum, stripped.slice(0, 200), frame.name));
|
|
15469
|
+
symbols.push(makeLineSymbol(filePath, constM[1] ?? "", "const", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
15344
15470
|
}
|
|
15345
15471
|
}
|
|
15346
15472
|
} else if (!isIndented) {
|
|
@@ -15350,11 +15476,11 @@ function extractKotlin(content, filePath) {
|
|
|
15350
15476
|
const fname = tfm[1] ?? "";
|
|
15351
15477
|
const sigEnd = line.indexOf("{");
|
|
15352
15478
|
const sig = sigEnd >= 0 ? line.slice(0, sigEnd).trim() : line.trimEnd();
|
|
15353
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, sig.slice(0, 200)));
|
|
15479
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, sig.slice(0, 200), void 0, lines2, "c"));
|
|
15354
15480
|
}
|
|
15355
15481
|
const topConstM = CONST_RE2.exec(lineNoAnn);
|
|
15356
15482
|
if (topConstM) {
|
|
15357
|
-
symbols.push(makeLineSymbol(filePath, topConstM[1] ?? "", "const", lineNum, stripped.slice(0, 200)));
|
|
15483
|
+
symbols.push(makeLineSymbol(filePath, topConstM[1] ?? "", "const", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
15358
15484
|
}
|
|
15359
15485
|
}
|
|
15360
15486
|
const braceLine = stripStringLiterals(line);
|
|
@@ -15458,7 +15584,7 @@ function extractSwift(content, filePath) {
|
|
|
15458
15584
|
const tname = tm[2] ?? "";
|
|
15459
15585
|
const kind = keyword === "struct" ? "struct" : keyword === "enum" ? "enum" : keyword === "protocol" ? "protocol" : keyword === "extension" ? "extension" : keyword === "actor" ? "actor" : "class";
|
|
15460
15586
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
15461
|
-
symbols.push(makeLineSymbol(filePath, tname, kind, lineNum, stripped.slice(0, 200), parent));
|
|
15587
|
+
symbols.push(makeLineSymbol(filePath, tname, kind, lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15462
15588
|
typeStack.push({ name: tname, startDepth: braceDepth, bodyEntered: false });
|
|
15463
15589
|
}
|
|
15464
15590
|
const frame = typeStack.length > 0 ? typeStack[typeStack.length - 1] : null;
|
|
@@ -15471,17 +15597,17 @@ function extractSwift(content, filePath) {
|
|
|
15471
15597
|
const subscriptM = SUBSCRIPT_RE.exec(lineNoAttr);
|
|
15472
15598
|
const fm = FUNC_RE.exec(lineNoAttr);
|
|
15473
15599
|
if (initM) {
|
|
15474
|
-
symbols.push(makeLineSymbol(filePath, initM[1] ?? "init", "method", lineNum, stripped.slice(0, 200), frame.name));
|
|
15600
|
+
symbols.push(makeLineSymbol(filePath, initM[1] ?? "init", "method", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
15475
15601
|
} else if (deinitM) {
|
|
15476
|
-
symbols.push(makeLineSymbol(filePath, "deinit", "method", lineNum, stripped.slice(0, 200), frame.name));
|
|
15602
|
+
symbols.push(makeLineSymbol(filePath, "deinit", "method", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
15477
15603
|
} else if (subscriptM) {
|
|
15478
|
-
symbols.push(makeLineSymbol(filePath, subscriptM[1] ?? "subscript", "method", lineNum, stripped.slice(0, 200), frame.name));
|
|
15604
|
+
symbols.push(makeLineSymbol(filePath, subscriptM[1] ?? "subscript", "method", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
15479
15605
|
} else if (fm) {
|
|
15480
|
-
symbols.push(makeLineSymbol(filePath, fm[1] ?? "", "method", lineNum, stripped.slice(0, 200), frame.name));
|
|
15606
|
+
symbols.push(makeLineSymbol(filePath, fm[1] ?? "", "method", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
15481
15607
|
} else {
|
|
15482
15608
|
const propM = PROPERTY_RE2.exec(lineNoAttr);
|
|
15483
15609
|
if (propM) {
|
|
15484
|
-
symbols.push(makeLineSymbol(filePath, propM[1] ?? "", "var", lineNum, stripped.slice(0, 200), frame.name));
|
|
15610
|
+
symbols.push(makeLineSymbol(filePath, propM[1] ?? "", "var", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
15485
15611
|
}
|
|
15486
15612
|
}
|
|
15487
15613
|
}
|
|
@@ -15489,7 +15615,7 @@ function extractSwift(content, filePath) {
|
|
|
15489
15615
|
const lineNoAttr = stripLeadingAttributes2(line);
|
|
15490
15616
|
const fm = FUNC_RE.exec(lineNoAttr);
|
|
15491
15617
|
if (fm) {
|
|
15492
|
-
symbols.push(makeLineSymbol(filePath, fm[1] ?? "", "function", lineNum, stripped.slice(0, 200)));
|
|
15618
|
+
symbols.push(makeLineSymbol(filePath, fm[1] ?? "", "function", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
15493
15619
|
}
|
|
15494
15620
|
}
|
|
15495
15621
|
const braceLine = stripStringLiterals(line);
|
|
@@ -15586,7 +15712,7 @@ function extractScala(content, filePath) {
|
|
|
15586
15712
|
if (cm) {
|
|
15587
15713
|
const cname = cm[1] ?? "";
|
|
15588
15714
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
15589
|
-
symbols.push(makeLineSymbol(filePath, cname, "class", lineNum, stripped.slice(0, 200), parent));
|
|
15715
|
+
symbols.push(makeLineSymbol(filePath, cname, "class", lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15590
15716
|
typeStack.push({ name: cname, startDepth: braceDepth, bodyEntered: false });
|
|
15591
15717
|
if (/\bcase\s+class\b/.test(stripped) && !stripStringLiterals(line).includes("{")) {
|
|
15592
15718
|
typeStack.pop();
|
|
@@ -15597,7 +15723,7 @@ function extractScala(content, filePath) {
|
|
|
15597
15723
|
if (om) {
|
|
15598
15724
|
const oname = om[1] ?? "";
|
|
15599
15725
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
15600
|
-
symbols.push(makeLineSymbol(filePath, oname, "object", lineNum, stripped.slice(0, 200), parent));
|
|
15726
|
+
symbols.push(makeLineSymbol(filePath, oname, "object", lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15601
15727
|
typeStack.push({ name: oname, startDepth: braceDepth, bodyEntered: false });
|
|
15602
15728
|
if (/\bcase\s+object\b/.test(stripped) && !stripStringLiterals(line).includes("{")) {
|
|
15603
15729
|
typeStack.pop();
|
|
@@ -15608,7 +15734,7 @@ function extractScala(content, filePath) {
|
|
|
15608
15734
|
if (tm) {
|
|
15609
15735
|
const tname = tm[1] ?? "";
|
|
15610
15736
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
15611
|
-
symbols.push(makeLineSymbol(filePath, tname, "trait", lineNum, stripped.slice(0, 200), parent));
|
|
15737
|
+
symbols.push(makeLineSymbol(filePath, tname, "trait", lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15612
15738
|
typeStack.push({ name: tname, startDepth: braceDepth, bodyEntered: false });
|
|
15613
15739
|
matched = true;
|
|
15614
15740
|
}
|
|
@@ -15616,7 +15742,7 @@ function extractScala(content, filePath) {
|
|
|
15616
15742
|
if (enm) {
|
|
15617
15743
|
const enname = enm[1] ?? "";
|
|
15618
15744
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
15619
|
-
symbols.push(makeLineSymbol(filePath, enname, "enum", lineNum, stripped.slice(0, 200), parent));
|
|
15745
|
+
symbols.push(makeLineSymbol(filePath, enname, "enum", lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15620
15746
|
typeStack.push({ name: enname, startDepth: braceDepth, bodyEntered: false });
|
|
15621
15747
|
matched = true;
|
|
15622
15748
|
}
|
|
@@ -15626,36 +15752,36 @@ function extractScala(content, filePath) {
|
|
|
15626
15752
|
if (depthInType === 1) {
|
|
15627
15753
|
const fm = FUNC_RE2.exec(stripped);
|
|
15628
15754
|
if (fm) {
|
|
15629
|
-
symbols.push(makeLineSymbol(filePath, fm[1] ?? "", "function", lineNum, stripped.slice(0, 200), frame.name));
|
|
15755
|
+
symbols.push(makeLineSymbol(filePath, fm[1] ?? "", "function", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
15630
15756
|
matched = true;
|
|
15631
15757
|
}
|
|
15632
15758
|
const vm = !matched ? VAL_RE.exec(stripped) : null;
|
|
15633
15759
|
if (vm) {
|
|
15634
|
-
symbols.push(makeLineSymbol(filePath, vm[1] ?? "", "val", lineNum, stripped.slice(0, 200), frame.name));
|
|
15760
|
+
symbols.push(makeLineSymbol(filePath, vm[1] ?? "", "val", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
15635
15761
|
matched = true;
|
|
15636
15762
|
}
|
|
15637
15763
|
if (!matched) {
|
|
15638
15764
|
const varm = VAR_RE.exec(stripped);
|
|
15639
15765
|
if (varm) {
|
|
15640
|
-
symbols.push(makeLineSymbol(filePath, varm[1] ?? "", "var", lineNum, stripped.slice(0, 200), frame.name));
|
|
15766
|
+
symbols.push(makeLineSymbol(filePath, varm[1] ?? "", "var", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
15641
15767
|
}
|
|
15642
15768
|
}
|
|
15643
15769
|
}
|
|
15644
15770
|
} else if (!matched && frame === null && !isIndented) {
|
|
15645
15771
|
const fm = FUNC_RE2.exec(stripped);
|
|
15646
15772
|
if (fm) {
|
|
15647
|
-
symbols.push(makeLineSymbol(filePath, fm[1] ?? "", "function", lineNum, stripped.slice(0, 200)));
|
|
15773
|
+
symbols.push(makeLineSymbol(filePath, fm[1] ?? "", "function", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
15648
15774
|
matched = true;
|
|
15649
15775
|
}
|
|
15650
15776
|
const vm = !matched ? VAL_RE.exec(stripped) : null;
|
|
15651
15777
|
if (vm) {
|
|
15652
|
-
symbols.push(makeLineSymbol(filePath, vm[1] ?? "", "val", lineNum, stripped.slice(0, 200)));
|
|
15778
|
+
symbols.push(makeLineSymbol(filePath, vm[1] ?? "", "val", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
15653
15779
|
matched = true;
|
|
15654
15780
|
}
|
|
15655
15781
|
if (!matched) {
|
|
15656
15782
|
const varm = VAR_RE.exec(stripped);
|
|
15657
15783
|
if (varm) {
|
|
15658
|
-
symbols.push(makeLineSymbol(filePath, varm[1] ?? "", "var", lineNum, stripped.slice(0, 200)));
|
|
15784
|
+
symbols.push(makeLineSymbol(filePath, varm[1] ?? "", "var", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
15659
15785
|
}
|
|
15660
15786
|
}
|
|
15661
15787
|
}
|
|
@@ -15834,14 +15960,14 @@ function extractElixir(content, filePath) {
|
|
|
15834
15960
|
const modM = MODULE_RE.exec(stripped);
|
|
15835
15961
|
if (modM) {
|
|
15836
15962
|
const modName = modM[1] ?? "";
|
|
15837
|
-
symbols.push(makeLineSymbol(filePath, modName, "class", lineNum, stripped.slice(0, 200)));
|
|
15963
|
+
symbols.push(makeLineSymbol(filePath, modName, "class", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
15838
15964
|
moduleStack.push({ name: modName, endKeywordNeeded: true, isBlock: false });
|
|
15839
15965
|
continue;
|
|
15840
15966
|
}
|
|
15841
15967
|
const protoM = PROTOCOL_RE.exec(stripped);
|
|
15842
15968
|
if (protoM) {
|
|
15843
15969
|
const protoName = protoM[1] ?? "";
|
|
15844
|
-
symbols.push(makeLineSymbol(filePath, protoName, "protocol", lineNum, stripped.slice(0, 200)));
|
|
15970
|
+
symbols.push(makeLineSymbol(filePath, protoName, "protocol", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
15845
15971
|
moduleStack.push({ name: protoName, endKeywordNeeded: true, isBlock: false });
|
|
15846
15972
|
continue;
|
|
15847
15973
|
}
|
|
@@ -15850,9 +15976,9 @@ function extractElixir(content, filePath) {
|
|
|
15850
15976
|
const fname = fm[1] ?? "";
|
|
15851
15977
|
const parent = nearestDefName(moduleStack);
|
|
15852
15978
|
if (parent !== void 0) {
|
|
15853
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), parent));
|
|
15979
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), parent, lines2, "hash"));
|
|
15854
15980
|
} else {
|
|
15855
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200)));
|
|
15981
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
15856
15982
|
}
|
|
15857
15983
|
if (opensDoBlock) {
|
|
15858
15984
|
moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false });
|
|
@@ -15864,9 +15990,9 @@ function extractElixir(content, filePath) {
|
|
|
15864
15990
|
const fname = pfm[1] ?? "";
|
|
15865
15991
|
const parent = nearestDefName(moduleStack);
|
|
15866
15992
|
if (parent !== void 0) {
|
|
15867
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), parent));
|
|
15993
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), parent, lines2, "hash"));
|
|
15868
15994
|
} else {
|
|
15869
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200)));
|
|
15995
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
15870
15996
|
}
|
|
15871
15997
|
if (opensDoBlock) {
|
|
15872
15998
|
moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false });
|
|
@@ -15876,7 +16002,7 @@ function extractElixir(content, filePath) {
|
|
|
15876
16002
|
if (STRUCT_RE.test(stripped)) {
|
|
15877
16003
|
const parent = nearestDefName(moduleStack);
|
|
15878
16004
|
if (parent !== void 0) {
|
|
15879
|
-
symbols.push(makeLineSymbol(filePath, "__struct__", "var", lineNum, stripped.slice(0, 200), parent));
|
|
16005
|
+
symbols.push(makeLineSymbol(filePath, "__struct__", "var", lineNum, stripped.slice(0, 200), parent, lines2, "hash"));
|
|
15880
16006
|
}
|
|
15881
16007
|
continue;
|
|
15882
16008
|
}
|
|
@@ -15936,7 +16062,7 @@ function extractDart(content, filePath) {
|
|
|
15936
16062
|
if (cm) {
|
|
15937
16063
|
const cname = cm[1] ?? "";
|
|
15938
16064
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
15939
|
-
symbols.push(makeLineSymbol(filePath, cname, "class", lineNum, stripped.slice(0, 200), parent));
|
|
16065
|
+
symbols.push(makeLineSymbol(filePath, cname, "class", lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15940
16066
|
typeStack.push({ name: cname, startDepth: braceDepth, bodyEntered: false });
|
|
15941
16067
|
matched = true;
|
|
15942
16068
|
}
|
|
@@ -15944,7 +16070,7 @@ function extractDart(content, filePath) {
|
|
|
15944
16070
|
if (em) {
|
|
15945
16071
|
const ename = em[1] ?? "";
|
|
15946
16072
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
15947
|
-
symbols.push(makeLineSymbol(filePath, ename, "enum", lineNum, stripped.slice(0, 200), parent));
|
|
16073
|
+
symbols.push(makeLineSymbol(filePath, ename, "enum", lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15948
16074
|
typeStack.push({ name: ename, startDepth: braceDepth, bodyEntered: false });
|
|
15949
16075
|
matched = true;
|
|
15950
16076
|
}
|
|
@@ -15952,7 +16078,7 @@ function extractDart(content, filePath) {
|
|
|
15952
16078
|
if (mm) {
|
|
15953
16079
|
const mname = mm[1] ?? "";
|
|
15954
16080
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
15955
|
-
symbols.push(makeLineSymbol(filePath, mname, "mixin", lineNum, stripped.slice(0, 200), parent));
|
|
16081
|
+
symbols.push(makeLineSymbol(filePath, mname, "mixin", lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15956
16082
|
typeStack.push({ name: mname, startDepth: braceDepth, bodyEntered: false });
|
|
15957
16083
|
matched = true;
|
|
15958
16084
|
}
|
|
@@ -15960,7 +16086,7 @@ function extractDart(content, filePath) {
|
|
|
15960
16086
|
if (etm) {
|
|
15961
16087
|
const etname = etm[1] ?? "";
|
|
15962
16088
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
15963
|
-
symbols.push(makeLineSymbol(filePath, etname, "extension_type", lineNum, stripped.slice(0, 200), parent));
|
|
16089
|
+
symbols.push(makeLineSymbol(filePath, etname, "extension_type", lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15964
16090
|
typeStack.push({ name: etname, startDepth: braceDepth, bodyEntered: false });
|
|
15965
16091
|
matched = true;
|
|
15966
16092
|
}
|
|
@@ -15968,7 +16094,7 @@ function extractDart(content, filePath) {
|
|
|
15968
16094
|
if (extm) {
|
|
15969
16095
|
const extname14 = extm[1] ?? "extension";
|
|
15970
16096
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
15971
|
-
symbols.push(makeLineSymbol(filePath, extname14, "extension", lineNum, stripped.slice(0, 200), parent));
|
|
16097
|
+
symbols.push(makeLineSymbol(filePath, extname14, "extension", lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
15972
16098
|
typeStack.push({ name: extname14, startDepth: braceDepth, bodyEntered: false });
|
|
15973
16099
|
matched = true;
|
|
15974
16100
|
}
|
|
@@ -15981,7 +16107,7 @@ function extractDart(content, filePath) {
|
|
|
15981
16107
|
if (fm) {
|
|
15982
16108
|
let fname = fm[1] ?? "";
|
|
15983
16109
|
fname = fname.replace(/^operator\s+/, "");
|
|
15984
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), frame.name));
|
|
16110
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
15985
16111
|
}
|
|
15986
16112
|
}
|
|
15987
16113
|
} else if (!matched && frame === null && !isIndented) {
|
|
@@ -15989,7 +16115,7 @@ function extractDart(content, filePath) {
|
|
|
15989
16115
|
if (fm) {
|
|
15990
16116
|
let fname = fm[1] ?? "";
|
|
15991
16117
|
fname = fname.replace(/^operator\s+/, "");
|
|
15992
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200)));
|
|
16118
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
15993
16119
|
}
|
|
15994
16120
|
}
|
|
15995
16121
|
const braceLine = stripStringLiterals(line);
|
|
@@ -16061,7 +16187,7 @@ function extractZig(content, filePath) {
|
|
|
16061
16187
|
const skind = sm[2] ?? "struct";
|
|
16062
16188
|
if (sname) {
|
|
16063
16189
|
const parent = outerFrame !== null ? outerFrame.name : void 0;
|
|
16064
|
-
symbols.push(makeLineSymbol(filePath, sname, skind, lineNum, stripped.slice(0, 200), parent));
|
|
16190
|
+
symbols.push(makeLineSymbol(filePath, sname, skind, lineNum, stripped.slice(0, 200), parent, lines2, "c"));
|
|
16065
16191
|
scopeStack.push({ name: sname, startDepth: braceDepth, bodyEntered: false });
|
|
16066
16192
|
matched = true;
|
|
16067
16193
|
}
|
|
@@ -16072,7 +16198,7 @@ function extractZig(content, filePath) {
|
|
|
16072
16198
|
const fm = FUNC_RE6.exec(stripped);
|
|
16073
16199
|
if (fm) {
|
|
16074
16200
|
const fname = fm[2] ?? "";
|
|
16075
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200)));
|
|
16201
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
16076
16202
|
matched = true;
|
|
16077
16203
|
}
|
|
16078
16204
|
} else if (!matched && frame !== null) {
|
|
@@ -16081,7 +16207,7 @@ function extractZig(content, filePath) {
|
|
|
16081
16207
|
const fm = FUNC_RE6.exec(stripped);
|
|
16082
16208
|
if (fm) {
|
|
16083
16209
|
const fname = fm[2] ?? "";
|
|
16084
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), frame.name));
|
|
16210
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), frame.name, lines2, "c"));
|
|
16085
16211
|
matched = true;
|
|
16086
16212
|
}
|
|
16087
16213
|
}
|
|
@@ -16089,13 +16215,13 @@ function extractZig(content, filePath) {
|
|
|
16089
16215
|
if (!matched && !isIndented) {
|
|
16090
16216
|
const cm = CONST_RE3.exec(stripped);
|
|
16091
16217
|
if (cm) {
|
|
16092
|
-
symbols.push(makeLineSymbol(filePath, cm[1] ?? "", "const", lineNum, stripped.slice(0, 200)));
|
|
16218
|
+
symbols.push(makeLineSymbol(filePath, cm[1] ?? "", "const", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
16093
16219
|
matched = true;
|
|
16094
16220
|
}
|
|
16095
16221
|
if (!matched) {
|
|
16096
16222
|
const vm = VAR_RE2.exec(stripped);
|
|
16097
16223
|
if (vm) {
|
|
16098
|
-
symbols.push(makeLineSymbol(filePath, vm[1] ?? "", "var", lineNum, stripped.slice(0, 200)));
|
|
16224
|
+
symbols.push(makeLineSymbol(filePath, vm[1] ?? "", "var", lineNum, stripped.slice(0, 200), void 0, lines2, "c"));
|
|
16099
16225
|
}
|
|
16100
16226
|
}
|
|
16101
16227
|
}
|
|
@@ -16154,17 +16280,17 @@ function extractR(content, filePath) {
|
|
|
16154
16280
|
if (!isIndented) {
|
|
16155
16281
|
const fm = FUNC_ASSIGN_RE.exec(stripped);
|
|
16156
16282
|
if (fm) {
|
|
16157
|
-
symbols.push(makeLineSymbol(filePath, fm[1] ?? "", "function", lineNum, stripped.slice(0, 200)));
|
|
16283
|
+
symbols.push(makeLineSymbol(filePath, fm[1] ?? "", "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
16158
16284
|
continue;
|
|
16159
16285
|
}
|
|
16160
16286
|
const cm = SETCLASS_RE.exec(stripped);
|
|
16161
16287
|
if (cm) {
|
|
16162
|
-
symbols.push(makeLineSymbol(filePath, cm[1] ?? "", "class", lineNum, stripped.slice(0, 200)));
|
|
16288
|
+
symbols.push(makeLineSymbol(filePath, cm[1] ?? "", "class", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
16163
16289
|
continue;
|
|
16164
16290
|
}
|
|
16165
16291
|
const mm = SETMETHOD_RE.exec(stripped);
|
|
16166
16292
|
if (mm) {
|
|
16167
|
-
symbols.push(makeLineSymbol(filePath, mm[1] ?? "", "function", lineNum, stripped.slice(0, 200)));
|
|
16293
|
+
symbols.push(makeLineSymbol(filePath, mm[1] ?? "", "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
16168
16294
|
}
|
|
16169
16295
|
}
|
|
16170
16296
|
}
|
|
@@ -16698,7 +16824,7 @@ function extractBash(content, filePath) {
|
|
|
16698
16824
|
if (funcMatch) {
|
|
16699
16825
|
const fname = funcMatch[1] ?? "";
|
|
16700
16826
|
if (fname && symbols.length < MAX_SYMBOLS4) {
|
|
16701
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200)));
|
|
16827
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
16702
16828
|
}
|
|
16703
16829
|
if (fname) {
|
|
16704
16830
|
if (stripped.includes("{")) {
|
|
@@ -16719,7 +16845,7 @@ function extractBash(content, filePath) {
|
|
|
16719
16845
|
if (varMatch) {
|
|
16720
16846
|
const vname = varMatch[1] ?? "";
|
|
16721
16847
|
if (vname && symbols.length < MAX_SYMBOLS4) {
|
|
16722
|
-
symbols.push(makeLineSymbol(filePath, vname, "variable", lineNum, stripped.slice(0, 200)));
|
|
16848
|
+
symbols.push(makeLineSymbol(filePath, vname, "variable", lineNum, stripped.slice(0, 200), void 0, lines2, "hash"));
|
|
16723
16849
|
}
|
|
16724
16850
|
}
|
|
16725
16851
|
}
|
|
@@ -17228,7 +17354,7 @@ function extractPowershell(content, filePath) {
|
|
|
17228
17354
|
if (funcMatch) {
|
|
17229
17355
|
const fname = funcMatch[1] ?? "";
|
|
17230
17356
|
if (symbols.length < MAX_SYMBOLS8) {
|
|
17231
|
-
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, line.trimEnd().slice(0, 200)));
|
|
17357
|
+
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, line.trimEnd().slice(0, 200), void 0, lines2, "hash"));
|
|
17232
17358
|
}
|
|
17233
17359
|
}
|
|
17234
17360
|
}
|
|
@@ -17238,7 +17364,7 @@ function extractPowershell(content, filePath) {
|
|
|
17238
17364
|
const cname = classMatch[2] ?? "";
|
|
17239
17365
|
const kind = (classMatch[1] ?? "").toLowerCase() === "enum" ? "enum" : "class";
|
|
17240
17366
|
if (symbols.length < MAX_SYMBOLS8) {
|
|
17241
|
-
symbols.push(makeLineSymbol(filePath, cname, kind, lineNum, line.trimEnd().slice(0, 200)));
|
|
17367
|
+
symbols.push(makeLineSymbol(filePath, cname, kind, lineNum, line.trimEnd().slice(0, 200), void 0, lines2, "hash"));
|
|
17242
17368
|
}
|
|
17243
17369
|
if (kind === "class") {
|
|
17244
17370
|
const strippedLine = stripPowershellStringLiterals(line);
|
|
@@ -17263,7 +17389,7 @@ function extractPowershell(content, filePath) {
|
|
|
17263
17389
|
if (mname && symbols.length < MAX_SYMBOLS8) {
|
|
17264
17390
|
const sigEnd = line.indexOf("{");
|
|
17265
17391
|
const sig = sigEnd >= 0 ? line.slice(0, sigEnd).trimEnd() : line.trimEnd();
|
|
17266
|
-
symbols.push(makeLineSymbol(filePath, mname, "method", lineNum, sig.slice(0, 200), currentClass));
|
|
17392
|
+
symbols.push(makeLineSymbol(filePath, mname, "method", lineNum, sig.slice(0, 200), currentClass, lines2, "hash"));
|
|
17267
17393
|
}
|
|
17268
17394
|
}
|
|
17269
17395
|
}
|
|
@@ -17361,12 +17487,13 @@ function extractApex(content, filePath) {
|
|
|
17361
17487
|
const stringFree = stripStringLiterals(blockCommentFree);
|
|
17362
17488
|
const code = stripCstyleComments(stringFree, /\/\/.*$/gm);
|
|
17363
17489
|
const codeLines = code.split(/\r?\n/);
|
|
17364
|
-
const
|
|
17490
|
+
const rawLines = content.split(/\r?\n/);
|
|
17491
|
+
const emit5 = (name2, kind, span, parent = "") => {
|
|
17365
17492
|
if (!name2 || symbols.length >= MAX_SYMBOLS9) return;
|
|
17366
17493
|
const key = `${name2}\0${kind}\0${span.startLine}`;
|
|
17367
17494
|
if (seen.has(key)) return;
|
|
17368
17495
|
seen.add(key);
|
|
17369
|
-
symbols.push(makeSpanSymbol(filePath, name2, kind, span,
|
|
17496
|
+
symbols.push(makeSpanSymbol(filePath, name2, kind, span, parent, rawLines, "c"));
|
|
17370
17497
|
};
|
|
17371
17498
|
for (const match2 of code.matchAll(TRIGGER_RE2)) {
|
|
17372
17499
|
const name2 = match2[1] ?? "";
|
|
@@ -17812,7 +17939,7 @@ function lwcTagAlias(name2) {
|
|
|
17812
17939
|
return `c-${kebab}`;
|
|
17813
17940
|
}
|
|
17814
17941
|
function symbol(filePath, name2, kind, lineStart, lineEnd = lineStart) {
|
|
17815
|
-
return { filePath, name: name2, kind, lineStart, lineEnd, body: "", docstring: "" };
|
|
17942
|
+
return { filePath, name: name2, kind, lineStart, lineEnd, body: "", docstring: "", parent: "" };
|
|
17816
17943
|
}
|
|
17817
17944
|
function ref(filePath, name2, line, col, context) {
|
|
17818
17945
|
return { filePath, name: name2, line, col, context };
|
|
@@ -18084,7 +18211,7 @@ function maskSpans(content, spans) {
|
|
|
18084
18211
|
return chars.join("");
|
|
18085
18212
|
}
|
|
18086
18213
|
function componentSymbol(filePath, name2, kind, totalLines) {
|
|
18087
|
-
return { filePath, name: name2, kind, lineStart: 1, lineEnd: totalLines, body: "", docstring: "" };
|
|
18214
|
+
return { filePath, name: name2, kind, lineStart: 1, lineEnd: totalLines, body: "", docstring: "", parent: "" };
|
|
18088
18215
|
}
|
|
18089
18216
|
function extractVue(content, filePath) {
|
|
18090
18217
|
const totalLines = content.split("\n").length;
|
|
@@ -18362,15 +18489,17 @@ function nodeName(node) {
|
|
|
18362
18489
|
if (named !== null) return named.text;
|
|
18363
18490
|
return null;
|
|
18364
18491
|
}
|
|
18365
|
-
function makeSymbol(filePath, name2, kind, node) {
|
|
18492
|
+
function makeSymbol(filePath, name2, kind, node, lines2, style) {
|
|
18493
|
+
const lineStart = node.startPosition.row + 1;
|
|
18366
18494
|
return {
|
|
18367
18495
|
filePath,
|
|
18368
18496
|
name: name2,
|
|
18369
18497
|
kind,
|
|
18370
|
-
lineStart
|
|
18498
|
+
lineStart,
|
|
18371
18499
|
lineEnd: node.endPosition.row + 1,
|
|
18372
18500
|
body: node.text,
|
|
18373
|
-
docstring: ""
|
|
18501
|
+
docstring: lines2 !== void 0 && style !== void 0 ? precedingDocComment(lines2, lineStart, style) : "",
|
|
18502
|
+
parent: ""
|
|
18374
18503
|
};
|
|
18375
18504
|
}
|
|
18376
18505
|
function collectPatternBindings(node) {
|
|
@@ -18385,7 +18514,7 @@ function collectPatternBindings(node) {
|
|
|
18385
18514
|
walk(node);
|
|
18386
18515
|
return names;
|
|
18387
18516
|
}
|
|
18388
|
-
function extractTsJsSymbols(root, filePath) {
|
|
18517
|
+
function extractTsJsSymbols(root, filePath, lines2) {
|
|
18389
18518
|
const out2 = [];
|
|
18390
18519
|
const visit = (node, insideFunction) => {
|
|
18391
18520
|
const kind = TSJS_KIND_BY_TYPE.get(node.type);
|
|
@@ -18394,16 +18523,18 @@ function extractTsJsSymbols(root, filePath) {
|
|
|
18394
18523
|
if (name2 !== null && name2 !== "") {
|
|
18395
18524
|
const decorators = leadingTsDecorators(node);
|
|
18396
18525
|
if (decorators.length === 0) {
|
|
18397
|
-
out2.push(makeSymbol(filePath, name2, kind, node));
|
|
18526
|
+
out2.push(makeSymbol(filePath, name2, kind, node, lines2, "c"));
|
|
18398
18527
|
} else {
|
|
18528
|
+
const lineStart = decorators[0].startPosition.row + 1;
|
|
18399
18529
|
out2.push({
|
|
18400
18530
|
filePath,
|
|
18401
18531
|
name: name2,
|
|
18402
18532
|
kind,
|
|
18403
|
-
lineStart
|
|
18533
|
+
lineStart,
|
|
18404
18534
|
lineEnd: node.endPosition.row + 1,
|
|
18405
18535
|
body: [...decorators, node].map((n) => n.text).join("\n"),
|
|
18406
|
-
docstring: ""
|
|
18536
|
+
docstring: precedingDocComment(lines2, lineStart, "c"),
|
|
18537
|
+
parent: ""
|
|
18407
18538
|
});
|
|
18408
18539
|
}
|
|
18409
18540
|
}
|
|
@@ -18416,10 +18547,10 @@ function extractTsJsSymbols(root, filePath) {
|
|
|
18416
18547
|
if (name2 === null) continue;
|
|
18417
18548
|
if (name2.type === "identifier") {
|
|
18418
18549
|
const isFn = value !== null && (value.type === "arrow_function" || value.type === "function_expression" || value.type === "function");
|
|
18419
|
-
out2.push(makeSymbol(filePath, name2.text, isFn ? "function" : "variable", child));
|
|
18550
|
+
out2.push(makeSymbol(filePath, name2.text, isFn ? "function" : "variable", child, lines2, "c"));
|
|
18420
18551
|
} else {
|
|
18421
18552
|
for (const bound of collectPatternBindings(name2)) {
|
|
18422
|
-
out2.push(makeSymbol(filePath, bound, "variable", child));
|
|
18553
|
+
out2.push(makeSymbol(filePath, bound, "variable", child, lines2, "c"));
|
|
18423
18554
|
}
|
|
18424
18555
|
}
|
|
18425
18556
|
}
|
|
@@ -18428,7 +18559,7 @@ function extractTsJsSymbols(root, filePath) {
|
|
|
18428
18559
|
const fieldName = node.childForFieldName("name") ?? node.childForFieldName("property");
|
|
18429
18560
|
const value = node.childForFieldName("value");
|
|
18430
18561
|
if (fieldName !== null && value !== null && (value.type === "arrow_function" || value.type === "function_expression" || value.type === "function")) {
|
|
18431
|
-
out2.push(makeSymbol(filePath, fieldName.text, "method", node));
|
|
18562
|
+
out2.push(makeSymbol(filePath, fieldName.text, "method", node, lines2, "c"));
|
|
18432
18563
|
}
|
|
18433
18564
|
}
|
|
18434
18565
|
const childInside = insideFunction || TSJS_FN_SCOPE_TYPES.has(node.type);
|
|
@@ -18492,14 +18623,14 @@ function stripPythonStringQuotes(raw) {
|
|
|
18492
18623
|
}
|
|
18493
18624
|
return s.trim();
|
|
18494
18625
|
}
|
|
18495
|
-
function extractGoSymbols(root, filePath) {
|
|
18626
|
+
function extractGoSymbols(root, filePath, lines2) {
|
|
18496
18627
|
const out2 = [];
|
|
18497
18628
|
const visit = (node, insideFunction) => {
|
|
18498
18629
|
const kind = GO_KIND_BY_TYPE.get(node.type);
|
|
18499
18630
|
if (kind !== void 0 && !(insideFunction && GO_LOCAL_KINDS.has(node.type))) {
|
|
18500
18631
|
const name2 = nodeName(node);
|
|
18501
18632
|
if (name2 !== null && name2 !== "") {
|
|
18502
|
-
out2.push(makeSymbol(filePath, name2, kind, node));
|
|
18633
|
+
out2.push(makeSymbol(filePath, name2, kind, node, lines2, "c"));
|
|
18503
18634
|
}
|
|
18504
18635
|
}
|
|
18505
18636
|
const childInside = insideFunction || GO_FN_SCOPE_TYPES.has(node.type);
|
|
@@ -18519,7 +18650,7 @@ function leadingRustAttributes(node) {
|
|
|
18519
18650
|
}
|
|
18520
18651
|
return attrs;
|
|
18521
18652
|
}
|
|
18522
|
-
function extractRustSymbols(root, filePath) {
|
|
18653
|
+
function extractRustSymbols(root, filePath, lines2) {
|
|
18523
18654
|
const out2 = [];
|
|
18524
18655
|
const visit = (node, insideFunction) => {
|
|
18525
18656
|
const kind = RUST_KIND_BY_TYPE.get(node.type);
|
|
@@ -18528,16 +18659,18 @@ function extractRustSymbols(root, filePath) {
|
|
|
18528
18659
|
if (name2 !== null && name2 !== "") {
|
|
18529
18660
|
const attrs = leadingRustAttributes(node);
|
|
18530
18661
|
if (attrs.length === 0) {
|
|
18531
|
-
out2.push(makeSymbol(filePath, name2, kind, node));
|
|
18662
|
+
out2.push(makeSymbol(filePath, name2, kind, node, lines2, "c"));
|
|
18532
18663
|
} else {
|
|
18664
|
+
const lineStart = attrs[0].startPosition.row + 1;
|
|
18533
18665
|
out2.push({
|
|
18534
18666
|
filePath,
|
|
18535
18667
|
name: name2,
|
|
18536
18668
|
kind,
|
|
18537
|
-
lineStart
|
|
18669
|
+
lineStart,
|
|
18538
18670
|
lineEnd: node.endPosition.row + 1,
|
|
18539
18671
|
body: [...attrs, node].map((n) => n.text).join("\n"),
|
|
18540
|
-
docstring: ""
|
|
18672
|
+
docstring: precedingDocComment(lines2, lineStart, "c"),
|
|
18673
|
+
parent: ""
|
|
18541
18674
|
});
|
|
18542
18675
|
}
|
|
18543
18676
|
}
|
|
@@ -18550,14 +18683,14 @@ function extractRustSymbols(root, filePath) {
|
|
|
18550
18683
|
visit(root, false);
|
|
18551
18684
|
return out2;
|
|
18552
18685
|
}
|
|
18553
|
-
function extractSimpleSymbols(root, filePath, kindByType, nameFor = nodeName) {
|
|
18686
|
+
function extractSimpleSymbols(root, filePath, kindByType, lines2, style, nameFor = nodeName) {
|
|
18554
18687
|
const out2 = [];
|
|
18555
18688
|
const visit = (node) => {
|
|
18556
18689
|
const kind = kindByType.get(node.type);
|
|
18557
18690
|
if (kind !== void 0) {
|
|
18558
18691
|
const name2 = nameFor(node);
|
|
18559
18692
|
if (name2 !== null && name2 !== "") {
|
|
18560
|
-
out2.push(makeSymbol(filePath, name2, kind, node));
|
|
18693
|
+
out2.push(makeSymbol(filePath, name2, kind, node, lines2, style));
|
|
18561
18694
|
}
|
|
18562
18695
|
}
|
|
18563
18696
|
for (const child of node.namedChildren) {
|
|
@@ -18567,17 +18700,19 @@ function extractSimpleSymbols(root, filePath, kindByType, nameFor = nodeName) {
|
|
|
18567
18700
|
visit(root);
|
|
18568
18701
|
return out2;
|
|
18569
18702
|
}
|
|
18570
|
-
function extractRubySymbols(root, filePath) {
|
|
18571
|
-
return extractSimpleSymbols(root, filePath, RUBY_KIND_BY_TYPE);
|
|
18703
|
+
function extractRubySymbols(root, filePath, lines2) {
|
|
18704
|
+
return extractSimpleSymbols(root, filePath, RUBY_KIND_BY_TYPE, lines2, "hash");
|
|
18572
18705
|
}
|
|
18573
|
-
function extractJavaSymbols(root, filePath) {
|
|
18574
|
-
return extractSimpleSymbols(root, filePath, JAVA_KIND_BY_TYPE);
|
|
18706
|
+
function extractJavaSymbols(root, filePath, lines2) {
|
|
18707
|
+
return extractSimpleSymbols(root, filePath, JAVA_KIND_BY_TYPE, lines2, "c");
|
|
18575
18708
|
}
|
|
18576
|
-
function extractCppSymbols(root, filePath) {
|
|
18709
|
+
function extractCppSymbols(root, filePath, lines2) {
|
|
18577
18710
|
return extractSimpleSymbols(
|
|
18578
18711
|
root,
|
|
18579
18712
|
filePath,
|
|
18580
18713
|
CPP_KIND_BY_TYPE,
|
|
18714
|
+
lines2,
|
|
18715
|
+
"c",
|
|
18581
18716
|
(node) => node.type === "function_definition" ? cFunctionName(node) : node.type === "type_definition" ? cTypedefAliasName(node) : node.type === "declaration" ? cFunctionPrototypeName(node) : nodeName(node)
|
|
18582
18717
|
);
|
|
18583
18718
|
}
|
|
@@ -18839,7 +18974,8 @@ function extractMarkdownSymbols(content, filePath) {
|
|
|
18839
18974
|
lineStart: i + 1,
|
|
18840
18975
|
lineEnd: i + 1,
|
|
18841
18976
|
body: line.trim(),
|
|
18842
|
-
docstring: ""
|
|
18977
|
+
docstring: "",
|
|
18978
|
+
parent: ""
|
|
18843
18979
|
});
|
|
18844
18980
|
}
|
|
18845
18981
|
}
|
|
@@ -18898,7 +19034,8 @@ function extractJsonSymbols(content, filePath) {
|
|
|
18898
19034
|
lineStart: strStartLine,
|
|
18899
19035
|
lineEnd,
|
|
18900
19036
|
body,
|
|
18901
|
-
docstring: ""
|
|
19037
|
+
docstring: "",
|
|
19038
|
+
parent: ""
|
|
18902
19039
|
});
|
|
18903
19040
|
}
|
|
18904
19041
|
}
|
|
@@ -18983,7 +19120,8 @@ function extractYamlSymbols(content, filePath) {
|
|
|
18983
19120
|
lineStart: i + 1,
|
|
18984
19121
|
lineEnd: i + 1,
|
|
18985
19122
|
body: line.trim(),
|
|
18986
|
-
docstring: ""
|
|
19123
|
+
docstring: "",
|
|
19124
|
+
parent: ""
|
|
18987
19125
|
});
|
|
18988
19126
|
openQuote = yamlOpenQuoteAfter(line, match2[0].length);
|
|
18989
19127
|
}
|
|
@@ -19035,7 +19173,8 @@ function extractTomlSymbols(content, filePath) {
|
|
|
19035
19173
|
lineStart: lineNum + 1,
|
|
19036
19174
|
lineEnd: lineNum + 1,
|
|
19037
19175
|
body: line.trim(),
|
|
19038
|
-
docstring: ""
|
|
19176
|
+
docstring: "",
|
|
19177
|
+
parent: ""
|
|
19039
19178
|
});
|
|
19040
19179
|
}
|
|
19041
19180
|
const keyMatch = /^\s*([a-zA-Z_][\w-]*)\s*=/.exec(line);
|
|
@@ -19047,7 +19186,8 @@ function extractTomlSymbols(content, filePath) {
|
|
|
19047
19186
|
lineStart: lineNum + 1,
|
|
19048
19187
|
lineEnd: lineNum + 1,
|
|
19049
19188
|
body: line.trim(),
|
|
19050
|
-
docstring: ""
|
|
19189
|
+
docstring: "",
|
|
19190
|
+
parent: ""
|
|
19051
19191
|
});
|
|
19052
19192
|
}
|
|
19053
19193
|
}
|
|
@@ -19121,7 +19261,8 @@ function extractCssSymbols(content, filePath) {
|
|
|
19121
19261
|
lineStart: p.line,
|
|
19122
19262
|
lineEnd: p.line,
|
|
19123
19263
|
body: p.body,
|
|
19124
|
-
docstring: ""
|
|
19264
|
+
docstring: "",
|
|
19265
|
+
parent: ""
|
|
19125
19266
|
});
|
|
19126
19267
|
}
|
|
19127
19268
|
pending = [];
|
|
@@ -19138,7 +19279,8 @@ function extractCssSymbols(content, filePath) {
|
|
|
19138
19279
|
lineStart: i + 1,
|
|
19139
19280
|
lineEnd: i + 1,
|
|
19140
19281
|
body: line.trim(),
|
|
19141
|
-
docstring: ""
|
|
19282
|
+
docstring: "",
|
|
19283
|
+
parent: ""
|
|
19142
19284
|
});
|
|
19143
19285
|
}
|
|
19144
19286
|
}
|
|
@@ -19153,7 +19295,8 @@ function extractCssSymbols(content, filePath) {
|
|
|
19153
19295
|
lineStart: p.line,
|
|
19154
19296
|
lineEnd: p.line,
|
|
19155
19297
|
body: p.body,
|
|
19156
|
-
docstring: ""
|
|
19298
|
+
docstring: "",
|
|
19299
|
+
parent: ""
|
|
19157
19300
|
});
|
|
19158
19301
|
}
|
|
19159
19302
|
pending = [];
|
|
@@ -19197,7 +19340,8 @@ function extractDockerfileSymbols(content, filePath) {
|
|
|
19197
19340
|
lineStart: i + 1,
|
|
19198
19341
|
lineEnd: i + 1,
|
|
19199
19342
|
body: line.trim(),
|
|
19200
|
-
docstring: ""
|
|
19343
|
+
docstring: "",
|
|
19344
|
+
parent: ""
|
|
19201
19345
|
});
|
|
19202
19346
|
}
|
|
19203
19347
|
continuing = !isComment2 && line.trimEnd().endsWith("\\");
|
|
@@ -19210,7 +19354,7 @@ function extractWithRegex(content, filePath) {
|
|
|
19210
19354
|
for (let i = 0; i < lines2.length; i++) {
|
|
19211
19355
|
const line = lines2[i];
|
|
19212
19356
|
if (line === void 0) continue;
|
|
19213
|
-
for (const { re, kind } of FALLBACK_PATTERNS) {
|
|
19357
|
+
for (const { re, kind, style } of FALLBACK_PATTERNS) {
|
|
19214
19358
|
const m = re.exec(line);
|
|
19215
19359
|
if (m !== null && m[1] !== void 0) {
|
|
19216
19360
|
out2.push({
|
|
@@ -19220,7 +19364,8 @@ function extractWithRegex(content, filePath) {
|
|
|
19220
19364
|
lineStart: i + 1,
|
|
19221
19365
|
lineEnd: i + 1,
|
|
19222
19366
|
body: line.trim(),
|
|
19223
|
-
docstring:
|
|
19367
|
+
docstring: precedingDocComment(lines2, i + 1, style),
|
|
19368
|
+
parent: ""
|
|
19224
19369
|
});
|
|
19225
19370
|
break;
|
|
19226
19371
|
}
|
|
@@ -19275,17 +19420,17 @@ function parseContent(content, filePath, language) {
|
|
|
19275
19420
|
if (language === "python") {
|
|
19276
19421
|
symbols = extractPythonSymbols(root, filePath);
|
|
19277
19422
|
} else if (language === "go") {
|
|
19278
|
-
symbols = extractGoSymbols(root, filePath);
|
|
19423
|
+
symbols = extractGoSymbols(root, filePath, content.split(/\r?\n/));
|
|
19279
19424
|
} else if (language === "rust") {
|
|
19280
|
-
symbols = extractRustSymbols(root, filePath);
|
|
19425
|
+
symbols = extractRustSymbols(root, filePath, content.split(/\r?\n/));
|
|
19281
19426
|
} else if (language === "ruby") {
|
|
19282
|
-
symbols = extractRubySymbols(root, filePath);
|
|
19427
|
+
symbols = extractRubySymbols(root, filePath, content.split(/\r?\n/));
|
|
19283
19428
|
} else if (language === "java") {
|
|
19284
|
-
symbols = extractJavaSymbols(root, filePath);
|
|
19429
|
+
symbols = extractJavaSymbols(root, filePath, content.split(/\r?\n/));
|
|
19285
19430
|
} else if (language === "cpp" || language === "c") {
|
|
19286
|
-
symbols = extractCppSymbols(root, filePath);
|
|
19431
|
+
symbols = extractCppSymbols(root, filePath, content.split(/\r?\n/));
|
|
19287
19432
|
} else {
|
|
19288
|
-
symbols = extractTsJsSymbols(root, filePath);
|
|
19433
|
+
symbols = extractTsJsSymbols(root, filePath, content.split(/\r?\n/));
|
|
19289
19434
|
}
|
|
19290
19435
|
const refs = REF_LANGUAGES.has(language) ? extractRefs(root, filePath, language) : [];
|
|
19291
19436
|
const parsed = { symbols, refs };
|
|
@@ -19304,7 +19449,8 @@ function sectionsToHeadingSymbols(sections, filePath) {
|
|
|
19304
19449
|
lineStart: s.line,
|
|
19305
19450
|
lineEnd: s.endLine,
|
|
19306
19451
|
body: "",
|
|
19307
|
-
docstring: ""
|
|
19452
|
+
docstring: "",
|
|
19453
|
+
parent: ""
|
|
19308
19454
|
}));
|
|
19309
19455
|
}
|
|
19310
19456
|
function extractNoTreeSitter(content, filePath, language) {
|
|
@@ -19340,6 +19486,7 @@ function isUnderSkipDir(filePath, skipDirs) {
|
|
|
19340
19486
|
}
|
|
19341
19487
|
function isParseSkipEligible(filePath, cfg) {
|
|
19342
19488
|
if (isUnderSkipDir(filePath, cfg.skip_dirs)) return true;
|
|
19489
|
+
if (cfg.skip_files.includes(path26.basename(filePath))) return true;
|
|
19343
19490
|
try {
|
|
19344
19491
|
const stat2 = fs22.statSync(filePath);
|
|
19345
19492
|
if (stat2.size > cfg.large_file_skip_kb * 1024) return true;
|
|
@@ -19358,11 +19505,20 @@ function writeParseResult(filePath, content, result, dbPath) {
|
|
|
19358
19505
|
"INSERT INTO files (path, sha, mtime, language, indexed_at) VALUES (?, ?, ?, ?, ?)"
|
|
19359
19506
|
).run(filePath, sha, mtime, result.language, now);
|
|
19360
19507
|
const insSym = db.prepare(
|
|
19361
|
-
"INSERT INTO symbols (file_path, name, kind, line_start, line_end, body, docstring) VALUES (?, ?, ?, ?, ?, ?, ?)"
|
|
19508
|
+
"INSERT INTO symbols (file_path, name, kind, line_start, line_end, body, docstring, parent) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
|
|
19362
19509
|
);
|
|
19363
19510
|
for (const s of result.symbols) {
|
|
19364
19511
|
if (s.name === "" || s.kind === "") continue;
|
|
19365
|
-
insSym.run(
|
|
19512
|
+
insSym.run(
|
|
19513
|
+
s.filePath,
|
|
19514
|
+
s.name,
|
|
19515
|
+
s.kind,
|
|
19516
|
+
s.lineStart,
|
|
19517
|
+
s.lineEnd,
|
|
19518
|
+
boundSymbolBody(s.body),
|
|
19519
|
+
boundSymbolDocstring(s.docstring),
|
|
19520
|
+
s.parent
|
|
19521
|
+
);
|
|
19366
19522
|
}
|
|
19367
19523
|
const insRef = db.prepare(
|
|
19368
19524
|
"INSERT INTO refs (file_path, name, line, col, context) VALUES (?, ?, ?, ?, ?)"
|
|
@@ -19521,6 +19677,7 @@ var init_parser = __esm({
|
|
|
19521
19677
|
init_sql_path();
|
|
19522
19678
|
init_markdown_lines();
|
|
19523
19679
|
init_parser_types();
|
|
19680
|
+
init_doc_comment();
|
|
19524
19681
|
init_index_reader();
|
|
19525
19682
|
init_markdown_hints();
|
|
19526
19683
|
init_csharp();
|
|
@@ -19550,6 +19707,7 @@ var init_parser = __esm({
|
|
|
19550
19707
|
init_sfc_idx();
|
|
19551
19708
|
init_ipynb_idx();
|
|
19552
19709
|
init_util2();
|
|
19710
|
+
init_doc_comment();
|
|
19553
19711
|
_require4 = createRequire5(import.meta.url);
|
|
19554
19712
|
_grammarCache = /* @__PURE__ */ new Map();
|
|
19555
19713
|
CPP_HEADER_SNIFF_RE = /\bclass\s+\w|\bnamespace\s+\w|\btemplate\s*<|::\s*\w|\b(?:public|private|protected)\s*:/;
|
|
@@ -19992,28 +20150,31 @@ var init_parser = __esm({
|
|
|
19992
20150
|
EMPTY_STRING_SET = /* @__PURE__ */ new Set();
|
|
19993
20151
|
FALLBACK_PATTERNS = [
|
|
19994
20152
|
// Python
|
|
19995
|
-
{ re: /^[ \t]*(?:async\s+)?def\s+([A-Za-z_]\w*)/, kind: "function" },
|
|
19996
|
-
{ re: /^[ \t]*class\s+([A-Za-z_]\w*)/, kind: "class" },
|
|
20153
|
+
{ re: /^[ \t]*(?:async\s+)?def\s+([A-Za-z_]\w*)/, kind: "function", style: "hash" },
|
|
20154
|
+
{ re: /^[ \t]*class\s+([A-Za-z_]\w*)/, kind: "class", style: "hash" },
|
|
19997
20155
|
// TS/JS function & class declarations (optionally exported/async)
|
|
19998
20156
|
{
|
|
19999
20157
|
re: /^[ \t]*(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s*\*?\s*([A-Za-z_$][\w$]*)/,
|
|
20000
|
-
kind: "function"
|
|
20158
|
+
kind: "function",
|
|
20159
|
+
style: "c"
|
|
20001
20160
|
},
|
|
20002
20161
|
{
|
|
20003
20162
|
re: /^[ \t]*(?:export\s+)?(?:default\s+)?(?:abstract\s+)?class\s+([A-Za-z_$][\w$]*)/,
|
|
20004
|
-
kind: "class"
|
|
20163
|
+
kind: "class",
|
|
20164
|
+
style: "c"
|
|
20005
20165
|
},
|
|
20006
|
-
{ re: /^[ \t]*(?:export\s+)?interface\s+([A-Za-z_$][\w$]*)/, kind: "interface" },
|
|
20007
|
-
{ re: /^[ \t]*(?:export\s+)?type\s+([A-Za-z_$][\w$]*)\s*=/, kind: "type" },
|
|
20166
|
+
{ re: /^[ \t]*(?:export\s+)?interface\s+([A-Za-z_$][\w$]*)/, kind: "interface", style: "c" },
|
|
20167
|
+
{ re: /^[ \t]*(?:export\s+)?type\s+([A-Za-z_$][\w$]*)\s*=/, kind: "type", style: "c" },
|
|
20008
20168
|
// const/let/var bound to an arrow or function expression
|
|
20009
20169
|
{
|
|
20010
20170
|
re: /^[ \t]*(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:async\s+)?(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>/,
|
|
20011
|
-
kind: "function"
|
|
20171
|
+
kind: "function",
|
|
20172
|
+
style: "c"
|
|
20012
20173
|
},
|
|
20013
20174
|
// Rust / Go function & struct/type patterns
|
|
20014
|
-
{ re: /^[ \t]*(?:pub\s+)?(?:async\s+)?fn\s+([A-Za-z_]\w*)/, kind: "function" },
|
|
20015
|
-
{ re: /^[ \t]*(?:pub\s+)?struct\s+([A-Za-z_]\w*)/, kind: "struct" },
|
|
20016
|
-
{ re: /^[ \t]*func\s+(?:\([^)]*\)\s*)?([A-Za-z_]\w*)/, kind: "function" }
|
|
20175
|
+
{ re: /^[ \t]*(?:pub\s+)?(?:async\s+)?fn\s+([A-Za-z_]\w*)/, kind: "function", style: "c" },
|
|
20176
|
+
{ re: /^[ \t]*(?:pub\s+)?struct\s+([A-Za-z_]\w*)/, kind: "struct", style: "c" },
|
|
20177
|
+
{ re: /^[ \t]*func\s+(?:\([^)]*\)\s*)?([A-Za-z_]\w*)/, kind: "function", style: "c" }
|
|
20017
20178
|
];
|
|
20018
20179
|
NO_TREE_SITTER_EXTRACTORS = {
|
|
20019
20180
|
markdown: extractMarkdownSymbols,
|
|
@@ -24043,7 +24204,7 @@ function fetchTopSymbols(limit, dbPath, rootDir) {
|
|
|
24043
24204
|
const db = getDb(dbPath);
|
|
24044
24205
|
const { clause, param } = projectScopeClause("file_path");
|
|
24045
24206
|
const rows = db.prepare(
|
|
24046
|
-
`SELECT file_path, name, kind, line_start, line_end, body, docstring
|
|
24207
|
+
`SELECT file_path, name, kind, line_start, line_end, body, docstring, parent
|
|
24047
24208
|
FROM symbols
|
|
24048
24209
|
WHERE kind IN ('class', 'function', 'interface') AND ${clause}
|
|
24049
24210
|
ORDER BY CASE kind WHEN 'class' THEN 0 WHEN 'interface' THEN 1 ELSE 2 END,
|
|
@@ -24057,7 +24218,8 @@ function fetchTopSymbols(limit, dbPath, rootDir) {
|
|
|
24057
24218
|
lineStart: r.line_start,
|
|
24058
24219
|
lineEnd: r.line_end,
|
|
24059
24220
|
body: r.body ?? "",
|
|
24060
|
-
docstring: r.docstring ?? ""
|
|
24221
|
+
docstring: r.docstring ?? "",
|
|
24222
|
+
parent: r.parent ?? ""
|
|
24061
24223
|
}));
|
|
24062
24224
|
} catch {
|
|
24063
24225
|
return [];
|
|
@@ -24172,9 +24334,9 @@ function formatMemSuggestions(projectRoot) {
|
|
|
24172
24334
|
if (suggestions.length === 0) return "";
|
|
24173
24335
|
const lines2 = ["", "## mem suggestions"];
|
|
24174
24336
|
for (const s of suggestions) {
|
|
24175
|
-
const
|
|
24337
|
+
const basename21 = path33.basename(s.path);
|
|
24176
24338
|
lines2.push(
|
|
24177
|
-
"Consider: mem import --from-md " + s.path + " # migrates " + s.count + " preference-shaped lines from " +
|
|
24339
|
+
"Consider: mem import --from-md " + s.path + " # migrates " + s.count + " preference-shaped lines from " + basename21 + " as pending facts for review"
|
|
24178
24340
|
);
|
|
24179
24341
|
}
|
|
24180
24342
|
return lines2.join(String.fromCharCode(10));
|
|
@@ -29545,6 +29707,8 @@ function findParentName(entry, fileSymbols) {
|
|
|
29545
29707
|
}
|
|
29546
29708
|
}
|
|
29547
29709
|
if (best !== null) return best.name;
|
|
29710
|
+
const parent = (entry.parent ?? "").trim();
|
|
29711
|
+
if (parent !== "") return parent;
|
|
29548
29712
|
const doc = entry.docstring.trim();
|
|
29549
29713
|
if (doc !== "" && PARENT_IDENTIFIER_RE.test(doc)) return doc;
|
|
29550
29714
|
return null;
|
|
@@ -29621,7 +29785,9 @@ function resolveSymbolSpec(spec, forceRefresh, projectRoot) {
|
|
|
29621
29785
|
});
|
|
29622
29786
|
const symBaseLower = symBase.toLowerCase();
|
|
29623
29787
|
const scoped = candidates.filter((c) => {
|
|
29624
|
-
|
|
29788
|
+
const cParent = c.parent ?? "";
|
|
29789
|
+
if (cParent.toLowerCase() === symBaseLower) return true;
|
|
29790
|
+
if (cParent === "" && c.docstring.toLowerCase() === symBaseLower) return true;
|
|
29625
29791
|
return containers.some(
|
|
29626
29792
|
(cls) => cls.filePath === c.filePath && c.lineStart >= cls.lineStart && c.lineEnd <= cls.lineEnd
|
|
29627
29793
|
);
|
|
@@ -29634,6 +29800,10 @@ function runRead(opts) {
|
|
|
29634
29800
|
const range2 = parseLineRange(opts.spec);
|
|
29635
29801
|
if (range2 !== null) return runLineRange(range2, opts);
|
|
29636
29802
|
const { file: file2, symbol: symbol3 } = parseReadSpec(opts.spec);
|
|
29803
|
+
if (symbol3 !== void 0 && symbol3 !== "" && symbol3.includes(",") && parseColonLineRange(symbol3) === null) {
|
|
29804
|
+
const multiSymbols = symbol3.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
29805
|
+
if (multiSymbols.length > 1) return runReadMulti(file2, multiSymbols, opts);
|
|
29806
|
+
}
|
|
29637
29807
|
if (symbol3 === void 0 || symbol3 === "") {
|
|
29638
29808
|
const text2 = readFileText(file2);
|
|
29639
29809
|
if (text2 === null) {
|
|
@@ -29661,22 +29831,55 @@ function runRead(opts) {
|
|
|
29661
29831
|
}
|
|
29662
29832
|
const match2 = resolution.entry;
|
|
29663
29833
|
const fullSourceBytes = sumFileSizes([match2.filePath]);
|
|
29834
|
+
const refCounts = opts.stats === true ? queryRefCounts([match2.name], globalDbPath(), resolveProjectRoot({ project: opts.projectRoot ?? process.cwd() })) : void 0;
|
|
29664
29835
|
if (opts.json === true) {
|
|
29665
|
-
const text2 = JSON.stringify(
|
|
29666
|
-
|
|
29836
|
+
const text2 = JSON.stringify(
|
|
29837
|
+
{
|
|
29838
|
+
...match2,
|
|
29839
|
+
body: resolveBody(match2),
|
|
29840
|
+
...refCounts !== void 0 ? { refCount: refCounts.get(match2.name) ?? 0 } : {}
|
|
29841
|
+
},
|
|
29842
|
+
null,
|
|
29843
|
+
2
|
|
29844
|
+
);
|
|
29845
|
+
if (opts.suppressStat !== true) recordReadStat("read_replacement", fullSourceBytes, text2, opts.spec);
|
|
29667
29846
|
return { text: text2, code: 0 };
|
|
29668
29847
|
}
|
|
29669
29848
|
const body = resolveBody(match2);
|
|
29670
29849
|
const bodyLen = match2.lineEnd - match2.lineStart + 1;
|
|
29850
|
+
const statsStr = formatStatsSuffix(refCounts, match2);
|
|
29671
29851
|
const lines2 = [
|
|
29672
|
-
`# ${bodyLen} lines (~${Math.ceil(body.length / 4)} tok)`,
|
|
29852
|
+
`# ${bodyLen} lines (~${Math.ceil(body.length / 4)} tok)${statsStr}`,
|
|
29673
29853
|
body
|
|
29674
29854
|
];
|
|
29675
29855
|
const warning = staleWarning(match2.filePath);
|
|
29676
29856
|
const text = guardText(warning + trimBlankLines(lines2).join("\n"), "symbol");
|
|
29677
|
-
recordReadStat("read_replacement", fullSourceBytes, text, opts.spec);
|
|
29857
|
+
if (opts.suppressStat !== true) recordReadStat("read_replacement", fullSourceBytes, text, opts.spec);
|
|
29678
29858
|
return { text, code: 0 };
|
|
29679
29859
|
}
|
|
29860
|
+
function runReadMulti(file2, symbols, opts) {
|
|
29861
|
+
let anyFound = false;
|
|
29862
|
+
const jsonOut = {};
|
|
29863
|
+
const textBlocks = [];
|
|
29864
|
+
for (const sym of symbols) {
|
|
29865
|
+
const sub = runRead({ ...opts, spec: `${file2}::${sym}`, suppressStat: true });
|
|
29866
|
+
if (sub.code === 0) anyFound = true;
|
|
29867
|
+
if (opts.json === true) {
|
|
29868
|
+
jsonOut[sym] = sub.code === 0 ? JSON.parse(sub.text) : { error: sub.text };
|
|
29869
|
+
continue;
|
|
29870
|
+
}
|
|
29871
|
+
textBlocks.push(`${sym}:
|
|
29872
|
+
${sub.text}`);
|
|
29873
|
+
}
|
|
29874
|
+
if (anyFound) {
|
|
29875
|
+
const fullSourceBytes = sumFileSizes([resolveIndexPath(file2, opts.projectRoot ?? process.cwd())]);
|
|
29876
|
+
const text2 = opts.json === true ? JSON.stringify(jsonOut, null, 2) : textBlocks.join("\n\n");
|
|
29877
|
+
recordReadStat("read_replacement", fullSourceBytes, text2, opts.spec);
|
|
29878
|
+
return { text: text2, code: 0 };
|
|
29879
|
+
}
|
|
29880
|
+
const text = opts.json === true ? JSON.stringify(jsonOut, null, 2) : textBlocks.join("\n\n");
|
|
29881
|
+
return { text, code: 1 };
|
|
29882
|
+
}
|
|
29680
29883
|
function runSection(opts) {
|
|
29681
29884
|
const colonIdx = findSpecSeparator(opts.spec);
|
|
29682
29885
|
if (colonIdx === -1) {
|
|
@@ -29879,6 +30082,13 @@ function noSymbolsMessage(displayPath, resolvedPath) {
|
|
|
29879
30082
|
}
|
|
29880
30083
|
return `No indexed symbols found in '${displayPath}'`;
|
|
29881
30084
|
}
|
|
30085
|
+
function hasRealDocstring(docstring) {
|
|
30086
|
+
const doc = docstring.trim();
|
|
30087
|
+
return doc !== "" && !PARENT_IDENTIFIER_RE.test(doc);
|
|
30088
|
+
}
|
|
30089
|
+
function formatStatsSuffix(refCounts, sym) {
|
|
30090
|
+
return refCounts !== void 0 ? ` [${refCounts.get(sym.name) ?? 0} refs, ${hasRealDocstring(sym.docstring) ? "documented" : "undocumented"}]` : "";
|
|
30091
|
+
}
|
|
29882
30092
|
function prepareSymbolListing(file2, opts) {
|
|
29883
30093
|
const resolved = resolveIndexPath(file2, opts.projectRoot ?? process.cwd());
|
|
29884
30094
|
if (opts.forceRefresh === true) {
|
|
@@ -29911,7 +30121,7 @@ function runSkeleton(opts) {
|
|
|
29911
30121
|
kind: s.kind,
|
|
29912
30122
|
lineStart: s.lineStart,
|
|
29913
30123
|
lineEnd: s.lineEnd,
|
|
29914
|
-
...refCounts !== void 0 ? { refCount: refCounts.get(s.name) ?? 0, hasDoc: s.docstring
|
|
30124
|
+
...refCounts !== void 0 ? { refCount: refCounts.get(s.name) ?? 0, hasDoc: hasRealDocstring(s.docstring) } : {}
|
|
29915
30125
|
}));
|
|
29916
30126
|
const capped = guardJsonRows(rows);
|
|
29917
30127
|
const payload = {
|
|
@@ -29927,7 +30137,7 @@ function runSkeleton(opts) {
|
|
|
29927
30137
|
const lines2 = [`# Skeleton: ${opts.file} (${filtered.length} symbols, ${totalLines} lines)`];
|
|
29928
30138
|
for (const sym of filtered) {
|
|
29929
30139
|
const lineStr = sym.lineStart.toString().padStart(6);
|
|
29930
|
-
const statsStr = refCounts
|
|
30140
|
+
const statsStr = formatStatsSuffix(refCounts, sym);
|
|
29931
30141
|
lines2.push(` ${lineStr} ${sym.kind.padEnd(10)} ${sym.name} ${firstBodyLine(sym.body)}${statsStr}`);
|
|
29932
30142
|
}
|
|
29933
30143
|
const text = guardText(staleWarning(resolved) + lines2.join("\n"), "symbol");
|
|
@@ -29944,7 +30154,7 @@ function runOutline(opts) {
|
|
|
29944
30154
|
const rows = refCounts !== void 0 ? filtered.map((s) => ({
|
|
29945
30155
|
...s,
|
|
29946
30156
|
refCount: refCounts.get(s.name) ?? 0,
|
|
29947
|
-
hasDoc: s.docstring
|
|
30157
|
+
hasDoc: hasRealDocstring(s.docstring)
|
|
29948
30158
|
})) : filtered;
|
|
29949
30159
|
const capped = guardJsonRows(rows);
|
|
29950
30160
|
const payload = {
|
|
@@ -29961,8 +30171,8 @@ function runOutline(opts) {
|
|
|
29961
30171
|
const rangeStr = `${sym.lineStart.toString().padStart(4)}-${sym.lineEnd.toString().padEnd(6)}`;
|
|
29962
30172
|
const kindStr = sym.kind.padEnd(14);
|
|
29963
30173
|
const bodyLen = sym.lineEnd - sym.lineStart + 1;
|
|
29964
|
-
const docFirst = sym.docstring ? ` # ${sym.docstring.split("\n")[0] ?? ""}` : "";
|
|
29965
|
-
const statsStr = refCounts
|
|
30174
|
+
const docFirst = hasRealDocstring(sym.docstring) ? ` # ${sym.docstring.split("\n")[0] ?? ""}` : "";
|
|
30175
|
+
const statsStr = formatStatsSuffix(refCounts, sym);
|
|
29966
30176
|
lines2.push(` ${rangeStr} ${kindStr} ${sym.name} (${bodyLen}\u2113)${docFirst}${statsStr}`);
|
|
29967
30177
|
}
|
|
29968
30178
|
const text = guardText(staleWarning(resolved) + lines2.join("\n"), "symbol");
|
|
@@ -46972,21 +47182,23 @@ function createMcpServer() {
|
|
|
46972
47182
|
server.registerTool(
|
|
46973
47183
|
"read",
|
|
46974
47184
|
{
|
|
46975
|
-
description: "Read one symbol's full body, given a spec of the form file::symbol, or a line range file@N-M / file@N, or a bare file path.",
|
|
47185
|
+
description: "Read one symbol's full body, given a spec of the form file::symbol, or a line range file@N-M / file@N, or a bare file path. Pass a comma-separated spec (file::a,b) to fetch several symbols' bodies from one file in a single call.",
|
|
46976
47186
|
inputSchema: {
|
|
46977
|
-
spec: external_exports.string().describe("file::symbol, file@N-M, file@N,
|
|
47187
|
+
spec: external_exports.string().describe("file::symbol, file@N-M, file@N, a bare file path, or comma-separated file::a,b for a merged multi-symbol view"),
|
|
46978
47188
|
json: external_exports.boolean().optional().describe("output as JSON"),
|
|
46979
47189
|
forceRefresh: external_exports.boolean().optional().describe("reparse file from disk before querying (ignore stale index)"),
|
|
47190
|
+
stats: external_exports.boolean().optional().describe("add per-symbol reference count and doc-coverage flag"),
|
|
46980
47191
|
projectRoot: projectRootField
|
|
46981
47192
|
}
|
|
46982
47193
|
},
|
|
46983
47194
|
(args) => {
|
|
46984
|
-
const { spec, json: json2, forceRefresh, projectRoot } = args;
|
|
47195
|
+
const { spec, json: json2, forceRefresh, stats, projectRoot } = args;
|
|
46985
47196
|
return toCallToolResult(
|
|
46986
47197
|
runRead({
|
|
46987
47198
|
spec,
|
|
46988
47199
|
...json2 === true ? { json: true } : {},
|
|
46989
47200
|
...forceRefresh === true ? { forceRefresh: true } : {},
|
|
47201
|
+
...stats === true ? { stats: true } : {},
|
|
46990
47202
|
...projectRoot !== void 0 ? { projectRoot } : {}
|
|
46991
47203
|
})
|
|
46992
47204
|
);
|
|
@@ -63766,8 +63978,8 @@ function formatTopFiles(ranked) {
|
|
|
63766
63978
|
if (ranked.length === 0) return "";
|
|
63767
63979
|
const lines2 = ["Top files this session:"];
|
|
63768
63980
|
for (const { path: filePath, count } of ranked) {
|
|
63769
|
-
const
|
|
63770
|
-
lines2.push(` ${count.toString().padStart(3)}x ${
|
|
63981
|
+
const basename21 = path48.basename(filePath);
|
|
63982
|
+
lines2.push(` ${count.toString().padStart(3)}x ${basename21} (${filePath})`);
|
|
63771
63983
|
}
|
|
63772
63984
|
return lines2.join("\n");
|
|
63773
63985
|
}
|
|
@@ -72708,9 +72920,16 @@ function buildProgram() {
|
|
|
72708
72920
|
)
|
|
72709
72921
|
);
|
|
72710
72922
|
program2.command("read <spec>").description(
|
|
72711
|
-
"read one symbol's full body (spec: file::symbol; disambiguate a name shared by several classes with file::Parent.symbol)"
|
|
72712
|
-
).option("-j, --json", "output as JSON").option("--force-refresh", "reparse file from disk before querying (ignore stale index)").action(
|
|
72713
|
-
(spec, opts) => runExitText(
|
|
72923
|
+
"read one symbol's full body (spec: file::symbol; disambiguate a name shared by several classes with file::Parent.symbol; comma-separated file::a,b for a merged multi-symbol view)"
|
|
72924
|
+
).option("-j, --json", "output as JSON").option("--force-refresh", "reparse file from disk before querying (ignore stale index)").option("--stats", "add per-symbol reference count and doc-coverage flag").action(
|
|
72925
|
+
(spec, opts) => runExitText(
|
|
72926
|
+
() => runRead({
|
|
72927
|
+
spec,
|
|
72928
|
+
...opts.json === true ? { json: true } : {},
|
|
72929
|
+
...opts.forceRefresh === true ? { forceRefresh: true } : {},
|
|
72930
|
+
...opts.stats === true ? { stats: true } : {}
|
|
72931
|
+
})
|
|
72932
|
+
)
|
|
72714
72933
|
);
|
|
72715
72934
|
program2.command("brief <spec>").description("symbol body + callers + containing doc section in one call (spec: file::symbol)").option("-j, --json", "output as JSON").option("--limit <n>", "max callers to show (default: 20)").action(
|
|
72716
72935
|
(spec, opts) => runExit(
|
|
@@ -73262,7 +73481,7 @@ init_hooks_common();
|
|
|
73262
73481
|
init_config();
|
|
73263
73482
|
init_index_reader();
|
|
73264
73483
|
init_constants();
|
|
73265
|
-
var GENERIC_REMINDER = 'token-goat: prefer surgical reads over Read/Grep on this codebase -- `token-goat symbol <name>`, `token-goat read "file::symbol"`, `token-goat section "file::Heading"`, `token-goat semantic "description"`, `token-goat outline <file>`. Run `token-goat index .` if this project is not indexed yet.';
|
|
73484
|
+
var GENERIC_REMINDER = 'token-goat: prefer surgical reads over the Read/Grep tools on this codebase; shell commands like `rg`, `grep`, `fd`, `sed`, `cat`, `find`, and `ls` are just commands, not tool names -- `token-goat symbol <name>`, `token-goat read "file::symbol"`, `token-goat section "file::Heading"`, `token-goat semantic "description"`, `token-goat outline <file>`. Run `token-goat index .` if this project is not indexed yet.';
|
|
73266
73485
|
function buildReminder(cwd) {
|
|
73267
73486
|
if (cwd === void 0) return GENERIC_REMINDER;
|
|
73268
73487
|
let symbolCount;
|
|
@@ -73272,7 +73491,7 @@ function buildReminder(cwd) {
|
|
|
73272
73491
|
return GENERIC_REMINDER;
|
|
73273
73492
|
}
|
|
73274
73493
|
if (symbolCount <= 0) return GENERIC_REMINDER;
|
|
73275
|
-
return `token-goat: this project is indexed (${symbolCount} symbols). Prefer \`symbol <name>\`, \`read "file::symbol"\`, \`section "file::Heading"\`, \`semantic "description"\`, or \`outline <file>\` over a full Read/Grep.`;
|
|
73494
|
+
return `token-goat: this project is indexed (${symbolCount} symbols). Prefer \`symbol <name>\`, \`read "file::symbol"\`, \`section "file::Heading"\`, \`semantic "description"\`, or \`outline <file>\` over a full Read/Grep tool call; shell commands like \`rg\`, \`grep\`, \`fd\`, \`sed\`, \`cat\`, \`find\`, and \`ls\` are still just commands.`;
|
|
73276
73495
|
}
|
|
73277
73496
|
function sessionStartHandler(event) {
|
|
73278
73497
|
try {
|
|
@@ -79575,16 +79794,16 @@ function isTempPath(fp) {
|
|
|
79575
79794
|
return /^\/tmp\//i.test(norm) || /\/var\/folders\//i.test(norm) || /AppData\/Local\/Temp\//i.test(norm) || norm.startsWith("/c/Users/") && norm.includes("/AppData/Local/Temp/") || isUnderSystemTemp(fp);
|
|
79576
79795
|
}
|
|
79577
79796
|
function isOrchestratorStateFile(filePath) {
|
|
79578
|
-
const
|
|
79579
|
-
return /^\.improve-state-/.test(
|
|
79797
|
+
const basename21 = (filePath.includes("/") ? filePath.split("/").at(-1) : filePath.split("\\").at(-1)) ?? filePath;
|
|
79798
|
+
return /^\.improve-state-/.test(basename21);
|
|
79580
79799
|
}
|
|
79581
79800
|
function extractCatSourceFile(cmd) {
|
|
79582
79801
|
const m = /^cat\s+(\S+\.(?:java|py|ts|tsx|js|jsx|go|rb|rs|cpp|cc|cxx|c|h|hpp|kt|swift|cs|php|scala|clj|css|scss|sass|less))\s*$/.exec(cmd);
|
|
79583
79802
|
return m?.[1] ?? null;
|
|
79584
79803
|
}
|
|
79585
79804
|
function classifyFileExtensions(filePath) {
|
|
79586
|
-
const
|
|
79587
|
-
const isEnvFile = /^\.env(\.\w+)?$/i.test(
|
|
79805
|
+
const basename21 = (filePath.includes("/") ? filePath.split("/").at(-1) : filePath.split("\\").at(-1)) ?? filePath;
|
|
79806
|
+
const isEnvFile = /^\.env(\.\w+)?$/i.test(basename21);
|
|
79588
79807
|
const hasKnownExt = /\.(?:java|py|ts|tsx|js|jsx|go|rb|rs|cpp|cc|cxx|c|h|hpp|kt|swift|cs|php|scala|clj|css|scss|sass|less|md|mdx|rst|txt|json|yaml|yml|toml|xml|conf|cfg|ini|properties|sql|ps1|psm1|env)$/i.test(filePath);
|
|
79589
79808
|
if (!hasKnownExt && !isEnvFile) return null;
|
|
79590
79809
|
const isSql = /\.sql$/i.test(filePath);
|
|
@@ -81265,8 +81484,8 @@ ${redactSecrets(compressed).text}`
|
|
|
81265
81484
|
}
|
|
81266
81485
|
return passOutput();
|
|
81267
81486
|
}
|
|
81268
|
-
registerHook("pre_tool_use", preMcpHandler);
|
|
81269
|
-
registerHook("post_tool_use", postMcpHandler);
|
|
81487
|
+
registerHook("pre_tool_use", preMcpHandler, { toolPattern: "^mcp__" });
|
|
81488
|
+
registerHook("post_tool_use", postMcpHandler, { toolPattern: "^mcp__" });
|
|
81270
81489
|
|
|
81271
81490
|
// src/hooks_websearch.ts
|
|
81272
81491
|
init_define_import_meta_env();
|
|
@@ -81349,7 +81568,7 @@ function preScreenshotHandler(event) {
|
|
|
81349
81568
|
`${toolName} was called with no destination file, so the screenshot would land raw in context (tens of thousands of tokens). Re-issue it with \`${paramName}\` set to an absolute path, then Read the saved file \u2014 the read is automatically compressed by token-goat's image-shrink pipeline.`
|
|
81350
81569
|
);
|
|
81351
81570
|
}
|
|
81352
|
-
registerHook("pre_tool_use", preScreenshotHandler);
|
|
81571
|
+
registerHook("pre_tool_use", preScreenshotHandler, { toolPattern: "^mcp__" });
|
|
81353
81572
|
|
|
81354
81573
|
// src/hooks_browser_image.ts
|
|
81355
81574
|
init_define_import_meta_env();
|
|
@@ -81427,7 +81646,7 @@ async function postBrowserImageHandler(event) {
|
|
|
81427
81646
|
return passOutput();
|
|
81428
81647
|
}
|
|
81429
81648
|
}
|
|
81430
|
-
registerHook("post_tool_use", postBrowserImageHandler);
|
|
81649
|
+
registerHook("post_tool_use", postBrowserImageHandler, { toolPattern: "^mcp__" });
|
|
81431
81650
|
|
|
81432
81651
|
// src/hooks_agent_spawn.ts
|
|
81433
81652
|
init_define_import_meta_env();
|