@plebeiantech/lat.md 0.12.3-fork.14 → 0.12.3-fork.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/cli/checklist-menu.d.ts +2 -1
- package/dist/src/cli/checklist-menu.js +3 -2
- package/dist/src/cli/index.js +47 -10
- package/dist/src/cli/init-preferences.d.ts +4 -0
- package/dist/src/cli/init-preferences.js +35 -0
- package/dist/src/cli/init.js +7 -1
- package/dist/src/cli/search.js +2 -7
- package/dist/src/cli/ui-build-server.d.ts +12 -0
- package/dist/src/cli/ui-build-server.js +26 -0
- package/dist/src/cli/ui-build.js +1 -1
- package/dist/src/cli/ui.js +1 -1
- package/dist/src/search/query.d.ts +5 -2
- package/dist/src/search/query.js +25 -21
- package/dist/src/source-formats.d.ts +1 -1
- package/dist/src/source-formats.js +2 -0
- package/dist/src/source-parser.js +200 -0
- package/dist/src/view/client/assets/GraphView-BuZg_wrj.js +456 -0
- package/dist/src/view/client/assets/{MarkdownEditor-B7quqPb8.js → MarkdownEditor-BKqJtZYv.js} +8 -8
- package/dist/src/view/client/assets/_commonjsHelpers-CqkleIqs.js +1 -0
- package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-CAu3KwfO.js +1 -0
- package/dist/src/view/client/assets/{arc-BnwR8Bu7.js → arc-CFnPZhKM.js} +1 -1
- package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-Cf9Kd0OA.js +36 -0
- package/dist/src/view/client/assets/{blockDiagram-I7D4REHJ-DETl8e_H.js → blockDiagram-I7D4REHJ-dPn7g_vm.js} +2 -2
- package/dist/src/view/client/assets/{c4Diagram-7LVT6UL2-DJRAT1Ve.js → c4Diagram-7LVT6UL2-DdZrwaPd.js} +2 -2
- package/dist/src/view/client/assets/channel-C-byJRR7.js +1 -0
- package/dist/src/view/client/assets/{chunk-2Q5K7J3B-C0TmOC1Q.js → chunk-2Q5K7J3B-C42JuteH.js} +1 -1
- package/dist/src/view/client/assets/{chunk-5VM5RSS4-dfBOrYE6.js → chunk-5VM5RSS4-BKK3z8Zy.js} +1 -1
- package/dist/src/view/client/assets/{chunk-F27PBJKO-DAnks99K.js → chunk-F27PBJKO-qZl_uKcW.js} +1 -1
- package/dist/src/view/client/assets/{chunk-IMKFNOWR-CPjB07if.js → chunk-IMKFNOWR-Bs4Rnoj_.js} +1 -1
- package/dist/src/view/client/assets/{chunk-JWPE2WC7-VvU_gZI6.js → chunk-JWPE2WC7-BpxgV2rA.js} +1 -1
- package/dist/src/view/client/assets/{chunk-POPQ4Y6H-DDUbVF55.js → chunk-POPQ4Y6H-hIynofdE.js} +1 -1
- package/dist/src/view/client/assets/{chunk-SVP7TREG-BHROkr6D.js → chunk-SVP7TREG-t3gKMqeu.js} +1 -1
- package/dist/src/view/client/assets/{chunk-TICWLB2K-95PzGIOg.js → chunk-TICWLB2K-B2x394mh.js} +1 -1
- package/dist/src/view/client/assets/{chunk-XXDRQBXY-MdmuLhIs.js → chunk-XXDRQBXY-CHaVKDsH.js} +1 -1
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-FlqGrEwv.js +1 -0
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-FlqGrEwv.js +1 -0
- package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-DE2-Jgqu.js +1 -0
- package/dist/src/view/client/assets/{cynefin-OW5HDTMX-CeA8IKWo.js → cynefin-OW5HDTMX-BsEtOvRy.js} +1 -1
- package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-BKYG1Xs8.js +62 -0
- package/dist/src/view/client/assets/{dagre-GXQ25YYZ-DLQwTa3H.js → dagre-GXQ25YYZ-hgrdNjl7.js} +2 -2
- package/dist/src/view/client/assets/{diagram-S7CK7UJ4-kbKdIyXG.js → diagram-S7CK7UJ4-VIx8zAxf.js} +2 -2
- package/dist/src/view/client/assets/diagram-UQ7AKVKN-yfloehRm.js +41 -0
- package/dist/src/view/client/assets/{diagram-VSXAHHWV-EXJTU8qq.js → diagram-VSXAHHWV-BT_dA4Q9.js} +2 -2
- package/dist/src/view/client/assets/diagram-VX7I27RA-Gfmwxx6u.js +24 -0
- package/dist/src/view/client/assets/diagram-Z3DM3KII-C2yM7EOo.js +24 -0
- package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-Bkb_Lj59.js +1 -0
- package/dist/src/view/client/assets/{erDiagram-RLTQ6QDP-C925J5A3.js → erDiagram-RLTQ6QDP-C7wQHPye.js} +2 -2
- package/dist/src/view/client/assets/{flowDiagram-HODETNUW-DzoCa-Nq.js → flowDiagram-HODETNUW-CXoKr3oI.js} +1 -1
- package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-DqqXKgLa.js +292 -0
- package/dist/src/view/client/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/src/view/client/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/src/view/client/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/src/view/client/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/dist/src/view/client/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/dist/src/view/client/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-D_DAhSgZ.js +106 -0
- package/dist/src/view/client/assets/index-DAxFk0q-.css +1 -0
- package/dist/src/view/client/assets/index-DPuOWFj2.js +10 -0
- package/dist/src/view/client/assets/infoDiagram-27XIBGKW-B50EOats.js +2 -0
- package/dist/src/view/client/assets/{ishikawaDiagram-5VMMS53U-CW4mto2d.js → ishikawaDiagram-5VMMS53U-D1rny9gj.js} +2 -2
- package/dist/src/view/client/assets/{journeyDiagram-3NMN7TZE-8R4eacFW.js → journeyDiagram-3NMN7TZE-B5UD2Xo4.js} +2 -2
- package/dist/src/view/client/assets/{kanban-definition-UXKFOSKX-Cy9ioXEJ.js → kanban-definition-UXKFOSKX-CTgey9zw.js} +6 -6
- package/dist/src/view/client/assets/{layout-C0MFuhth.js → layout-4X2n4os-.js} +1 -1
- package/dist/src/view/client/assets/{linear-Dv3N4dQR.js → linear-D0RIBXsp.js} +1 -1
- package/dist/src/view/client/assets/{maplibre-gl-DnqZgfUS.js → maplibre-gl-CDX6Zuow.js} +1 -1
- package/dist/src/view/client/assets/{mermaid.core-bds9A7e2.js → mermaid.core-BAnH8y-D.js} +11 -11
- package/dist/src/view/client/assets/{mindmap-definition-YA3MSWOX-DjmGW355.js → mindmap-definition-YA3MSWOX-WiFsh3Jg.js} +2 -2
- package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-DCJOrckP.js +1 -0
- package/dist/src/view/client/assets/{pieDiagram-E7YTZNPT-CCH2gGR-.js → pieDiagram-E7YTZNPT-C78IkUE2.js} +2 -2
- package/dist/src/view/client/assets/{quadrantDiagram-AXDQQJYC-CjocPJFz.js → quadrantDiagram-AXDQQJYC-xZ6guleB.js} +4 -4
- package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-D3PwmgX0.js +1 -0
- package/dist/src/view/client/assets/{requirementDiagram-BXWQKSXE-Ct6AoXRr.js → requirementDiagram-BXWQKSXE-v-I8wLGH.js} +2 -2
- package/dist/src/view/client/assets/{sankeyDiagram-P5KCCOFB-CIpgGN_w.js → sankeyDiagram-P5KCCOFB-DBY-sdO7.js} +2 -2
- package/dist/src/view/client/assets/{sequenceDiagram-WJ2MYXX4-DrmLFj6w.js → sequenceDiagram-WJ2MYXX4-D9HApBFi.js} +2 -2
- package/dist/src/view/client/assets/sizeCapture-INFHLROL-ERAytLnQ.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-D77RDMKH-BKef_Qwv.js +1 -0
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-BePfayWI.js +1 -0
- package/dist/src/view/client/assets/swimlanes-42K2YHIH-D7dS_tnF.js +1 -0
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-DaqCEguT.js +8 -0
- package/dist/src/view/client/assets/{timeline-definition-24CTP7MA-BExPu6X5.js → timeline-definition-24CTP7MA-Di1UCseG.js} +2 -2
- package/dist/src/view/client/assets/{vennDiagram-4TSXK5OY-PC1MU3si.js → vennDiagram-4TSXK5OY-g7Je3H2H.js} +2 -2
- package/dist/src/view/client/assets/{wardleyDiagram-VM6X3IG4-DNWqU3fa.js → wardleyDiagram-VM6X3IG4-C_diPEka.js} +2 -2
- package/dist/src/view/client/assets/{xychartDiagram-S5SC5T6Z-E1uA28_D.js → xychartDiagram-S5SC5T6Z-C8uIQy_I.js} +2 -2
- package/dist/src/view/client/index.html +2 -2
- package/dist/src/view/document-route.d.ts +2 -0
- package/dist/src/view/document-route.js +40 -7
- package/dist/src/view/graph.d.ts +2 -2
- package/dist/src/view/graph.js +7 -3
- package/dist/src/view/highlight.js +205 -203
- package/dist/src/view/markdown.js +4 -0
- package/dist/src/view/preindexed-search.d.ts +15 -0
- package/dist/src/view/preindexed-search.js +25 -0
- package/dist/src/view/protocol.d.ts +3 -0
- package/dist/src/view/references.js +3 -4
- package/dist/src/view/search-result.d.ts +4 -0
- package/dist/src/view/search-result.js +20 -0
- package/dist/src/view/search.d.ts +7 -2
- package/dist/src/view/search.js +23 -30
- package/dist/src/view/server-build.d.ts +21 -0
- package/dist/src/view/server-build.js +145 -0
- package/dist/src/view/server-deployment.d.ts +32 -0
- package/dist/src/view/server-deployment.js +133 -0
- package/dist/src/view/server-index-worker.d.ts +6 -0
- package/dist/src/view/server-index-worker.js +14 -0
- package/dist/src/view/server.d.ts +1 -1
- package/dist/src/view/server.js +26 -8
- package/dist/src/view/static-build.d.ts +16 -1
- package/dist/src/view/static-build.js +187 -89
- package/dist/src/view/static-protocol.d.ts +7 -0
- package/dist/src/view/static-protocol.js +5 -0
- package/dist/src/view/store.js +14 -4
- package/dist/src/view/vercel-build.d.ts +24 -0
- package/dist/src/view/vercel-build.js +133 -0
- package/dist/src/view/vercel-server-build.d.ts +10 -0
- package/dist/src/view/vercel-server-build.js +61 -0
- package/dist/vendor/lat.md-server/cli.d.ts +2 -0
- package/dist/vendor/lat.md-server/cli.js +12 -0
- package/dist/vendor/lat.md-server/index.d.ts +38 -0
- package/dist/vendor/lat.md-server/index.js +128 -0
- package/package.json +19 -5
- package/dist/src/view/client/assets/abnfDiagram-VCTEODGH-V7-T6qsl.js +0 -1
- package/dist/src/view/client/assets/architectureDiagram-5GKGNRK7-u97vDna9.js +0 -36
- package/dist/src/view/client/assets/channel-BwQbnWCN.js +0 -1
- package/dist/src/view/client/assets/classDiagram-ZZMXUADV-HvQKkIS-.js +0 -1
- package/dist/src/view/client/assets/classDiagram-v2-VYDZK3BY-HvQKkIS-.js +0 -1
- package/dist/src/view/client/assets/cose-bilkent-JH36ORCC-CauUf_rN.js +0 -1
- package/dist/src/view/client/assets/cynefinDiagram-5FMLGOSQ-L1rtcT8l.js +0 -62
- package/dist/src/view/client/assets/diagram-UQ7AKVKN-kmzp92RC.js +0 -41
- package/dist/src/view/client/assets/diagram-VX7I27RA-DAiIyMCG.js +0 -24
- package/dist/src/view/client/assets/diagram-Z3DM3KII-G9wz50ZV.js +0 -24
- package/dist/src/view/client/assets/ebnfDiagram-PWID7BFC-D2tVRCNA.js +0 -1
- package/dist/src/view/client/assets/ganttDiagram-EL5Y4UJY-D2ebbg4p.js +0 -292
- package/dist/src/view/client/assets/gitGraphDiagram-WWUBYQGX-B4QratYy.js +0 -106
- package/dist/src/view/client/assets/index-D0ajr_Ja.css +0 -1
- package/dist/src/view/client/assets/index-KZcnpXJH.js +0 -321
- package/dist/src/view/client/assets/infoDiagram-27XIBGKW-DL4mtHkt.js +0 -2
- package/dist/src/view/client/assets/pegDiagram-XKGWAZYB-BWsZp0ab.js +0 -1
- package/dist/src/view/client/assets/railroadDiagram-O6MQD6OU-BjLeb2KF.js +0 -1
- package/dist/src/view/client/assets/sizeCapture-INFHLROL-BdFMe2Lr.js +0 -1
- package/dist/src/view/client/assets/stateDiagram-D77RDMKH-Zd9F1goW.js +0 -1
- package/dist/src/view/client/assets/stateDiagram-v2-MP3YSRHH-ByIKCftl.js +0 -1
- package/dist/src/view/client/assets/swimlanes-42K2YHIH-a7VFwi00.js +0 -1
- package/dist/src/view/client/assets/swimlanesDiagram-VR7AAH4N-CzxaUHB-.js +0 -8
- /package/dist/src/view/client/assets/{logo-small-RR_KBOAT.svg → logo-RR_KBOAT.svg} +0 -0
|
@@ -5,8 +5,9 @@ export interface ChecklistOption {
|
|
|
5
5
|
/**
|
|
6
6
|
* Display an interactive multi-select checklist with arrow-key navigation.
|
|
7
7
|
* Returns an array of checked values.
|
|
8
|
+
* Known initial values start checked; unknown values are ignored.
|
|
8
9
|
*
|
|
9
10
|
* Keys: Up/Down (j/k) to move, Space to toggle, Enter to confirm, Ctrl+C to exit.
|
|
10
11
|
* Non-TTY fallback: returns [].
|
|
11
12
|
*/
|
|
12
|
-
export declare function checklistMenu(options: ChecklistOption[], prompt?: string): Promise<string[]>;
|
|
13
|
+
export declare function checklistMenu(options: ChecklistOption[], prompt?: string, initialValues?: readonly string[]): Promise<string[]>;
|
|
@@ -2,18 +2,19 @@ import { styleText } from 'node:util';
|
|
|
2
2
|
/**
|
|
3
3
|
* Display an interactive multi-select checklist with arrow-key navigation.
|
|
4
4
|
* Returns an array of checked values.
|
|
5
|
+
* Known initial values start checked; unknown values are ignored.
|
|
5
6
|
*
|
|
6
7
|
* Keys: Up/Down (j/k) to move, Space to toggle, Enter to confirm, Ctrl+C to exit.
|
|
7
8
|
* Non-TTY fallback: returns [].
|
|
8
9
|
*/
|
|
9
|
-
export async function checklistMenu(options, prompt) {
|
|
10
|
+
export async function checklistMenu(options, prompt, initialValues = []) {
|
|
10
11
|
if (options.length === 0)
|
|
11
12
|
return [];
|
|
12
13
|
if (!process.stdin.isTTY)
|
|
13
14
|
return [];
|
|
14
15
|
return new Promise((resolve) => {
|
|
15
16
|
let cursor = 0;
|
|
16
|
-
const checked = new Set();
|
|
17
|
+
const checked = new Set(options.flatMap((option, index) => initialValues.includes(option.value) ? [index] : []));
|
|
17
18
|
const stdin = process.stdin;
|
|
18
19
|
const wasRaw = stdin.isRaw;
|
|
19
20
|
stdin.setRawMode(true);
|
package/dist/src/cli/index.js
CHANGED
|
@@ -19,6 +19,18 @@ function parsePort(value) {
|
|
|
19
19
|
}
|
|
20
20
|
return port;
|
|
21
21
|
}
|
|
22
|
+
function parseUiServerBuildTarget(value) {
|
|
23
|
+
if (value !== 'node' && value !== 'vercel') {
|
|
24
|
+
throw new InvalidArgumentError('target must be node or vercel');
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
function configureUiRun(command) {
|
|
29
|
+
return command
|
|
30
|
+
.option('--logo-text <text>', 'top-left logo text')
|
|
31
|
+
.option('--no-git', 'disable Git working-tree integration')
|
|
32
|
+
.option('--port <number>', 'server port (default: 4242; explicit ports are strict)', parsePort);
|
|
33
|
+
}
|
|
22
34
|
function parseSimilarityThreshold(value) {
|
|
23
35
|
const threshold = Number(value);
|
|
24
36
|
if (!Number.isFinite(threshold) || threshold < 0 || threshold > 1) {
|
|
@@ -108,27 +120,52 @@ program
|
|
|
108
120
|
const { sectionCommand } = await import('./section.js');
|
|
109
121
|
handleResult(await sectionCommand(ctx, query));
|
|
110
122
|
});
|
|
111
|
-
|
|
112
|
-
.command('ui')
|
|
113
|
-
.description('Open lat.md in a local browser')
|
|
114
|
-
.option('--logo-text <text>', 'top-left logo text')
|
|
115
|
-
.option('--port <number>', 'server port (default: 4242; explicit ports are strict)', parsePort)
|
|
116
|
-
.action(async (opts) => {
|
|
123
|
+
async function runUi(opts) {
|
|
117
124
|
const ctx = resolveContext(program.opts());
|
|
118
125
|
const { uiCommand } = await import('./ui.js');
|
|
119
|
-
handleResult(await uiCommand(ctx, {
|
|
126
|
+
handleResult(await uiCommand(ctx, {
|
|
127
|
+
git: opts.git,
|
|
128
|
+
logoText: opts.logoText,
|
|
129
|
+
port: opts.port,
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
const ui = configureUiRun(program.command('ui').description('Run or build the Lat UI')).action(runUi);
|
|
133
|
+
configureUiRun(ui.command('run').description('Run the local Lat UI server')).action(async (opts) => {
|
|
134
|
+
await runUi(opts);
|
|
120
135
|
});
|
|
121
|
-
ui.command('build')
|
|
122
|
-
|
|
123
|
-
.
|
|
136
|
+
const uiBuild = ui.command('build').description('Build a deployable Lat UI');
|
|
137
|
+
uiBuild
|
|
138
|
+
.command('static')
|
|
139
|
+
.description('Build a fully static, read-only Lat UI')
|
|
140
|
+
.argument('[output]', 'output directory relative to the project (default: .lat-build/static)', '.lat-build/static')
|
|
124
141
|
.option('--base <path>', 'deployment base path', '/')
|
|
142
|
+
.option('--force', 'replace an existing output path')
|
|
125
143
|
.option('--logo-text <text>', 'top-left logo text')
|
|
126
144
|
.action(async (output, opts) => {
|
|
127
145
|
const ctx = resolveContext(program.opts());
|
|
128
146
|
const { uiBuildCommand } = await import('./ui-build.js');
|
|
129
147
|
handleResult(await uiBuildCommand(ctx, output, {
|
|
130
148
|
basePath: opts.base,
|
|
149
|
+
force: opts.force,
|
|
150
|
+
logoText: opts.logoText ?? ui.opts().logoText,
|
|
151
|
+
}));
|
|
152
|
+
});
|
|
153
|
+
uiBuild
|
|
154
|
+
.command('server')
|
|
155
|
+
.description('Build a static Lat UI with a portable search server')
|
|
156
|
+
.argument('[output]', 'output directory (default: .lat-build/server for node, .vercel/output for vercel)')
|
|
157
|
+
.option('--base <path>', 'deployment base path', '/')
|
|
158
|
+
.option('--force', 'replace an existing output path')
|
|
159
|
+
.option('--logo-text <text>', 'top-left logo text')
|
|
160
|
+
.option('--target <target>', 'deployment target: node or vercel', parseUiServerBuildTarget, 'node')
|
|
161
|
+
.action(async (output, opts) => {
|
|
162
|
+
const ctx = resolveContext(program.opts());
|
|
163
|
+
const { uiBuildServerCommand } = await import('./ui-build-server.js');
|
|
164
|
+
handleResult(await uiBuildServerCommand(ctx, output, {
|
|
165
|
+
basePath: opts.base,
|
|
166
|
+
force: opts.force,
|
|
131
167
|
logoText: opts.logoText ?? ui.opts().logoText,
|
|
168
|
+
target: opts.target,
|
|
132
169
|
}));
|
|
133
170
|
});
|
|
134
171
|
program
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Read machine-local checklist defaults without inferring installed agents. */
|
|
2
|
+
export declare function readInitAgents(latDir: string): string[];
|
|
3
|
+
/** Update just the confirmed selection, preserving other YAML and comments. */
|
|
4
|
+
export declare function writeInitAgents(latDir: string, agents: string[]): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { isMap, parseDocument } from 'yaml';
|
|
4
|
+
function readPreferences(latDir) {
|
|
5
|
+
const path = join(latDir, 'config.local.yaml');
|
|
6
|
+
const document = parseDocument(existsSync(path) ? readFileSync(path, 'utf8') : '');
|
|
7
|
+
if (document.errors.length > 0) {
|
|
8
|
+
throw new Error(`Cannot parse ${path}: ${document.errors[0].message}`);
|
|
9
|
+
}
|
|
10
|
+
if (document.contents !== null && !isMap(document.contents)) {
|
|
11
|
+
throw new Error(`${path} must be a mapping`);
|
|
12
|
+
}
|
|
13
|
+
if (document.has('init') && !isMap(document.get('init', true))) {
|
|
14
|
+
throw new Error(`${path}: init must be a mapping`);
|
|
15
|
+
}
|
|
16
|
+
return { path, document };
|
|
17
|
+
}
|
|
18
|
+
/** Read machine-local checklist defaults without inferring installed agents. */
|
|
19
|
+
export function readInitAgents(latDir) {
|
|
20
|
+
const { path, document } = readPreferences(latDir);
|
|
21
|
+
const agents = document.toJS()?.init?.agents;
|
|
22
|
+
if (agents === undefined)
|
|
23
|
+
return [];
|
|
24
|
+
if (!Array.isArray(agents) ||
|
|
25
|
+
agents.some((agent) => typeof agent !== 'string')) {
|
|
26
|
+
throw new Error(`${path}: init.agents must be a list of strings`);
|
|
27
|
+
}
|
|
28
|
+
return agents;
|
|
29
|
+
}
|
|
30
|
+
/** Update just the confirmed selection, preserving other YAML and comments. */
|
|
31
|
+
export function writeInitAgents(latDir, agents) {
|
|
32
|
+
const { path, document } = readPreferences(latDir);
|
|
33
|
+
document.setIn(['init', 'agents'], agents);
|
|
34
|
+
writeFileSync(path, document.toString());
|
|
35
|
+
}
|
package/dist/src/cli/init.js
CHANGED
|
@@ -18,6 +18,7 @@ import { checklistMenu } from './checklist-menu.js';
|
|
|
18
18
|
import { writeForkInstructions } from './fork-instructions.js';
|
|
19
19
|
import { offerRequireMode, writeForkScaffold } from './fork-scaffold.js';
|
|
20
20
|
import { setupAntigravity } from '../fork/antigravity-init.js';
|
|
21
|
+
import { readInitAgents, writeInitAgents } from './init-preferences.js';
|
|
21
22
|
async function confirm(rl, message) {
|
|
22
23
|
while (true) {
|
|
23
24
|
let answer;
|
|
@@ -916,6 +917,7 @@ export async function initCmd(targetDir) {
|
|
|
916
917
|
writeForkScaffold(latDir);
|
|
917
918
|
}
|
|
918
919
|
ensureLatLocalConfigIgnored(latDir);
|
|
920
|
+
ensureGitignored(root, '.lat-build');
|
|
919
921
|
// Step 2: Configure fresh/outdated setups, ask interactive users about an
|
|
920
922
|
// available key, and offer to rebuild an index whose backend differs. This
|
|
921
923
|
// happens before agent selection so "no agents" still completes it.
|
|
@@ -931,7 +933,7 @@ export async function initCmd(targetDir) {
|
|
|
931
933
|
{ label: 'Codex', value: 'codex' },
|
|
932
934
|
{ label: 'Antigravity / Gemini', value: 'antigravity' },
|
|
933
935
|
];
|
|
934
|
-
const selectedAgents = await checklistMenu(allAgents, 'Which coding agents do you use?');
|
|
936
|
+
const selectedAgents = await checklistMenu(allAgents, 'Which coding agents do you use?', readInitAgents(latDir));
|
|
935
937
|
const useClaudeCode = selectedAgents.includes('claude');
|
|
936
938
|
const usePi = selectedAgents.includes('pi');
|
|
937
939
|
const useCursor = selectedAgents.includes('cursor');
|
|
@@ -978,6 +980,8 @@ export async function initCmd(targetDir) {
|
|
|
978
980
|
// agent. Stamp the version so future non-interactive runs do not reapply
|
|
979
981
|
// fresh/outdated defaults and overwrite the chosen backend.
|
|
980
982
|
writeInitMeta(latDir, {});
|
|
983
|
+
if (interactive)
|
|
984
|
+
writeInitAgents(latDir, selectedAgents);
|
|
981
985
|
console.log('');
|
|
982
986
|
console.log(styleText('dim', 'No agents selected. You can re-run') +
|
|
983
987
|
' lat init ' +
|
|
@@ -1049,6 +1053,8 @@ export async function initCmd(targetDir) {
|
|
|
1049
1053
|
await writeForkInstructions(root, latDir, fileHashes, ask);
|
|
1050
1054
|
// Record init version and file hashes so `lat check` can detect stale setups
|
|
1051
1055
|
writeInitMeta(latDir, fileHashes);
|
|
1056
|
+
if (interactive)
|
|
1057
|
+
writeInitAgents(latDir, selectedAgents);
|
|
1052
1058
|
console.log('');
|
|
1053
1059
|
console.log(styleText('green', 'Done!') +
|
|
1054
1060
|
' Run ' +
|
package/dist/src/cli/search.js
CHANGED
|
@@ -5,7 +5,7 @@ import { getLlmKey } from '../config.js';
|
|
|
5
5
|
import { embedderForIndex, modelKey, ReindexRequiredError, EmbeddingAuthError, } from '../search/embedder.js';
|
|
6
6
|
import { indexSections } from '../search/index.js';
|
|
7
7
|
import { searchSections } from '../search/search.js';
|
|
8
|
-
import { searchIndexedSections } from '../search/query.js';
|
|
8
|
+
import { resolveSearchMatches, searchIndexedSections, } from '../search/query.js';
|
|
9
9
|
import { analyzeMarkdownProject, commandProjectAnalysis, } from '../project-analysis.js';
|
|
10
10
|
import { formatSectionPreview, formatNavHints } from '../format.js';
|
|
11
11
|
import { provenanceNote, formatProvenanceNote } from './check-status.js';
|
|
@@ -97,12 +97,7 @@ export async function runSearch(latDir, query, limit, progress, opts) {
|
|
|
97
97
|
const results = await searchSections(db, query, embedder, limit, opts?.threshold);
|
|
98
98
|
return {
|
|
99
99
|
query,
|
|
100
|
-
matches: results.
|
|
101
|
-
const section = analyzed.sectionById.get(result.id.toLowerCase());
|
|
102
|
-
return section
|
|
103
|
-
? [{ section, reason: 'semantic match', score: result.score }]
|
|
104
|
-
: [];
|
|
105
|
-
}),
|
|
100
|
+
matches: resolveSearchMatches(results, analyzed.sectionById),
|
|
106
101
|
};
|
|
107
102
|
});
|
|
108
103
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CmdContext, CmdResult } from '../context.js';
|
|
2
|
+
import { buildServerView, type ServerViewBuildOptions, type ServerViewBuildResult } from '../view/server-build.js';
|
|
3
|
+
export type ServerViewBuildTarget = 'node' | 'vercel';
|
|
4
|
+
export type UiBuildServerOptions = ServerViewBuildOptions & {
|
|
5
|
+
target?: ServerViewBuildTarget;
|
|
6
|
+
};
|
|
7
|
+
export type UiBuildServerDependencies = {
|
|
8
|
+
buildNode: typeof buildServerView;
|
|
9
|
+
buildVercel?: (ctx: CmdContext, output: string, options: ServerViewBuildOptions) => Promise<ServerViewBuildResult>;
|
|
10
|
+
};
|
|
11
|
+
/** Export immutable UI data with a Node or Vercel semantic-search service. */
|
|
12
|
+
export declare function uiBuildServerCommand(ctx: CmdContext, output: string | undefined, options?: UiBuildServerOptions, dependencies?: UiBuildServerDependencies): Promise<CmdResult>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { buildServerView, } from '../view/server-build.js';
|
|
2
|
+
const defaultDependencies = {
|
|
3
|
+
buildNode: buildServerView,
|
|
4
|
+
};
|
|
5
|
+
/** Export immutable UI data with a Node or Vercel semantic-search service. */
|
|
6
|
+
export async function uiBuildServerCommand(ctx, output, options = {}, dependencies = defaultDependencies) {
|
|
7
|
+
try {
|
|
8
|
+
const { target = 'node', ...buildOptions } = options;
|
|
9
|
+
const resolvedOutput = output ?? (target === 'vercel' ? '.vercel/output' : '.lat-build/server');
|
|
10
|
+
let result;
|
|
11
|
+
if (target === 'vercel') {
|
|
12
|
+
const buildVercel = dependencies.buildVercel ??
|
|
13
|
+
(await import('../view/vercel-server-build.js')).buildVercelServerView;
|
|
14
|
+
result = await buildVercel(ctx, resolvedOutput, buildOptions);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
result = await dependencies.buildNode(ctx, resolvedOutput, buildOptions);
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
output: `Built ${result.documents} documents and ${result.sources} source views for ${target} at ${result.outputDir}`,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
return { output: error.message, isError: true };
|
|
25
|
+
}
|
|
26
|
+
}
|
package/dist/src/cli/ui-build.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { buildStaticView, } from '../view/static-build.js';
|
|
2
2
|
/** Export the current vault as a serverless, read-only Lat UI. */
|
|
3
|
-
export async function uiBuildCommand(ctx, output = 'lat-
|
|
3
|
+
export async function uiBuildCommand(ctx, output = '.lat-build/static', options = {}) {
|
|
4
4
|
try {
|
|
5
5
|
const result = await buildStaticView(ctx, output, options);
|
|
6
6
|
return {
|
package/dist/src/cli/ui.js
CHANGED
|
@@ -38,7 +38,7 @@ export async function uiCommand(ctx, options = {}) {
|
|
|
38
38
|
options.onStarted?.(server);
|
|
39
39
|
const lines = [
|
|
40
40
|
`Viewing lat.md at ${server.url}`,
|
|
41
|
-
'Note:
|
|
41
|
+
'Note: use `lat ui build static` or `lat ui build server` to build a deployable UI',
|
|
42
42
|
];
|
|
43
43
|
try {
|
|
44
44
|
await (options.openBrowser ?? openBrowser)(server.url);
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import type { Section, SectionMatch } from '../lattice-model.js';
|
|
2
2
|
import { type CreateSearchEngine } from './embedder.js';
|
|
3
|
+
import { type SearchResult } from './search.js';
|
|
3
4
|
export type IndexedSearchResult = {
|
|
4
5
|
query: string;
|
|
5
6
|
matches: SectionMatch[];
|
|
6
7
|
};
|
|
7
8
|
export type IndexedSearchSession = {
|
|
8
|
-
search: (query: string, limit: number, threshold?: number) => Promise<
|
|
9
|
+
search: (query: string, limit: number, threshold?: number) => Promise<SearchResult[]>;
|
|
9
10
|
close: () => Promise<void>;
|
|
10
11
|
};
|
|
12
|
+
/** Resolve scored index rows against one already-analyzed project snapshot. */
|
|
13
|
+
export declare function resolveSearchMatches(results: readonly SearchResult[], sectionById: ReadonlyMap<string, Section>): SectionMatch[];
|
|
11
14
|
/** Open one reusable database and embedder for a sequence of index queries. */
|
|
12
|
-
export declare function openIndexedSearchSession(latDir: string,
|
|
15
|
+
export declare function openIndexedSearchSession(latDir: string, options?: {
|
|
13
16
|
cacheDir?: string;
|
|
14
17
|
createSearchEngine?: CreateSearchEngine;
|
|
15
18
|
}): Promise<IndexedSearchSession>;
|
package/dist/src/search/query.js
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import { closeDb, ensureMeta, ensureSectionsSchema, getStoredModel, openDb, } from './db.js';
|
|
2
2
|
import { embedderForIndex } from './embedder.js';
|
|
3
3
|
import { searchSections } from './search.js';
|
|
4
|
+
/** Resolve scored index rows against one already-analyzed project snapshot. */
|
|
5
|
+
export function resolveSearchMatches(results, sectionById) {
|
|
6
|
+
return results.flatMap((result) => {
|
|
7
|
+
const section = sectionById.get(result.id.toLowerCase());
|
|
8
|
+
return section
|
|
9
|
+
? [
|
|
10
|
+
{
|
|
11
|
+
section,
|
|
12
|
+
reason: 'semantic match',
|
|
13
|
+
score: result.score,
|
|
14
|
+
},
|
|
15
|
+
]
|
|
16
|
+
: [];
|
|
17
|
+
});
|
|
18
|
+
}
|
|
4
19
|
/** Open one reusable database and embedder for a sequence of index queries. */
|
|
5
|
-
export async function openIndexedSearchSession(latDir,
|
|
20
|
+
export async function openIndexedSearchSession(latDir, options = {}) {
|
|
6
21
|
const db = openDb(latDir, options.cacheDir);
|
|
7
22
|
let closed = false;
|
|
8
23
|
const close = async () => {
|
|
@@ -16,10 +31,10 @@ export async function openIndexedSearchSession(latDir, sectionById, options = {}
|
|
|
16
31
|
const stored = await getStoredModel(db);
|
|
17
32
|
if (stored === null) {
|
|
18
33
|
return {
|
|
19
|
-
search: async (
|
|
34
|
+
search: async () => {
|
|
20
35
|
if (closed)
|
|
21
36
|
throw new Error('Search session is closed');
|
|
22
|
-
return
|
|
37
|
+
return [];
|
|
23
38
|
},
|
|
24
39
|
close,
|
|
25
40
|
};
|
|
@@ -30,22 +45,7 @@ export async function openIndexedSearchSession(latDir, sectionById, options = {}
|
|
|
30
45
|
async search(query, limit, threshold) {
|
|
31
46
|
if (closed)
|
|
32
47
|
throw new Error('Search session is closed');
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
query,
|
|
36
|
-
matches: results.flatMap((result) => {
|
|
37
|
-
const section = sectionById.get(result.id.toLowerCase());
|
|
38
|
-
return section
|
|
39
|
-
? [
|
|
40
|
-
{
|
|
41
|
-
section,
|
|
42
|
-
reason: 'semantic match',
|
|
43
|
-
score: result.score,
|
|
44
|
-
},
|
|
45
|
-
]
|
|
46
|
-
: [];
|
|
47
|
-
}),
|
|
48
|
-
};
|
|
48
|
+
return searchSections(db, query, embedder, limit, threshold);
|
|
49
49
|
},
|
|
50
50
|
close,
|
|
51
51
|
};
|
|
@@ -57,9 +57,13 @@ export async function openIndexedSearchSession(latDir, sectionById, options = {}
|
|
|
57
57
|
}
|
|
58
58
|
/** Query a finished index and resolve its ids from precomputed section data. */
|
|
59
59
|
export async function searchIndexedSections(latDir, query, limit, sectionById, options = {}) {
|
|
60
|
-
const session = await openIndexedSearchSession(latDir,
|
|
60
|
+
const session = await openIndexedSearchSession(latDir, options);
|
|
61
61
|
try {
|
|
62
|
-
|
|
62
|
+
const results = await session.search(query, limit, options.threshold);
|
|
63
|
+
return {
|
|
64
|
+
query,
|
|
65
|
+
matches: resolveSearchMatches(results, sectionById),
|
|
66
|
+
};
|
|
63
67
|
}
|
|
64
68
|
finally {
|
|
65
69
|
await session.close();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Source file extensions supported by Lat's parser and code-reference scan. */
|
|
2
|
-
export declare const SOURCE_FILE_EXTENSIONS: readonly [".c", ".dart", ".go", ".h", ".java", ".js", ".jsx", ".py", ".rs", ".ts", ".tsx"];
|
|
2
|
+
export declare const SOURCE_FILE_EXTENSIONS: readonly [".c", ".dart", ".go", ".h", ".java", ".js", ".jsx", ".py", ".rake", ".rb", ".rs", ".ts", ".tsx"];
|
|
3
3
|
/** A source extension supported everywhere Lat accepts source files. */
|
|
4
4
|
export type SourceFileExtension = (typeof SOURCE_FILE_EXTENSIONS)[number];
|
|
5
5
|
export declare function isSourceFileExtension(extension: string): extension is SourceFileExtension;
|
|
@@ -34,6 +34,8 @@ const grammarMap = {
|
|
|
34
34
|
'.js': 'tree-sitter-javascript.wasm',
|
|
35
35
|
'.jsx': 'tree-sitter-javascript.wasm',
|
|
36
36
|
'.py': 'tree-sitter-python.wasm',
|
|
37
|
+
'.rake': 'tree-sitter-ruby.wasm',
|
|
38
|
+
'.rb': 'tree-sitter-ruby.wasm',
|
|
37
39
|
'.rs': 'tree-sitter-rust.wasm',
|
|
38
40
|
'.ts': 'tree-sitter-typescript.wasm',
|
|
39
41
|
'.tsx': 'tree-sitter-tsx.wasm',
|
|
@@ -246,6 +248,202 @@ function extractPySymbols(tree) {
|
|
|
246
248
|
}
|
|
247
249
|
return symbols;
|
|
248
250
|
}
|
|
251
|
+
function collectRubyScope(scope, parent, symbols) {
|
|
252
|
+
for (const node of scope.namedChildren) {
|
|
253
|
+
const startLine = node.startPosition.row + 1;
|
|
254
|
+
const endLine = node.endPosition.row + 1;
|
|
255
|
+
const signature = firstLine(node.text);
|
|
256
|
+
if (node.type === 'class' || node.type === 'module') {
|
|
257
|
+
const nameNode = node.childForFieldName('name');
|
|
258
|
+
if (nameNode) {
|
|
259
|
+
let childPart;
|
|
260
|
+
let parentPart;
|
|
261
|
+
if (nameNode.type === 'scope_resolution' &&
|
|
262
|
+
nameNode.namedChildren.length === 2) {
|
|
263
|
+
parentPart = nameNode.namedChildren[0].text;
|
|
264
|
+
childPart = nameNode.namedChildren[1].text;
|
|
265
|
+
symbols.push({
|
|
266
|
+
name: childPart,
|
|
267
|
+
kind: 'class',
|
|
268
|
+
startLine,
|
|
269
|
+
endLine,
|
|
270
|
+
signature,
|
|
271
|
+
});
|
|
272
|
+
symbols.push({
|
|
273
|
+
name: childPart,
|
|
274
|
+
kind: 'class',
|
|
275
|
+
parent: parentPart,
|
|
276
|
+
startLine,
|
|
277
|
+
endLine,
|
|
278
|
+
signature,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
childPart = nameNode.text;
|
|
283
|
+
symbols.push({
|
|
284
|
+
name: childPart,
|
|
285
|
+
kind: 'class',
|
|
286
|
+
startLine,
|
|
287
|
+
endLine,
|
|
288
|
+
signature,
|
|
289
|
+
});
|
|
290
|
+
if (parent) {
|
|
291
|
+
symbols.push({
|
|
292
|
+
name: childPart,
|
|
293
|
+
kind: 'class',
|
|
294
|
+
parent,
|
|
295
|
+
startLine,
|
|
296
|
+
endLine,
|
|
297
|
+
signature,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const body = node.childForFieldName('body');
|
|
302
|
+
if (body) {
|
|
303
|
+
collectRubyScope(body, childPart, symbols);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
else if (node.type === 'method' || node.type === 'singleton_method') {
|
|
308
|
+
const name = extractName(node);
|
|
309
|
+
if (name) {
|
|
310
|
+
symbols.push({
|
|
311
|
+
name,
|
|
312
|
+
kind: parent ? 'method' : 'function',
|
|
313
|
+
...(parent ? { parent } : {}),
|
|
314
|
+
startLine,
|
|
315
|
+
endLine,
|
|
316
|
+
signature,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else if (node.type === 'assignment') {
|
|
321
|
+
const left = node.childForFieldName('left');
|
|
322
|
+
if (left) {
|
|
323
|
+
if (left.type === 'scope_resolution' &&
|
|
324
|
+
left.namedChildren.length === 2) {
|
|
325
|
+
const parentPart = left.namedChildren[0].text;
|
|
326
|
+
const childPart = left.namedChildren[1].text;
|
|
327
|
+
symbols.push({
|
|
328
|
+
name: childPart,
|
|
329
|
+
kind: 'const',
|
|
330
|
+
startLine,
|
|
331
|
+
endLine,
|
|
332
|
+
signature,
|
|
333
|
+
});
|
|
334
|
+
symbols.push({
|
|
335
|
+
name: childPart,
|
|
336
|
+
kind: 'const',
|
|
337
|
+
parent: parentPart,
|
|
338
|
+
startLine,
|
|
339
|
+
endLine,
|
|
340
|
+
signature,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
else if (left.type === 'constant' ||
|
|
344
|
+
(left.type === 'identifier' && /^[A-Z]/.test(left.text))) {
|
|
345
|
+
const name = left.text;
|
|
346
|
+
symbols.push({
|
|
347
|
+
name,
|
|
348
|
+
kind: 'const',
|
|
349
|
+
startLine,
|
|
350
|
+
endLine,
|
|
351
|
+
signature,
|
|
352
|
+
});
|
|
353
|
+
if (parent) {
|
|
354
|
+
symbols.push({
|
|
355
|
+
name,
|
|
356
|
+
kind: 'const',
|
|
357
|
+
parent,
|
|
358
|
+
startLine,
|
|
359
|
+
endLine,
|
|
360
|
+
signature,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
else if (node.type === 'call') {
|
|
367
|
+
const methodNode = node.childForFieldName('method');
|
|
368
|
+
const methodName = methodNode?.text;
|
|
369
|
+
if (methodName === 'task' ||
|
|
370
|
+
methodName === 'multitask' ||
|
|
371
|
+
methodName === 'file') {
|
|
372
|
+
const name = extractRubyRakeName(node);
|
|
373
|
+
if (name) {
|
|
374
|
+
symbols.push({
|
|
375
|
+
name,
|
|
376
|
+
kind: parent ? 'method' : 'function',
|
|
377
|
+
...(parent ? { parent } : {}),
|
|
378
|
+
startLine,
|
|
379
|
+
endLine,
|
|
380
|
+
signature,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
else if (methodName === 'namespace') {
|
|
385
|
+
const name = extractRubyRakeName(node);
|
|
386
|
+
if (name) {
|
|
387
|
+
symbols.push({
|
|
388
|
+
name,
|
|
389
|
+
kind: 'class',
|
|
390
|
+
startLine,
|
|
391
|
+
endLine,
|
|
392
|
+
signature,
|
|
393
|
+
});
|
|
394
|
+
if (parent) {
|
|
395
|
+
symbols.push({
|
|
396
|
+
name,
|
|
397
|
+
kind: 'class',
|
|
398
|
+
parent,
|
|
399
|
+
startLine,
|
|
400
|
+
endLine,
|
|
401
|
+
signature,
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
const block = node.childForFieldName('block') ??
|
|
405
|
+
node.namedChildren.find((n) => n.type === 'do_block' || n.type === 'block');
|
|
406
|
+
if (block) {
|
|
407
|
+
const body = block.childForFieldName('body') ??
|
|
408
|
+
block.namedChildren.find((n) => n.type === 'body_statement' || n.type === 'block_body') ??
|
|
409
|
+
block;
|
|
410
|
+
collectRubyScope(body, name, symbols);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
function extractRubyRakeName(node) {
|
|
418
|
+
const args = node.childForFieldName('arguments');
|
|
419
|
+
if (!args || args.namedChildren.length === 0)
|
|
420
|
+
return null;
|
|
421
|
+
let first = args.namedChildren[0];
|
|
422
|
+
if (first.type === 'pair') {
|
|
423
|
+
first = first.childForFieldName('key') ?? first.namedChildren[0];
|
|
424
|
+
}
|
|
425
|
+
if (!first)
|
|
426
|
+
return null;
|
|
427
|
+
if (first.type === 'simple_symbol') {
|
|
428
|
+
return first.text.replace(/^:/, '');
|
|
429
|
+
}
|
|
430
|
+
if (first.type === 'hash_key_symbol') {
|
|
431
|
+
return first.text.replace(/:$/, '');
|
|
432
|
+
}
|
|
433
|
+
if (first.type === 'string') {
|
|
434
|
+
const content = first.namedChildren.find((c) => c.type === 'string_content');
|
|
435
|
+
return content ? content.text : first.text.replace(/^['"]|['"]$/g, '');
|
|
436
|
+
}
|
|
437
|
+
if (first.type === 'identifier') {
|
|
438
|
+
return first.text;
|
|
439
|
+
}
|
|
440
|
+
return null;
|
|
441
|
+
}
|
|
442
|
+
function extractRubySymbols(tree) {
|
|
443
|
+
const symbols = [];
|
|
444
|
+
collectRubyScope(tree.rootNode, undefined, symbols);
|
|
445
|
+
return symbols;
|
|
446
|
+
}
|
|
249
447
|
function dartDirectChild(node, type) {
|
|
250
448
|
return node.namedChildren.find((child) => child.type === type) ?? null;
|
|
251
449
|
}
|
|
@@ -1102,6 +1300,8 @@ const symbolExtractors = {
|
|
|
1102
1300
|
'.js': extractTsSymbols,
|
|
1103
1301
|
'.jsx': extractTsSymbols,
|
|
1104
1302
|
'.py': extractPySymbols,
|
|
1303
|
+
'.rake': extractRubySymbols,
|
|
1304
|
+
'.rb': extractRubySymbols,
|
|
1105
1305
|
'.rs': extractRustSymbols,
|
|
1106
1306
|
'.ts': extractTsSymbols,
|
|
1107
1307
|
'.tsx': extractTsSymbols,
|