@ridit/lens 0.1.5 → 0.1.7
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/{index.cjs → index.mjs} +917 -66
- package/package.json +5 -6
- package/skills.json +7 -0
- package/src/components/chat/ChatMessage.tsx +6 -0
- package/src/components/chat/ChatOverlays.tsx +28 -1
- package/src/components/chat/ChatRunner.tsx +211 -66
- package/src/index.tsx +60 -60
- package/src/types/chat.ts +18 -1
- package/src/utils/chat.ts +737 -24
- package/src/utils/thinking.tsx +20 -1
- package/tsconfig.json +1 -1
|
@@ -44404,6 +44404,26 @@ var PHRASES = {
|
|
|
44404
44404
|
"chefkiss incoming...",
|
|
44405
44405
|
"slay mode: on...",
|
|
44406
44406
|
"rizzing up an answer...",
|
|
44407
|
+
"rizzing up a baddie answer...",
|
|
44408
|
+
"sigma grindset: activated...",
|
|
44409
|
+
"NPC behavior: disabled...",
|
|
44410
|
+
"unaliving my writer's block...",
|
|
44411
|
+
"caught in 4K thinking...",
|
|
44412
|
+
"delulu but make it accurate...",
|
|
44413
|
+
"ate and left no crumbs...",
|
|
44414
|
+
"rent free in the codebase...",
|
|
44415
|
+
"understood the assignment (fr fr)...",
|
|
44416
|
+
"giving main character energy...",
|
|
44417
|
+
"no thoughts, head full...",
|
|
44418
|
+
"built different response incoming...",
|
|
44419
|
+
"chronically online and loving it...",
|
|
44420
|
+
"touch grass? not yet...",
|
|
44421
|
+
"this response is bussin...",
|
|
44422
|
+
"lowkey highkey computing...",
|
|
44423
|
+
"it's giving Einstein...",
|
|
44424
|
+
"we do a little thinking...",
|
|
44425
|
+
"gigachad analysis mode...",
|
|
44426
|
+
"the audacity to be this smart...",
|
|
44407
44427
|
"consulting the void...",
|
|
44408
44428
|
"asking my other personalities...",
|
|
44409
44429
|
"reading the codebase tea leaves...",
|
|
@@ -48635,11 +48655,11 @@ ${f.content.slice(0, 2000)}
|
|
|
48635
48655
|
\`\`\``).join(`
|
|
48636
48656
|
|
|
48637
48657
|
`);
|
|
48638
|
-
return `You are an expert software engineer assistant with access to the user's codebase and
|
|
48658
|
+
return `You are an expert software engineer assistant with access to the user's codebase and eleven tools.
|
|
48639
48659
|
|
|
48640
48660
|
## TOOLS
|
|
48641
48661
|
|
|
48642
|
-
You have exactly
|
|
48662
|
+
You have exactly eleven tools. To use a tool you MUST wrap it in the exact XML tags shown below — no other format will work.
|
|
48643
48663
|
|
|
48644
48664
|
### 1. fetch — load a URL
|
|
48645
48665
|
<fetch>https://example.com</fetch>
|
|
@@ -48650,19 +48670,47 @@ You have exactly six tools. To use a tool you MUST wrap it in the exact XML tags
|
|
|
48650
48670
|
### 3. read-file — read a file from the repo
|
|
48651
48671
|
<read-file>src/foo.ts</read-file>
|
|
48652
48672
|
|
|
48653
|
-
### 4.
|
|
48673
|
+
### 4. read-folder — list contents of a folder (files + subfolders, one level deep)
|
|
48674
|
+
<read-folder>src/components</read-folder>
|
|
48675
|
+
|
|
48676
|
+
### 5. grep — search for a pattern across files in the repo (cross-platform, no shell needed)
|
|
48677
|
+
<grep>
|
|
48678
|
+
{"pattern": "ChatRunner", "glob": "src/**/*.tsx"}
|
|
48679
|
+
</grep>
|
|
48680
|
+
|
|
48681
|
+
### 6. write-file — create or overwrite a file
|
|
48654
48682
|
<write-file>
|
|
48655
48683
|
{"path": "data/output.csv", "content": "col1,col2
|
|
48656
48684
|
val1,val2"}
|
|
48657
48685
|
</write-file>
|
|
48658
48686
|
|
|
48659
|
-
###
|
|
48687
|
+
### 7. delete-file — permanently delete a single file
|
|
48688
|
+
<delete-file>src/old-component.tsx</delete-file>
|
|
48689
|
+
|
|
48690
|
+
### 8. delete-folder — permanently delete a folder and all its contents
|
|
48691
|
+
<delete-folder>src/legacy</delete-folder>
|
|
48692
|
+
|
|
48693
|
+
### 9. open-url — open a URL in the user's default browser
|
|
48694
|
+
<open-url>https://github.com/owner/repo</open-url>
|
|
48695
|
+
|
|
48696
|
+
### 10. generate-pdf — generate a PDF file from markdown-style content
|
|
48697
|
+
<generate-pdf>
|
|
48698
|
+
{"path": "output/report.pdf", "content": "# Title
|
|
48699
|
+
|
|
48700
|
+
Some body text.
|
|
48701
|
+
|
|
48702
|
+
## Section
|
|
48703
|
+
|
|
48704
|
+
More content."}
|
|
48705
|
+
</generate-pdf>
|
|
48706
|
+
|
|
48707
|
+
### 11. search — search the internet for anything you are unsure about
|
|
48660
48708
|
<search>how to use React useEffect cleanup function</search>
|
|
48661
48709
|
|
|
48662
|
-
###
|
|
48710
|
+
### 11. clone — clone a GitHub repo so you can explore and discuss it
|
|
48663
48711
|
<clone>https://github.com/owner/repo</clone>
|
|
48664
48712
|
|
|
48665
|
-
###
|
|
48713
|
+
### 12. changes — propose code edits (shown as a diff for user approval)
|
|
48666
48714
|
<changes>
|
|
48667
48715
|
{"summary": "what changed and why", "patches": [{"path": "src/foo.ts", "content": "COMPLETE file content", "isNew": false}]}
|
|
48668
48716
|
</changes>
|
|
@@ -48675,16 +48723,47 @@ val1,val2"}
|
|
|
48675
48723
|
4. NEVER print a URL, command, filename, or JSON blob as plain text when you should be using a tool
|
|
48676
48724
|
5. NEVER say "I'll fetch" / "run this command" / "here's the write-file" — just emit the tag
|
|
48677
48725
|
6. NEVER use shell to run git clone — always use the clone tag instead
|
|
48678
|
-
7.
|
|
48679
|
-
8.
|
|
48680
|
-
9.
|
|
48681
|
-
10.
|
|
48682
|
-
11.
|
|
48683
|
-
12.
|
|
48684
|
-
13.
|
|
48685
|
-
14.
|
|
48686
|
-
15.
|
|
48687
|
-
16.
|
|
48726
|
+
7. NEVER use shell to list files or folders (no ls, dir, find, git ls-files, tree) — ALWAYS use read-folder instead
|
|
48727
|
+
8. NEVER use shell to read a file (no cat, type, Get-Content) — ALWAYS use read-file instead
|
|
48728
|
+
9. NEVER use shell grep, findstr, or Select-String to search file contents — ALWAYS use grep instead
|
|
48729
|
+
10. shell is ONLY for running code, installing packages, building, testing — not for filesystem inspection
|
|
48730
|
+
11. write-file content field must be the COMPLETE file content, never empty or placeholder
|
|
48731
|
+
12. After a write-file succeeds, do NOT repeat it — trust the result and move on
|
|
48732
|
+
13. After a write-file succeeds, use read-file to verify the content before telling the user it is done
|
|
48733
|
+
14. NEVER apologize and redo a tool call you already made — if write-file or shell ran and returned a result, it worked, do not run it again
|
|
48734
|
+
15. NEVER say "I made a mistake" and repeat the same tool — one attempt is enough, trust the output
|
|
48735
|
+
16. NEVER second-guess yourself mid-response — commit to your answer
|
|
48736
|
+
17. If a read-folder or read-file returns "not found", accept it and move on — do NOT retry the same path
|
|
48737
|
+
18. If you have already retrieved a result for a path in this conversation, do NOT request it again — use the result you already have
|
|
48738
|
+
17. Every shell command runs from the repo root — \`cd\` has NO persistent effect. NEVER use \`cd\` alone. Use full paths or combine with && e.g. \`cd list && bun run index.ts\`
|
|
48739
|
+
18. write-file paths are relative to the repo root — if creating files in a subfolder write the full relative path e.g. \`list/src/index.tsx\` NOT \`src/index.tsx\`
|
|
48740
|
+
19. When scaffolding a new project in a subfolder, ALL write-file paths must start with that subfolder name e.g. \`list/package.json\`, \`list/src/index.tsx\`
|
|
48741
|
+
20. For JSX/TSX files always use \`.tsx\` extension and include \`/** @jsxImportSource react */\` or ensure tsconfig has jsx set — bun needs this to parse JSX
|
|
48742
|
+
|
|
48743
|
+
## CRITICAL: READ BEFORE YOU WRITE
|
|
48744
|
+
|
|
48745
|
+
These rules are mandatory whenever you plan to edit or create a file:
|
|
48746
|
+
|
|
48747
|
+
### Before modifying ANY existing file:
|
|
48748
|
+
1. ALWAYS use read-file on the exact file you plan to change FIRST
|
|
48749
|
+
2. Study the full current content — understand every import, every export, every type, every existing feature
|
|
48750
|
+
3. Your changes patch MUST preserve ALL existing functionality — do not remove or rewrite things that were not part of the request
|
|
48751
|
+
4. If you are unsure what other files import from the file you are editing, use read-folder on the parent directory first to see what exists nearby, then read-file the relevant ones
|
|
48752
|
+
|
|
48753
|
+
### Before adding a feature that touches multiple files:
|
|
48754
|
+
1. Use read-folder on the relevant directory to see what files exist
|
|
48755
|
+
2. Use read-file on each file you plan to touch
|
|
48756
|
+
3. Only then emit a changes tag — with patches that are surgical additions, not wholesale rewrites
|
|
48757
|
+
|
|
48758
|
+
### The golden rule for write-file and changes:
|
|
48759
|
+
- The output file must contain EVERYTHING the original had, PLUS your new additions
|
|
48760
|
+
- NEVER produce a file that is shorter than the original unless you are explicitly asked to delete things
|
|
48761
|
+
- If you catch yourself rewriting a file from scratch, STOP — go back and read the original first
|
|
48762
|
+
|
|
48763
|
+
## WHEN TO USE read-folder:
|
|
48764
|
+
- Before editing files in an unfamiliar directory — list it first to understand the structure
|
|
48765
|
+
- When a feature spans multiple files and you are not sure what exists
|
|
48766
|
+
- When the user asks you to explore or explain a part of the codebase
|
|
48688
48767
|
|
|
48689
48768
|
## SCAFFOLDING A NEW PROJECT (follow this exactly)
|
|
48690
48769
|
|
|
@@ -48708,14 +48787,28 @@ When the user asks to create a new CLI/app in a subfolder (e.g. "make a todo app
|
|
|
48708
48787
|
|
|
48709
48788
|
- User shares any URL → fetch it immediately
|
|
48710
48789
|
- User asks to run anything → shell it immediately
|
|
48711
|
-
- User asks to
|
|
48790
|
+
- User asks to open a link, open a URL, or visit a website → open-url it immediately, do NOT use fetch
|
|
48791
|
+
- User asks to delete a file → delete-file it immediately (requires approval)
|
|
48792
|
+
- User asks to delete a folder or directory → delete-folder it immediately (requires approval)
|
|
48793
|
+
- User asks to search for a pattern in files, find usages, find where something is defined → grep it immediately, NEVER use shell grep/findstr/Select-String
|
|
48794
|
+
- User asks to read a file → read-file it immediately, NEVER use shell cat/type
|
|
48795
|
+
- User asks what files are in a folder, or to explore/list a directory → read-folder it immediately, NEVER use shell ls/dir/find/git ls-files
|
|
48796
|
+
- User asks to explore a folder or directory → read-folder it immediately
|
|
48712
48797
|
- User asks to save/create/write a file → write-file it immediately, then read-file to verify
|
|
48798
|
+
- User asks to modify/edit/add to an existing file → read-file it FIRST, then emit changes
|
|
48713
48799
|
- User shares a GitHub URL and wants to clone/explore/discuss it → use clone immediately, NEVER use shell git clone
|
|
48714
48800
|
- After clone succeeds, you will see context about the clone in the conversation. Wait for the user to ask a specific question before using any tools. Do NOT auto-read files, do NOT emit any tool tags until the user asks.
|
|
48715
48801
|
- You are unsure about an API, library, error, concept, or piece of code → search it immediately
|
|
48716
48802
|
- User asks about something recent or that you might not know → search it immediately
|
|
48717
48803
|
- You are about to say "I'm not sure" or "I don't know" → search instead of guessing
|
|
48718
48804
|
|
|
48805
|
+
## shell IS ONLY FOR:
|
|
48806
|
+
- Running code: \`node script.js\`, \`bun run dev\`, \`python main.py\`
|
|
48807
|
+
- Installing packages: \`npm install\`, \`pip install\`
|
|
48808
|
+
- Building/testing: \`npm run build\`, \`bun test\`
|
|
48809
|
+
- Git operations other than clone: \`git status\`, \`git log\`, \`git diff\`
|
|
48810
|
+
- Anything that EXECUTES — not reads or lists
|
|
48811
|
+
|
|
48719
48812
|
## CODEBASE
|
|
48720
48813
|
|
|
48721
48814
|
${fileList.length > 0 ? fileList : "(no files indexed)"}
|
|
@@ -48723,6 +48816,337 @@ ${fileList.length > 0 ? fileList : "(no files indexed)"}
|
|
|
48723
48816
|
${historySummary}`;
|
|
48724
48817
|
}
|
|
48725
48818
|
var FEW_SHOT_MESSAGES = [
|
|
48819
|
+
{
|
|
48820
|
+
role: "user",
|
|
48821
|
+
content: "delete src/old-component.tsx"
|
|
48822
|
+
},
|
|
48823
|
+
{
|
|
48824
|
+
role: "assistant",
|
|
48825
|
+
content: "<delete-file>src/old-component.tsx</delete-file>"
|
|
48826
|
+
},
|
|
48827
|
+
{
|
|
48828
|
+
role: "user",
|
|
48829
|
+
content: `Here is the output from delete-file of src/old-component.tsx:
|
|
48830
|
+
|
|
48831
|
+
Deleted: /repo/src/old-component.tsx
|
|
48832
|
+
|
|
48833
|
+
Please continue your response based on this output.`
|
|
48834
|
+
},
|
|
48835
|
+
{
|
|
48836
|
+
role: "assistant",
|
|
48837
|
+
content: "Done — `src/old-component.tsx` has been deleted."
|
|
48838
|
+
},
|
|
48839
|
+
{
|
|
48840
|
+
role: "user",
|
|
48841
|
+
content: "delete the legacy folder"
|
|
48842
|
+
},
|
|
48843
|
+
{
|
|
48844
|
+
role: "assistant",
|
|
48845
|
+
content: "<delete-folder>src/legacy</delete-folder>"
|
|
48846
|
+
},
|
|
48847
|
+
{
|
|
48848
|
+
role: "user",
|
|
48849
|
+
content: `Here is the output from delete-folder of src/legacy:
|
|
48850
|
+
|
|
48851
|
+
Deleted folder: /repo/src/legacy
|
|
48852
|
+
|
|
48853
|
+
Please continue your response based on this output.`
|
|
48854
|
+
},
|
|
48855
|
+
{
|
|
48856
|
+
role: "assistant",
|
|
48857
|
+
content: "Done — the `src/legacy` folder and all its contents have been deleted."
|
|
48858
|
+
},
|
|
48859
|
+
{
|
|
48860
|
+
role: "user",
|
|
48861
|
+
content: "open https://github.com/microsoft/typescript"
|
|
48862
|
+
},
|
|
48863
|
+
{
|
|
48864
|
+
role: "assistant",
|
|
48865
|
+
content: "<open-url>https://github.com/microsoft/typescript</open-url>"
|
|
48866
|
+
},
|
|
48867
|
+
{
|
|
48868
|
+
role: "user",
|
|
48869
|
+
content: `Here is the output from open-url https://github.com/microsoft/typescript:
|
|
48870
|
+
|
|
48871
|
+
Opened: https://github.com/microsoft/typescript
|
|
48872
|
+
|
|
48873
|
+
Please continue your response based on this output.`
|
|
48874
|
+
},
|
|
48875
|
+
{
|
|
48876
|
+
role: "assistant",
|
|
48877
|
+
content: "Opened the TypeScript GitHub page in your browser."
|
|
48878
|
+
},
|
|
48879
|
+
{
|
|
48880
|
+
role: "user",
|
|
48881
|
+
content: "generate a PDF report about the project and save it to docs/report.pdf"
|
|
48882
|
+
},
|
|
48883
|
+
{
|
|
48884
|
+
role: "assistant",
|
|
48885
|
+
content: `<generate-pdf>
|
|
48886
|
+
{"path": "docs/report.pdf", "content": "# Project Report\\n\\n## Overview\\n\\nThis document summarizes the project.\\n\\n## Details\\n\\nMore content here."}
|
|
48887
|
+
</generate-pdf>`
|
|
48888
|
+
},
|
|
48889
|
+
{
|
|
48890
|
+
role: "user",
|
|
48891
|
+
content: `Here is the output from generate-pdf to docs/report.pdf:
|
|
48892
|
+
|
|
48893
|
+
PDF generated: /repo/docs/report.pdf
|
|
48894
|
+
|
|
48895
|
+
Please continue your response based on this output.`
|
|
48896
|
+
},
|
|
48897
|
+
{
|
|
48898
|
+
role: "assistant",
|
|
48899
|
+
content: "Done — the PDF report has been saved to `docs/report.pdf`."
|
|
48900
|
+
},
|
|
48901
|
+
{
|
|
48902
|
+
role: "user",
|
|
48903
|
+
content: 'grep -R "ChatRunner" -n src'
|
|
48904
|
+
},
|
|
48905
|
+
{
|
|
48906
|
+
role: "assistant",
|
|
48907
|
+
content: `<grep>
|
|
48908
|
+
{"pattern": "ChatRunner", "glob": "src/**/*"}
|
|
48909
|
+
</grep>`
|
|
48910
|
+
},
|
|
48911
|
+
{
|
|
48912
|
+
role: "user",
|
|
48913
|
+
content: `Here is the output from grep for "ChatRunner":
|
|
48914
|
+
|
|
48915
|
+
grep /ChatRunner/ src/**/* — 3 match(es) in 2 file(s)
|
|
48916
|
+
|
|
48917
|
+
src/index.tsx
|
|
48918
|
+
12: import { ChatRunner } from "./components/chat/ChatRunner";
|
|
48919
|
+
|
|
48920
|
+
src/components/chat/ChatRunner.tsx
|
|
48921
|
+
1: export const ChatRunner = ...
|
|
48922
|
+
|
|
48923
|
+
Please continue your response based on this output.`
|
|
48924
|
+
},
|
|
48925
|
+
{
|
|
48926
|
+
role: "assistant",
|
|
48927
|
+
content: "`ChatRunner` is defined in `src/components/chat/ChatRunner.tsx` and imported in `src/index.tsx`."
|
|
48928
|
+
},
|
|
48929
|
+
{
|
|
48930
|
+
role: "user",
|
|
48931
|
+
content: "find all usages of useInput in the codebase"
|
|
48932
|
+
},
|
|
48933
|
+
{
|
|
48934
|
+
role: "assistant",
|
|
48935
|
+
content: `<grep>
|
|
48936
|
+
{"pattern": "useInput", "glob": "src/**/*.tsx"}
|
|
48937
|
+
</grep>`
|
|
48938
|
+
},
|
|
48939
|
+
{
|
|
48940
|
+
role: "user",
|
|
48941
|
+
content: `Here is the output from grep for "useInput":
|
|
48942
|
+
|
|
48943
|
+
grep /useInput/ src/**/*.tsx — 2 match(es) in 1 file(s)
|
|
48944
|
+
|
|
48945
|
+
src/components/chat/ChatRunner.tsx
|
|
48946
|
+
5: import { useInput } from "ink";
|
|
48947
|
+
210: useInput((input, key) => {
|
|
48948
|
+
|
|
48949
|
+
Please continue your response based on this output.`
|
|
48950
|
+
},
|
|
48951
|
+
{
|
|
48952
|
+
role: "assistant",
|
|
48953
|
+
content: "`useInput` is used in `src/components/chat/ChatRunner.tsx` — imported on line 5 and called on line 210."
|
|
48954
|
+
},
|
|
48955
|
+
{
|
|
48956
|
+
role: "user",
|
|
48957
|
+
content: "read src folder"
|
|
48958
|
+
},
|
|
48959
|
+
{
|
|
48960
|
+
role: "assistant",
|
|
48961
|
+
content: "<read-folder>src</read-folder>"
|
|
48962
|
+
},
|
|
48963
|
+
{
|
|
48964
|
+
role: "user",
|
|
48965
|
+
content: `Here is the output from read-folder of src:
|
|
48966
|
+
|
|
48967
|
+
Folder: src (4 entries)
|
|
48968
|
+
|
|
48969
|
+
Files:
|
|
48970
|
+
index.ts
|
|
48971
|
+
App.tsx
|
|
48972
|
+
|
|
48973
|
+
Subfolders:
|
|
48974
|
+
components/
|
|
48975
|
+
utils/
|
|
48976
|
+
|
|
48977
|
+
Please continue your response based on this output.`
|
|
48978
|
+
},
|
|
48979
|
+
{
|
|
48980
|
+
role: "assistant",
|
|
48981
|
+
content: "The `src` folder contains `index.ts`, `App.tsx`, plus subfolders `components/` and `utils/`."
|
|
48982
|
+
},
|
|
48983
|
+
{
|
|
48984
|
+
role: "user",
|
|
48985
|
+
content: "list src folder"
|
|
48986
|
+
},
|
|
48987
|
+
{
|
|
48988
|
+
role: "assistant",
|
|
48989
|
+
content: "<read-folder>src</read-folder>"
|
|
48990
|
+
},
|
|
48991
|
+
{
|
|
48992
|
+
role: "user",
|
|
48993
|
+
content: `Here is the output from read-folder of src:
|
|
48994
|
+
|
|
48995
|
+
Folder: src (4 entries)
|
|
48996
|
+
|
|
48997
|
+
Files:
|
|
48998
|
+
index.ts
|
|
48999
|
+
App.tsx
|
|
49000
|
+
|
|
49001
|
+
Subfolders:
|
|
49002
|
+
components/
|
|
49003
|
+
utils/
|
|
49004
|
+
|
|
49005
|
+
Please continue your response based on this output.`
|
|
49006
|
+
},
|
|
49007
|
+
{
|
|
49008
|
+
role: "assistant",
|
|
49009
|
+
content: "The `src` folder contains `index.ts`, `App.tsx`, plus subfolders `components/` and `utils/`."
|
|
49010
|
+
},
|
|
49011
|
+
{
|
|
49012
|
+
role: "user",
|
|
49013
|
+
content: "what files are in src/components?"
|
|
49014
|
+
},
|
|
49015
|
+
{
|
|
49016
|
+
role: "assistant",
|
|
49017
|
+
content: "<read-folder>src/components</read-folder>"
|
|
49018
|
+
},
|
|
49019
|
+
{
|
|
49020
|
+
role: "user",
|
|
49021
|
+
content: `Here is the output from read-folder of src/components:
|
|
49022
|
+
|
|
49023
|
+
Folder: src/components (5 entries)
|
|
49024
|
+
|
|
49025
|
+
Files:
|
|
49026
|
+
Header.tsx
|
|
49027
|
+
Footer.tsx
|
|
49028
|
+
Button.tsx
|
|
49029
|
+
|
|
49030
|
+
Subfolders:
|
|
49031
|
+
ui/
|
|
49032
|
+
forms/
|
|
49033
|
+
|
|
49034
|
+
Please continue your response based on this output.`
|
|
49035
|
+
},
|
|
49036
|
+
{
|
|
49037
|
+
role: "assistant",
|
|
49038
|
+
content: "The `src/components` folder has 3 files — `Header.tsx`, `Footer.tsx`, `Button.tsx` — plus two subfolders: `ui/` and `forms/`."
|
|
49039
|
+
},
|
|
49040
|
+
{
|
|
49041
|
+
role: "user",
|
|
49042
|
+
content: "list the files in src/utils"
|
|
49043
|
+
},
|
|
49044
|
+
{
|
|
49045
|
+
role: "assistant",
|
|
49046
|
+
content: "<read-folder>src/utils</read-folder>"
|
|
49047
|
+
},
|
|
49048
|
+
{
|
|
49049
|
+
role: "user",
|
|
49050
|
+
content: `Here is the output from read-folder of src/utils:
|
|
49051
|
+
|
|
49052
|
+
Folder: src/utils (3 entries)
|
|
49053
|
+
|
|
49054
|
+
Files:
|
|
49055
|
+
api.ts
|
|
49056
|
+
helpers.ts
|
|
49057
|
+
format.ts
|
|
49058
|
+
|
|
49059
|
+
Please continue your response based on this output.`
|
|
49060
|
+
},
|
|
49061
|
+
{
|
|
49062
|
+
role: "assistant",
|
|
49063
|
+
content: "The `src/utils` folder contains 3 files: `api.ts`, `helpers.ts`, and `format.ts`."
|
|
49064
|
+
},
|
|
49065
|
+
{
|
|
49066
|
+
role: "user",
|
|
49067
|
+
content: "show me what's in the src directory"
|
|
49068
|
+
},
|
|
49069
|
+
{
|
|
49070
|
+
role: "assistant",
|
|
49071
|
+
content: "<read-folder>src</read-folder>"
|
|
49072
|
+
},
|
|
49073
|
+
{
|
|
49074
|
+
role: "user",
|
|
49075
|
+
content: `Here is the output from read-folder of src:
|
|
49076
|
+
|
|
49077
|
+
Folder: src (4 entries)
|
|
49078
|
+
|
|
49079
|
+
Files:
|
|
49080
|
+
index.ts
|
|
49081
|
+
App.tsx
|
|
49082
|
+
|
|
49083
|
+
Subfolders:
|
|
49084
|
+
components/
|
|
49085
|
+
utils/
|
|
49086
|
+
|
|
49087
|
+
Please continue your response based on this output.`
|
|
49088
|
+
},
|
|
49089
|
+
{
|
|
49090
|
+
role: "assistant",
|
|
49091
|
+
content: "The `src` directory has 2 files (`index.ts`, `App.tsx`) and 2 subfolders (`components/`, `utils/`)."
|
|
49092
|
+
},
|
|
49093
|
+
{
|
|
49094
|
+
role: "user",
|
|
49095
|
+
content: "show me the project structure"
|
|
49096
|
+
},
|
|
49097
|
+
{
|
|
49098
|
+
role: "assistant",
|
|
49099
|
+
content: "<read-folder>.</read-folder>"
|
|
49100
|
+
},
|
|
49101
|
+
{
|
|
49102
|
+
role: "user",
|
|
49103
|
+
content: `Here is the output from read-folder of .:
|
|
49104
|
+
|
|
49105
|
+
Folder: . (5 entries)
|
|
49106
|
+
|
|
49107
|
+
Files:
|
|
49108
|
+
package.json
|
|
49109
|
+
tsconfig.json
|
|
49110
|
+
README.md
|
|
49111
|
+
|
|
49112
|
+
Subfolders:
|
|
49113
|
+
src/
|
|
49114
|
+
node_modules/
|
|
49115
|
+
|
|
49116
|
+
Please continue your response based on this output.`
|
|
49117
|
+
},
|
|
49118
|
+
{
|
|
49119
|
+
role: "assistant",
|
|
49120
|
+
content: "The project root has 3 files (`package.json`, `tsconfig.json`, `README.md`) and the `src/` folder for source code."
|
|
49121
|
+
},
|
|
49122
|
+
{
|
|
49123
|
+
role: "user",
|
|
49124
|
+
content: "what does the project look like?"
|
|
49125
|
+
},
|
|
49126
|
+
{
|
|
49127
|
+
role: "assistant",
|
|
49128
|
+
content: "<read-folder>.</read-folder>"
|
|
49129
|
+
},
|
|
49130
|
+
{
|
|
49131
|
+
role: "user",
|
|
49132
|
+
content: `Here is the output from read-folder of .:
|
|
49133
|
+
|
|
49134
|
+
Folder: . (4 entries)
|
|
49135
|
+
|
|
49136
|
+
Files:
|
|
49137
|
+
package.json
|
|
49138
|
+
README.md
|
|
49139
|
+
|
|
49140
|
+
Subfolders:
|
|
49141
|
+
src/
|
|
49142
|
+
dist/
|
|
49143
|
+
|
|
49144
|
+
Please continue your response based on this output.`
|
|
49145
|
+
},
|
|
49146
|
+
{
|
|
49147
|
+
role: "assistant",
|
|
49148
|
+
content: "The repo root contains `package.json` and `README.md`, with source code in `src/` and compiled output in `dist/`."
|
|
49149
|
+
},
|
|
48726
49150
|
{
|
|
48727
49151
|
role: "user",
|
|
48728
49152
|
content: "fetch https://api.github.com/repos/microsoft/typescript"
|
|
@@ -48779,6 +49203,31 @@ Please continue your response based on this output.`
|
|
|
48779
49203
|
role: "assistant",
|
|
48780
49204
|
content: "Done — saved and verified `ts-info.json`. Data looks correct."
|
|
48781
49205
|
},
|
|
49206
|
+
{
|
|
49207
|
+
role: "user",
|
|
49208
|
+
content: "add a logout button to src/components/Header.tsx"
|
|
49209
|
+
},
|
|
49210
|
+
{
|
|
49211
|
+
role: "assistant",
|
|
49212
|
+
content: "<read-file>src/components/Header.tsx</read-file>"
|
|
49213
|
+
},
|
|
49214
|
+
{
|
|
49215
|
+
role: "user",
|
|
49216
|
+
content: `Here is the output from read-file of src/components/Header.tsx:
|
|
49217
|
+
|
|
49218
|
+
File: src/components/Header.tsx (42 lines)
|
|
49219
|
+
|
|
49220
|
+
import React from 'react';
|
|
49221
|
+
// ... full file content ...
|
|
49222
|
+
|
|
49223
|
+
Please continue your response based on this output.`
|
|
49224
|
+
},
|
|
49225
|
+
{
|
|
49226
|
+
role: "assistant",
|
|
49227
|
+
content: `<changes>
|
|
49228
|
+
{"summary": "Add logout button to Header — preserves all existing nav items and imports", "patches": [{"path": "src/components/Header.tsx", "content": "// complete file with logout button added", "isNew": false}]}
|
|
49229
|
+
</changes>`
|
|
49230
|
+
},
|
|
48782
49231
|
{
|
|
48783
49232
|
role: "user",
|
|
48784
49233
|
content: "what node version am I on"
|
|
@@ -48842,6 +49291,15 @@ function parseResponse(text) {
|
|
|
48842
49291
|
{ kind: "fetch", re: /<fetch>([\s\S]*?)<\/fetch>/g },
|
|
48843
49292
|
{ kind: "shell", re: /<shell>([\s\S]*?)<\/shell>/g },
|
|
48844
49293
|
{ kind: "read-file", re: /<read-file>([\s\S]*?)<\/read-file>/g },
|
|
49294
|
+
{ kind: "read-folder", re: /<read-folder>([\s\S]*?)<\/read-folder>/g },
|
|
49295
|
+
{ kind: "grep", re: /<grep>([\s\S]*?)<\/grep>/g },
|
|
49296
|
+
{ kind: "delete-file", re: /<delete-file>([\s\S]*?)<\/delete-file>/g },
|
|
49297
|
+
{
|
|
49298
|
+
kind: "delete-folder",
|
|
49299
|
+
re: /<delete-folder>([\s\S]*?)<\/delete-folder>/g
|
|
49300
|
+
},
|
|
49301
|
+
{ kind: "open-url", re: /<open-url>([\s\S]*?)<\/open-url>/g },
|
|
49302
|
+
{ kind: "generate-pdf", re: /<generate-pdf>([\s\S]*?)<\/generate-pdf>/g },
|
|
48845
49303
|
{ kind: "write-file", re: /<write-file>([\s\S]*?)<\/write-file>/g },
|
|
48846
49304
|
{ kind: "search", re: /<search>([\s\S]*?)<\/search>/g },
|
|
48847
49305
|
{ kind: "clone", re: /<clone>([\s\S]*?)<\/clone>/g },
|
|
@@ -48849,6 +49307,7 @@ function parseResponse(text) {
|
|
|
48849
49307
|
{ kind: "fetch", re: /```fetch\r?\n([\s\S]*?)\r?\n```/g },
|
|
48850
49308
|
{ kind: "shell", re: /```shell\r?\n([\s\S]*?)\r?\n```/g },
|
|
48851
49309
|
{ kind: "read-file", re: /```read-file\r?\n([\s\S]*?)\r?\n```/g },
|
|
49310
|
+
{ kind: "read-folder", re: /```read-folder\r?\n([\s\S]*?)\r?\n```/g },
|
|
48852
49311
|
{ kind: "write-file", re: /```write-file\r?\n([\s\S]*?)\r?\n```/g },
|
|
48853
49312
|
{ kind: "search", re: /```search\r?\n([\s\S]*?)\r?\n```/g },
|
|
48854
49313
|
{ kind: "changes", re: /```changes\r?\n([\s\S]*?)\r?\n```/g }
|
|
@@ -48863,7 +49322,7 @@ function parseResponse(text) {
|
|
|
48863
49322
|
return { kind: "text", content: text.trim() };
|
|
48864
49323
|
candidates.sort((a, b) => a.index - b.index);
|
|
48865
49324
|
const { kind, match } = candidates[0];
|
|
48866
|
-
const before2 = text.slice(0, match.index).trim();
|
|
49325
|
+
const before2 = text.slice(0, match.index).replace(/<(fetch|shell|read-file|read-folder|write-file|search|clone|changes)[^>]*>[\s\S]*?<\/\1>/g, "").trim();
|
|
48867
49326
|
const body = match[1].trim();
|
|
48868
49327
|
if (kind === "changes") {
|
|
48869
49328
|
try {
|
|
@@ -48882,6 +49341,42 @@ function parseResponse(text) {
|
|
|
48882
49341
|
}
|
|
48883
49342
|
if (kind === "read-file")
|
|
48884
49343
|
return { kind: "read-file", content: before2, filePath: body };
|
|
49344
|
+
if (kind === "read-folder")
|
|
49345
|
+
return { kind: "read-folder", content: before2, folderPath: body };
|
|
49346
|
+
if (kind === "delete-file")
|
|
49347
|
+
return { kind: "delete-file", content: before2, filePath: body };
|
|
49348
|
+
if (kind === "delete-folder")
|
|
49349
|
+
return { kind: "delete-folder", content: before2, folderPath: body };
|
|
49350
|
+
if (kind === "open-url") {
|
|
49351
|
+
const url = body.replace(/^<|>$/g, "").trim();
|
|
49352
|
+
return { kind: "open-url", content: before2, url };
|
|
49353
|
+
}
|
|
49354
|
+
if (kind === "generate-pdf") {
|
|
49355
|
+
try {
|
|
49356
|
+
const parsed = JSON.parse(body);
|
|
49357
|
+
return {
|
|
49358
|
+
kind: "generate-pdf",
|
|
49359
|
+
content: before2,
|
|
49360
|
+
filePath: parsed.path ?? parsed.filePath ?? "output.pdf",
|
|
49361
|
+
pdfContent: parsed.content ?? ""
|
|
49362
|
+
};
|
|
49363
|
+
} catch {
|
|
49364
|
+
return { kind: "text", content: text };
|
|
49365
|
+
}
|
|
49366
|
+
}
|
|
49367
|
+
if (kind === "grep") {
|
|
49368
|
+
try {
|
|
49369
|
+
const parsed = JSON.parse(body);
|
|
49370
|
+
return {
|
|
49371
|
+
kind: "grep",
|
|
49372
|
+
content: before2,
|
|
49373
|
+
pattern: parsed.pattern,
|
|
49374
|
+
glob: parsed.glob ?? "**/*"
|
|
49375
|
+
};
|
|
49376
|
+
} catch {
|
|
49377
|
+
return { kind: "grep", content: before2, pattern: body, glob: "**/*" };
|
|
49378
|
+
}
|
|
49379
|
+
}
|
|
48885
49380
|
if (kind === "write-file") {
|
|
48886
49381
|
try {
|
|
48887
49382
|
const parsed = JSON.parse(body);
|
|
@@ -48918,7 +49413,7 @@ function buildApiMessages(messages) {
|
|
|
48918
49413
|
content: "The tool call was denied by the user. Please respond without using that tool."
|
|
48919
49414
|
};
|
|
48920
49415
|
}
|
|
48921
|
-
const label = m.toolName === "shell" ? `shell command \`${m.content}\`` : m.toolName === "fetch" ? `fetch of ${m.content}` : m.toolName === "read-file" ? `read-file of ${m.content}` : m.toolName === "search" ? `web search for "${m.content}"` : `write-file to ${m.content}`;
|
|
49416
|
+
const label = m.toolName === "shell" ? `shell command \`${m.content}\`` : m.toolName === "fetch" ? `fetch of ${m.content}` : m.toolName === "read-file" ? `read-file of ${m.content}` : m.toolName === "read-folder" ? `read-folder of ${m.content}` : m.toolName === "grep" ? `grep for "${m.content}"` : m.toolName === "delete-file" ? `delete-file of ${m.content}` : m.toolName === "delete-folder" ? `delete-folder of ${m.content}` : m.toolName === "open-url" ? `open-url ${m.content}` : m.toolName === "generate-pdf" ? `generate-pdf to ${m.content}` : m.toolName === "search" ? `web search for "${m.content}"` : `write-file to ${m.content}`;
|
|
48922
49417
|
return {
|
|
48923
49418
|
role: "user",
|
|
48924
49419
|
content: `Here is the output from the ${label}:
|
|
@@ -49273,6 +49768,133 @@ ${content.slice(0, 8000)}${content.length > 8000 ? `
|
|
|
49273
49768
|
}
|
|
49274
49769
|
return `File not found: ${filePath}. If reading from a cloned repo, use the full absolute path e.g. C:\\Users\\...\\repo\\file.ts`;
|
|
49275
49770
|
}
|
|
49771
|
+
function readFolder(folderPath, repoPath) {
|
|
49772
|
+
const sanitized = folderPath.replace(/^(ls|dir|find|tree|cat|read|ls -la?|ls -al?)\s+/i, "").trim();
|
|
49773
|
+
const candidates = path14.isAbsolute(sanitized) ? [sanitized] : [sanitized, path14.join(repoPath, sanitized)];
|
|
49774
|
+
for (const candidate of candidates) {
|
|
49775
|
+
if (!existsSync10(candidate))
|
|
49776
|
+
continue;
|
|
49777
|
+
let stat;
|
|
49778
|
+
try {
|
|
49779
|
+
stat = statSync4(candidate);
|
|
49780
|
+
} catch {
|
|
49781
|
+
continue;
|
|
49782
|
+
}
|
|
49783
|
+
if (!stat.isDirectory()) {
|
|
49784
|
+
return `Not a directory: ${candidate}. Use read-file to read a file.`;
|
|
49785
|
+
}
|
|
49786
|
+
let entries;
|
|
49787
|
+
try {
|
|
49788
|
+
entries = readdirSync3(candidate, { encoding: "utf-8" });
|
|
49789
|
+
} catch (err) {
|
|
49790
|
+
return `Error reading folder: ${err instanceof Error ? err.message : String(err)}`;
|
|
49791
|
+
}
|
|
49792
|
+
const files = [];
|
|
49793
|
+
const subfolders = [];
|
|
49794
|
+
for (const entry of entries) {
|
|
49795
|
+
if (entry.startsWith(".") && entry !== ".env")
|
|
49796
|
+
continue;
|
|
49797
|
+
const full = path14.join(candidate, entry);
|
|
49798
|
+
try {
|
|
49799
|
+
if (statSync4(full).isDirectory()) {
|
|
49800
|
+
subfolders.push(`${entry}/`);
|
|
49801
|
+
} else {
|
|
49802
|
+
files.push(entry);
|
|
49803
|
+
}
|
|
49804
|
+
} catch {}
|
|
49805
|
+
}
|
|
49806
|
+
const total = files.length + subfolders.length;
|
|
49807
|
+
const lines = [`Folder: ${candidate} (${total} entries)`, ""];
|
|
49808
|
+
if (files.length > 0) {
|
|
49809
|
+
lines.push("Files:");
|
|
49810
|
+
files.forEach((f) => lines.push(` ${f}`));
|
|
49811
|
+
}
|
|
49812
|
+
if (subfolders.length > 0) {
|
|
49813
|
+
if (files.length > 0)
|
|
49814
|
+
lines.push("");
|
|
49815
|
+
lines.push("Subfolders:");
|
|
49816
|
+
subfolders.forEach((d) => lines.push(` ${d}`));
|
|
49817
|
+
}
|
|
49818
|
+
if (total === 0) {
|
|
49819
|
+
lines.push("(empty folder)");
|
|
49820
|
+
}
|
|
49821
|
+
return lines.join(`
|
|
49822
|
+
`);
|
|
49823
|
+
}
|
|
49824
|
+
return `Folder not found: ${sanitized}`;
|
|
49825
|
+
}
|
|
49826
|
+
function grepFiles(pattern, glob, repoPath) {
|
|
49827
|
+
let regex2;
|
|
49828
|
+
try {
|
|
49829
|
+
regex2 = new RegExp(pattern, "i");
|
|
49830
|
+
} catch {
|
|
49831
|
+
regex2 = new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "i");
|
|
49832
|
+
}
|
|
49833
|
+
const globToFilter = (g) => {
|
|
49834
|
+
const cleaned = g.replace(/^\*\*\//, "");
|
|
49835
|
+
const parts = cleaned.split("/");
|
|
49836
|
+
const ext = parts[parts.length - 1];
|
|
49837
|
+
const prefix = parts.slice(0, -1).join("/");
|
|
49838
|
+
return (rel) => {
|
|
49839
|
+
if (ext?.startsWith("*.")) {
|
|
49840
|
+
const extSuffix = ext.slice(1);
|
|
49841
|
+
if (!rel.endsWith(extSuffix))
|
|
49842
|
+
return false;
|
|
49843
|
+
} else if (ext && !ext.includes("*")) {
|
|
49844
|
+
if (!rel.endsWith(ext))
|
|
49845
|
+
return false;
|
|
49846
|
+
}
|
|
49847
|
+
if (prefix && !prefix.includes("*")) {
|
|
49848
|
+
if (!rel.startsWith(prefix))
|
|
49849
|
+
return false;
|
|
49850
|
+
}
|
|
49851
|
+
return true;
|
|
49852
|
+
};
|
|
49853
|
+
};
|
|
49854
|
+
const filter2 = globToFilter(glob);
|
|
49855
|
+
const allFiles = walkDir3(repoPath);
|
|
49856
|
+
const matchedFiles = allFiles.filter(filter2);
|
|
49857
|
+
if (matchedFiles.length === 0) {
|
|
49858
|
+
return `No files matched glob: ${glob}`;
|
|
49859
|
+
}
|
|
49860
|
+
const results = [];
|
|
49861
|
+
let totalMatches = 0;
|
|
49862
|
+
for (const relPath of matchedFiles) {
|
|
49863
|
+
const fullPath = path14.join(repoPath, relPath);
|
|
49864
|
+
let content;
|
|
49865
|
+
try {
|
|
49866
|
+
content = readFileSync10(fullPath, "utf-8");
|
|
49867
|
+
} catch {
|
|
49868
|
+
continue;
|
|
49869
|
+
}
|
|
49870
|
+
const lines = content.split(`
|
|
49871
|
+
`);
|
|
49872
|
+
const fileMatches = [];
|
|
49873
|
+
lines.forEach((line, i) => {
|
|
49874
|
+
if (regex2.test(line)) {
|
|
49875
|
+
fileMatches.push(` ${i + 1}: ${line.trimEnd()}`);
|
|
49876
|
+
totalMatches++;
|
|
49877
|
+
}
|
|
49878
|
+
});
|
|
49879
|
+
if (fileMatches.length > 0) {
|
|
49880
|
+
results.push(`${relPath}
|
|
49881
|
+
${fileMatches.join(`
|
|
49882
|
+
`)}`);
|
|
49883
|
+
}
|
|
49884
|
+
if (totalMatches >= 200) {
|
|
49885
|
+
results.push("(truncated — too many matches)");
|
|
49886
|
+
break;
|
|
49887
|
+
}
|
|
49888
|
+
}
|
|
49889
|
+
if (results.length === 0) {
|
|
49890
|
+
return `No matches for /${pattern}/ in ${matchedFiles.length} file(s) matching ${glob}`;
|
|
49891
|
+
}
|
|
49892
|
+
return `grep /${pattern}/ ${glob} — ${totalMatches} match(es) in ${results.length} file(s)
|
|
49893
|
+
|
|
49894
|
+
${results.join(`
|
|
49895
|
+
|
|
49896
|
+
`)}`;
|
|
49897
|
+
}
|
|
49276
49898
|
function writeFile(filePath, content, repoPath) {
|
|
49277
49899
|
const fullPath = path14.isAbsolute(filePath) ? filePath : path14.join(repoPath, filePath);
|
|
49278
49900
|
try {
|
|
@@ -49287,6 +49909,130 @@ function writeFile(filePath, content, repoPath) {
|
|
|
49287
49909
|
return `Error writing file: ${err instanceof Error ? err.message : String(err)}`;
|
|
49288
49910
|
}
|
|
49289
49911
|
}
|
|
49912
|
+
function deleteFile(filePath, repoPath) {
|
|
49913
|
+
const fullPath = path14.isAbsolute(filePath) ? filePath : path14.join(repoPath, filePath);
|
|
49914
|
+
try {
|
|
49915
|
+
if (!existsSync10(fullPath))
|
|
49916
|
+
return `File not found: ${fullPath}`;
|
|
49917
|
+
const { unlinkSync } = __require("fs");
|
|
49918
|
+
unlinkSync(fullPath);
|
|
49919
|
+
return `Deleted: ${fullPath}`;
|
|
49920
|
+
} catch (err) {
|
|
49921
|
+
return `Error deleting file: ${err instanceof Error ? err.message : String(err)}`;
|
|
49922
|
+
}
|
|
49923
|
+
}
|
|
49924
|
+
function deleteFolder(folderPath, repoPath) {
|
|
49925
|
+
const fullPath = path14.isAbsolute(folderPath) ? folderPath : path14.join(repoPath, folderPath);
|
|
49926
|
+
try {
|
|
49927
|
+
if (!existsSync10(fullPath))
|
|
49928
|
+
return `Folder not found: ${fullPath}`;
|
|
49929
|
+
const { rmSync } = __require("fs");
|
|
49930
|
+
rmSync(fullPath, { recursive: true, force: true });
|
|
49931
|
+
return `Deleted folder: ${fullPath}`;
|
|
49932
|
+
} catch (err) {
|
|
49933
|
+
return `Error deleting folder: ${err instanceof Error ? err.message : String(err)}`;
|
|
49934
|
+
}
|
|
49935
|
+
}
|
|
49936
|
+
function openUrl(url) {
|
|
49937
|
+
try {
|
|
49938
|
+
const { execSync: execSync2 } = __require("child_process");
|
|
49939
|
+
const platform2 = process.platform;
|
|
49940
|
+
if (platform2 === "win32") {
|
|
49941
|
+
execSync2(`start "" "${url}"`, { stdio: "ignore" });
|
|
49942
|
+
} else if (platform2 === "darwin") {
|
|
49943
|
+
execSync2(`open "${url}"`, { stdio: "ignore" });
|
|
49944
|
+
} else {
|
|
49945
|
+
execSync2(`xdg-open "${url}"`, { stdio: "ignore" });
|
|
49946
|
+
}
|
|
49947
|
+
return `Opened: ${url}`;
|
|
49948
|
+
} catch (err) {
|
|
49949
|
+
return `Error opening URL: ${err instanceof Error ? err.message : String(err)}`;
|
|
49950
|
+
}
|
|
49951
|
+
}
|
|
49952
|
+
function generatePdf(filePath, content, repoPath) {
|
|
49953
|
+
const fullPath = path14.isAbsolute(filePath) ? filePath : path14.join(repoPath, filePath);
|
|
49954
|
+
try {
|
|
49955
|
+
const dir = path14.dirname(fullPath);
|
|
49956
|
+
if (!existsSync10(dir))
|
|
49957
|
+
mkdirSync4(dir, { recursive: true });
|
|
49958
|
+
const escaped = content.replace(/\\/g, "\\\\").replace(/"""/g, "\\\"\\\"\\\"").replace(/\r/g, "");
|
|
49959
|
+
const script = `
|
|
49960
|
+
import sys
|
|
49961
|
+
try:
|
|
49962
|
+
from reportlab.lib.pagesizes import letter
|
|
49963
|
+
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, HRFlowable
|
|
49964
|
+
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
|
49965
|
+
from reportlab.lib.units import inch
|
|
49966
|
+
from reportlab.lib import colors
|
|
49967
|
+
except ImportError:
|
|
49968
|
+
import subprocess
|
|
49969
|
+
subprocess.check_call([sys.executable, "-m", "pip", "install", "reportlab", "--break-system-packages", "-q"])
|
|
49970
|
+
from reportlab.lib.pagesizes import letter
|
|
49971
|
+
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, HRFlowable
|
|
49972
|
+
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
|
49973
|
+
from reportlab.lib.units import inch
|
|
49974
|
+
from reportlab.lib import colors
|
|
49975
|
+
|
|
49976
|
+
doc = SimpleDocTemplate(
|
|
49977
|
+
r"""${fullPath}""",
|
|
49978
|
+
pagesize=letter,
|
|
49979
|
+
rightMargin=inch,
|
|
49980
|
+
leftMargin=inch,
|
|
49981
|
+
topMargin=inch,
|
|
49982
|
+
bottomMargin=inch,
|
|
49983
|
+
)
|
|
49984
|
+
|
|
49985
|
+
styles = getSampleStyleSheet()
|
|
49986
|
+
styles.add(ParagraphStyle(name="H1", parent=styles["Heading1"], fontSize=22, spaceAfter=10))
|
|
49987
|
+
styles.add(ParagraphStyle(name="H2", parent=styles["Heading2"], fontSize=16, spaceAfter=8))
|
|
49988
|
+
styles.add(ParagraphStyle(name="H3", parent=styles["Heading3"], fontSize=13, spaceAfter=6))
|
|
49989
|
+
styles.add(ParagraphStyle(name="Body", parent=styles["Normal"], fontSize=11, leading=16, spaceAfter=8))
|
|
49990
|
+
styles.add(ParagraphStyle(name="Bullet", parent=styles["Normal"], fontSize=11, leading=16, leftIndent=20, spaceAfter=4, bulletIndent=10))
|
|
49991
|
+
|
|
49992
|
+
raw = """${escaped}"""
|
|
49993
|
+
|
|
49994
|
+
story = []
|
|
49995
|
+
for line in raw.split("\\n"):
|
|
49996
|
+
s = line.rstrip()
|
|
49997
|
+
if s.startswith("### "):
|
|
49998
|
+
story.append(Paragraph(s[4:], styles["H3"]))
|
|
49999
|
+
elif s.startswith("## "):
|
|
50000
|
+
story.append(Spacer(1, 6))
|
|
50001
|
+
story.append(Paragraph(s[3:], styles["H2"]))
|
|
50002
|
+
story.append(HRFlowable(width="100%", thickness=0.5, color=colors.grey, spaceAfter=4))
|
|
50003
|
+
elif s.startswith("# "):
|
|
50004
|
+
story.append(Paragraph(s[2:], styles["H1"]))
|
|
50005
|
+
story.append(HRFlowable(width="100%", thickness=1, color=colors.black, spaceAfter=6))
|
|
50006
|
+
elif s.startswith("- ") or s.startswith("* "):
|
|
50007
|
+
story.append(Paragraph(u"\\u2022 " + s[2:], styles["Bullet"]))
|
|
50008
|
+
elif s.startswith("---"):
|
|
50009
|
+
story.append(HRFlowable(width="100%", thickness=0.5, color=colors.grey, spaceAfter=4))
|
|
50010
|
+
elif s == "":
|
|
50011
|
+
story.append(Spacer(1, 6))
|
|
50012
|
+
else:
|
|
50013
|
+
# handle **bold** inline
|
|
50014
|
+
import re
|
|
50015
|
+
s = re.sub(r"\\*\\*(.+?)\\*\\*", r"<b>\\1</b>", s)
|
|
50016
|
+
s = re.sub(r"\\*(.+?)\\*", r"<i>\\1</i>", s)
|
|
50017
|
+
s = re.sub(r"\`(.+?)\`", r"<font name='Courier'>\\1</font>", s)
|
|
50018
|
+
story.append(Paragraph(s, styles["Body"]))
|
|
50019
|
+
|
|
50020
|
+
doc.build(story)
|
|
50021
|
+
print("OK")
|
|
50022
|
+
`.replace("${fullPath}", fullPath.replace(/\\/g, "/")).replace("${escaped}", escaped);
|
|
50023
|
+
const os6 = __require("os");
|
|
50024
|
+
const tmpFile = path14.join(os6.tmpdir(), `lens_pdf_${Date.now()}.py`);
|
|
50025
|
+
writeFileSync6(tmpFile, script, "utf-8");
|
|
50026
|
+
const { execSync: execSync2 } = __require("child_process");
|
|
50027
|
+
execSync2(`python "${tmpFile}"`, { stdio: "pipe" });
|
|
50028
|
+
try {
|
|
50029
|
+
__require("fs").unlinkSync(tmpFile);
|
|
50030
|
+
} catch {}
|
|
50031
|
+
return `PDF generated: ${fullPath}`;
|
|
50032
|
+
} catch (err) {
|
|
50033
|
+
return `Error generating PDF: ${err instanceof Error ? err.message : String(err)}`;
|
|
50034
|
+
}
|
|
50035
|
+
}
|
|
49290
50036
|
|
|
49291
50037
|
// src/components/chat/ChatMessage.tsx
|
|
49292
50038
|
var jsx_dev_runtime19 = __toESM(require_jsx_dev_runtime(), 1);
|
|
@@ -49421,6 +50167,12 @@ function StaticMessage({ msg }) {
|
|
|
49421
50167
|
shell: "$",
|
|
49422
50168
|
fetch: "~>",
|
|
49423
50169
|
"read-file": "r",
|
|
50170
|
+
"read-folder": "d",
|
|
50171
|
+
grep: "/",
|
|
50172
|
+
"delete-file": "x",
|
|
50173
|
+
"delete-folder": "X",
|
|
50174
|
+
"open-url": "↗",
|
|
50175
|
+
"generate-pdf": "P",
|
|
49424
50176
|
"write-file": "w",
|
|
49425
50177
|
search: "?"
|
|
49426
50178
|
};
|
|
@@ -49642,6 +50394,30 @@ function PermissionPrompt({
|
|
|
49642
50394
|
icon = "r";
|
|
49643
50395
|
label = "read";
|
|
49644
50396
|
value = tool.filePath;
|
|
50397
|
+
} else if (tool.type === "read-folder") {
|
|
50398
|
+
icon = "d";
|
|
50399
|
+
label = "folder";
|
|
50400
|
+
value = tool.folderPath;
|
|
50401
|
+
} else if (tool.type === "grep") {
|
|
50402
|
+
icon = "/";
|
|
50403
|
+
label = "grep";
|
|
50404
|
+
value = `${tool.pattern} ${tool.glob}`;
|
|
50405
|
+
} else if (tool.type === "delete-file") {
|
|
50406
|
+
icon = "x";
|
|
50407
|
+
label = "delete";
|
|
50408
|
+
value = tool.filePath;
|
|
50409
|
+
} else if (tool.type === "delete-folder") {
|
|
50410
|
+
icon = "X";
|
|
50411
|
+
label = "delete folder";
|
|
50412
|
+
value = tool.folderPath;
|
|
50413
|
+
} else if (tool.type === "open-url") {
|
|
50414
|
+
icon = "↗";
|
|
50415
|
+
label = "open";
|
|
50416
|
+
value = tool.url;
|
|
50417
|
+
} else if (tool.type === "generate-pdf") {
|
|
50418
|
+
icon = "P";
|
|
50419
|
+
label = "pdf";
|
|
50420
|
+
value = tool.filePath;
|
|
49645
50421
|
} else if (tool.type === "write-file") {
|
|
49646
50422
|
icon = "w";
|
|
49647
50423
|
label = "write";
|
|
@@ -49734,16 +50510,23 @@ function TypewriterText({
|
|
|
49734
50510
|
children: displayed
|
|
49735
50511
|
}, undefined, false, undefined, this);
|
|
49736
50512
|
}
|
|
49737
|
-
function ShortcutBar() {
|
|
50513
|
+
function ShortcutBar({ autoApprove }) {
|
|
49738
50514
|
return /* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Box_default, {
|
|
49739
50515
|
gap: 3,
|
|
49740
50516
|
marginTop: 0,
|
|
49741
|
-
children:
|
|
49742
|
-
|
|
49743
|
-
|
|
49744
|
-
|
|
49745
|
-
|
|
49746
|
-
|
|
50517
|
+
children: [
|
|
50518
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
|
|
50519
|
+
color: "gray",
|
|
50520
|
+
dimColor: true,
|
|
50521
|
+
children: "enter send · ^v paste · ^c exit"
|
|
50522
|
+
}, undefined, false, undefined, this),
|
|
50523
|
+
/* @__PURE__ */ jsx_dev_runtime20.jsxDEV(Text, {
|
|
50524
|
+
color: autoApprove ? "green" : "gray",
|
|
50525
|
+
dimColor: !autoApprove,
|
|
50526
|
+
children: autoApprove ? "⚡ auto" : "/auto"
|
|
50527
|
+
}, undefined, false, undefined, this)
|
|
50528
|
+
]
|
|
50529
|
+
}, undefined, true, undefined, this);
|
|
49747
50530
|
}
|
|
49748
50531
|
function CloneOfferView({
|
|
49749
50532
|
stage,
|
|
@@ -51519,7 +52302,8 @@ var jsx_dev_runtime22 = __toESM(require_jsx_dev_runtime(), 1);
|
|
|
51519
52302
|
var COMMANDS = [
|
|
51520
52303
|
{ cmd: "/timeline", desc: "browse commit history" },
|
|
51521
52304
|
{ cmd: "/clear history", desc: "wipe session memory for this repo" },
|
|
51522
|
-
{ cmd: "/review", desc: "review current codebsae" }
|
|
52305
|
+
{ cmd: "/review", desc: "review current codebsae" },
|
|
52306
|
+
{ cmd: "/auto", desc: "toggle auto-approve for read/search tools" }
|
|
51523
52307
|
];
|
|
51524
52308
|
function CommandPalette({
|
|
51525
52309
|
query,
|
|
@@ -51564,6 +52348,8 @@ var ChatRunner = ({ repoPath }) => {
|
|
|
51564
52348
|
const [clonedUrls, setClonedUrls] = import_react48.useState(new Set);
|
|
51565
52349
|
const [showTimeline, setShowTimeline] = import_react48.useState(false);
|
|
51566
52350
|
const [showReview, setShowReview] = import_react48.useState(false);
|
|
52351
|
+
const [autoApprove, setAutoApprove] = import_react48.useState(false);
|
|
52352
|
+
const toolResultCache = import_react48.useRef(new Map);
|
|
51567
52353
|
const inputBuffer = import_react48.useRef("");
|
|
51568
52354
|
const flushTimer = import_react48.useRef(null);
|
|
51569
52355
|
const thinkingPhrase = useThinkingPhrase(stage.type === "thinking");
|
|
@@ -51626,7 +52412,7 @@ var ChatRunner = ({ repoPath }) => {
|
|
|
51626
52412
|
});
|
|
51627
52413
|
return;
|
|
51628
52414
|
}
|
|
51629
|
-
if (parsed.kind === "shell" || parsed.kind === "fetch" || parsed.kind === "read-file" || parsed.kind === "write-file" || parsed.kind === "search") {
|
|
52415
|
+
if (parsed.kind === "shell" || parsed.kind === "fetch" || parsed.kind === "read-file" || parsed.kind === "read-folder" || parsed.kind === "grep" || parsed.kind === "write-file" || parsed.kind === "delete-file" || parsed.kind === "delete-folder" || parsed.kind === "open-url" || parsed.kind === "generate-pdf" || parsed.kind === "search") {
|
|
51630
52416
|
let tool;
|
|
51631
52417
|
if (parsed.kind === "shell") {
|
|
51632
52418
|
tool = { type: "shell", command: parsed.command };
|
|
@@ -51634,6 +52420,22 @@ var ChatRunner = ({ repoPath }) => {
|
|
|
51634
52420
|
tool = { type: "fetch", url: parsed.url };
|
|
51635
52421
|
} else if (parsed.kind === "read-file") {
|
|
51636
52422
|
tool = { type: "read-file", filePath: parsed.filePath };
|
|
52423
|
+
} else if (parsed.kind === "read-folder") {
|
|
52424
|
+
tool = { type: "read-folder", folderPath: parsed.folderPath };
|
|
52425
|
+
} else if (parsed.kind === "grep") {
|
|
52426
|
+
tool = { type: "grep", pattern: parsed.pattern, glob: parsed.glob };
|
|
52427
|
+
} else if (parsed.kind === "delete-file") {
|
|
52428
|
+
tool = { type: "delete-file", filePath: parsed.filePath };
|
|
52429
|
+
} else if (parsed.kind === "delete-folder") {
|
|
52430
|
+
tool = { type: "delete-folder", folderPath: parsed.folderPath };
|
|
52431
|
+
} else if (parsed.kind === "open-url") {
|
|
52432
|
+
tool = { type: "open-url", url: parsed.url };
|
|
52433
|
+
} else if (parsed.kind === "generate-pdf") {
|
|
52434
|
+
tool = {
|
|
52435
|
+
type: "generate-pdf",
|
|
52436
|
+
filePath: parsed.filePath,
|
|
52437
|
+
content: parsed.pdfContent
|
|
52438
|
+
};
|
|
51637
52439
|
} else if (parsed.kind === "search") {
|
|
51638
52440
|
tool = { type: "search", query: parsed.query };
|
|
51639
52441
|
} else {
|
|
@@ -51652,13 +52454,16 @@ var ChatRunner = ({ repoPath }) => {
|
|
|
51652
52454
|
setAllMessages([...currentAll, preambleMsg]);
|
|
51653
52455
|
setCommitted((prev) => [...prev, preambleMsg]);
|
|
51654
52456
|
}
|
|
51655
|
-
|
|
51656
|
-
|
|
51657
|
-
|
|
51658
|
-
|
|
51659
|
-
|
|
51660
|
-
|
|
51661
|
-
|
|
52457
|
+
const isSafeTool = parsed.kind === "read-file" || parsed.kind === "read-folder" || parsed.kind === "grep" || parsed.kind === "fetch" || parsed.kind === "open-url" || parsed.kind === "search";
|
|
52458
|
+
const executeAndContinue = async (approved) => {
|
|
52459
|
+
let result2 = "(denied by user)";
|
|
52460
|
+
if (approved) {
|
|
52461
|
+
const cacheKey = parsed.kind === "read-file" ? `read-file:${parsed.filePath}` : parsed.kind === "read-folder" ? `read-folder:${parsed.folderPath}` : parsed.kind === "grep" ? `grep:${parsed.pattern}:${parsed.glob}` : null;
|
|
52462
|
+
if (cacheKey && toolResultCache.current.has(cacheKey)) {
|
|
52463
|
+
result2 = toolResultCache.current.get(cacheKey) + `
|
|
52464
|
+
|
|
52465
|
+
[NOTE: This result was already retrieved earlier. Do not request it again.]`;
|
|
52466
|
+
} else {
|
|
51662
52467
|
try {
|
|
51663
52468
|
setStage({ type: "thinking" });
|
|
51664
52469
|
if (parsed.kind === "shell") {
|
|
@@ -51667,47 +52472,78 @@ var ChatRunner = ({ repoPath }) => {
|
|
|
51667
52472
|
result2 = await fetchUrl(parsed.url);
|
|
51668
52473
|
} else if (parsed.kind === "read-file") {
|
|
51669
52474
|
result2 = readFile(parsed.filePath, repoPath);
|
|
52475
|
+
} else if (parsed.kind === "read-folder") {
|
|
52476
|
+
result2 = readFolder(parsed.folderPath, repoPath);
|
|
52477
|
+
} else if (parsed.kind === "grep") {
|
|
52478
|
+
result2 = grepFiles(parsed.pattern, parsed.glob, repoPath);
|
|
52479
|
+
} else if (parsed.kind === "delete-file") {
|
|
52480
|
+
result2 = deleteFile(parsed.filePath, repoPath);
|
|
52481
|
+
} else if (parsed.kind === "delete-folder") {
|
|
52482
|
+
result2 = deleteFolder(parsed.folderPath, repoPath);
|
|
52483
|
+
} else if (parsed.kind === "open-url") {
|
|
52484
|
+
result2 = openUrl(parsed.url);
|
|
52485
|
+
} else if (parsed.kind === "generate-pdf") {
|
|
52486
|
+
result2 = generatePdf(parsed.filePath, parsed.pdfContent, repoPath);
|
|
51670
52487
|
} else if (parsed.kind === "write-file") {
|
|
51671
52488
|
result2 = writeFile(parsed.filePath, parsed.fileContent, repoPath);
|
|
51672
52489
|
} else if (parsed.kind === "search") {
|
|
51673
52490
|
result2 = await searchWeb(parsed.query);
|
|
51674
52491
|
}
|
|
52492
|
+
if (cacheKey) {
|
|
52493
|
+
toolResultCache.current.set(cacheKey, result2);
|
|
52494
|
+
}
|
|
51675
52495
|
} catch (err) {
|
|
51676
52496
|
result2 = `Error: ${err instanceof Error ? err.message : "failed"}`;
|
|
51677
52497
|
}
|
|
51678
52498
|
}
|
|
51679
|
-
|
|
51680
|
-
|
|
51681
|
-
|
|
51682
|
-
|
|
51683
|
-
|
|
51684
|
-
|
|
51685
|
-
|
|
51686
|
-
|
|
51687
|
-
|
|
51688
|
-
|
|
51689
|
-
|
|
51690
|
-
|
|
51691
|
-
|
|
51692
|
-
|
|
51693
|
-
});
|
|
51694
|
-
}
|
|
51695
|
-
const toolName = parsed.kind === "shell" ? "shell" : parsed.kind === "fetch" ? "fetch" : parsed.kind === "read-file" ? "read-file" : parsed.kind === "search" ? "search" : "write-file";
|
|
51696
|
-
const toolContent = parsed.kind === "shell" ? parsed.command : parsed.kind === "fetch" ? parsed.url : parsed.kind === "search" ? parsed.query : parsed.filePath;
|
|
51697
|
-
const toolMsg = {
|
|
51698
|
-
role: "assistant",
|
|
51699
|
-
type: "tool",
|
|
51700
|
-
toolName,
|
|
51701
|
-
content: toolContent,
|
|
51702
|
-
result: result2,
|
|
51703
|
-
approved
|
|
52499
|
+
}
|
|
52500
|
+
if (approved && !result2.startsWith("Error:")) {
|
|
52501
|
+
const kindMap2 = {
|
|
52502
|
+
shell: "shell-run",
|
|
52503
|
+
fetch: "url-fetched",
|
|
52504
|
+
"read-file": "file-read",
|
|
52505
|
+
"read-folder": "file-read",
|
|
52506
|
+
grep: "file-read",
|
|
52507
|
+
"delete-file": "file-written",
|
|
52508
|
+
"delete-folder": "file-written",
|
|
52509
|
+
"open-url": "url-fetched",
|
|
52510
|
+
"generate-pdf": "file-written",
|
|
52511
|
+
"write-file": "file-written",
|
|
52512
|
+
search: "url-fetched"
|
|
51704
52513
|
};
|
|
51705
|
-
|
|
51706
|
-
|
|
51707
|
-
|
|
51708
|
-
|
|
51709
|
-
|
|
52514
|
+
appendHistory({
|
|
52515
|
+
kind: kindMap2[parsed.kind] ?? "shell-run",
|
|
52516
|
+
detail: parsed.kind === "shell" ? parsed.command : parsed.kind === "fetch" ? parsed.url : parsed.kind === "search" ? parsed.query : parsed.kind === "read-folder" ? parsed.folderPath : parsed.kind === "grep" ? `${parsed.pattern} ${parsed.glob}` : parsed.kind === "delete-file" ? parsed.filePath : parsed.kind === "delete-folder" ? parsed.folderPath : parsed.kind === "open-url" ? parsed.url : parsed.kind === "generate-pdf" ? parsed.filePath : parsed.filePath,
|
|
52517
|
+
summary: result2.split(`
|
|
52518
|
+
`)[0]?.slice(0, 120) ?? "",
|
|
52519
|
+
repoPath
|
|
52520
|
+
});
|
|
51710
52521
|
}
|
|
52522
|
+
const toolName = parsed.kind === "shell" ? "shell" : parsed.kind === "fetch" ? "fetch" : parsed.kind === "read-file" ? "read-file" : parsed.kind === "read-folder" ? "read-folder" : parsed.kind === "grep" ? "grep" : parsed.kind === "delete-file" ? "delete-file" : parsed.kind === "delete-folder" ? "delete-folder" : parsed.kind === "open-url" ? "open-url" : parsed.kind === "generate-pdf" ? "generate-pdf" : parsed.kind === "search" ? "search" : "write-file";
|
|
52523
|
+
const toolContent = parsed.kind === "shell" ? parsed.command : parsed.kind === "fetch" ? parsed.url : parsed.kind === "search" ? parsed.query : parsed.kind === "read-folder" ? parsed.folderPath : parsed.kind === "grep" ? `${parsed.pattern} — ${parsed.glob}` : parsed.kind === "delete-file" ? parsed.filePath : parsed.kind === "delete-folder" ? parsed.folderPath : parsed.kind === "open-url" ? parsed.url : parsed.kind === "generate-pdf" ? parsed.filePath : parsed.filePath;
|
|
52524
|
+
const toolMsg = {
|
|
52525
|
+
role: "assistant",
|
|
52526
|
+
type: "tool",
|
|
52527
|
+
toolName,
|
|
52528
|
+
content: toolContent,
|
|
52529
|
+
result: result2,
|
|
52530
|
+
approved
|
|
52531
|
+
};
|
|
52532
|
+
const withTool = [...currentAll, toolMsg];
|
|
52533
|
+
setAllMessages(withTool);
|
|
52534
|
+
setCommitted((prev) => [...prev, toolMsg]);
|
|
52535
|
+
setStage({ type: "thinking" });
|
|
52536
|
+
callChat(provider, systemPrompt, withTool).then((r) => processResponse(r, withTool)).catch(handleError(withTool));
|
|
52537
|
+
};
|
|
52538
|
+
if (autoApprove && isSafeTool) {
|
|
52539
|
+
executeAndContinue(true);
|
|
52540
|
+
return;
|
|
52541
|
+
}
|
|
52542
|
+
setStage({
|
|
52543
|
+
type: "permission",
|
|
52544
|
+
tool,
|
|
52545
|
+
pendingMessages: currentAll,
|
|
52546
|
+
resolve: executeAndContinue
|
|
51711
52547
|
});
|
|
51712
52548
|
return;
|
|
51713
52549
|
}
|
|
@@ -51757,6 +52593,18 @@ var ChatRunner = ({ repoPath }) => {
|
|
|
51757
52593
|
setShowReview(true);
|
|
51758
52594
|
return;
|
|
51759
52595
|
}
|
|
52596
|
+
if (text.trim().toLowerCase() === "/auto") {
|
|
52597
|
+
const next = !autoApprove;
|
|
52598
|
+
setAutoApprove(next);
|
|
52599
|
+
const msg = {
|
|
52600
|
+
role: "assistant",
|
|
52601
|
+
content: next ? "Auto-approve ON — read, search, grep and folder tools will run without asking. Write and code changes still require approval." : "Auto-approve OFF — all tools will ask for permission.",
|
|
52602
|
+
type: "text"
|
|
52603
|
+
};
|
|
52604
|
+
setCommitted((prev) => [...prev, msg]);
|
|
52605
|
+
setAllMessages((prev) => [...prev, msg]);
|
|
52606
|
+
return;
|
|
52607
|
+
}
|
|
51760
52608
|
if (text.trim().toLowerCase() === "/clear history") {
|
|
51761
52609
|
clearRepoHistory(repoPath);
|
|
51762
52610
|
const clearedMsg = {
|
|
@@ -51772,6 +52620,7 @@ var ChatRunner = ({ repoPath }) => {
|
|
|
51772
52620
|
const nextAll = [...allMessages, userMsg];
|
|
51773
52621
|
setCommitted((prev) => [...prev, userMsg]);
|
|
51774
52622
|
setAllMessages(nextAll);
|
|
52623
|
+
toolResultCache.current.clear();
|
|
51775
52624
|
setStage({ type: "thinking" });
|
|
51776
52625
|
callChat(provider, systemPrompt, nextAll).then((raw) => processResponse(raw, nextAll)).catch(handleError(nextAll));
|
|
51777
52626
|
};
|
|
@@ -52134,7 +52983,9 @@ Tip: type /timeline to browse commit history.`,
|
|
|
52134
52983
|
setInputValue("");
|
|
52135
52984
|
}
|
|
52136
52985
|
}, undefined, false, undefined, this),
|
|
52137
|
-
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(ShortcutBar, {
|
|
52986
|
+
/* @__PURE__ */ jsx_dev_runtime22.jsxDEV(ShortcutBar, {
|
|
52987
|
+
autoApprove
|
|
52988
|
+
}, undefined, false, undefined, this)
|
|
52138
52989
|
]
|
|
52139
52990
|
}, undefined, true, undefined, this)
|
|
52140
52991
|
]
|