@shawnstack/quickforge 1.6.7 → 1.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dist/assets/{AgentProfilesPage-XJdWmkQb.js → AgentProfilesPage-R7N7eDq5.js} +1 -1
- package/dist/assets/{ChatPanelHost-BrUHIzBw.js → ChatPanelHost-C4orgd5l.js} +2 -2
- package/dist/assets/{PluginsPage-DDxjlhiK.js → PluginsPage-3pZG7D7e.js} +1 -1
- package/dist/assets/{ScheduledTasksPage-Bw-pSpbv.js → ScheduledTasksPage-BAqoK4xk.js} +1 -1
- package/dist/assets/{SettingsWorkspacePage-B_7o3noo.js → SettingsWorkspacePage-DWkPyGP_.js} +3 -3
- package/dist/assets/{SharedConversationPage-B5DPQla3.js → SharedConversationPage-C-1n_MmB.js} +1 -1
- package/dist/assets/{TerminalDock-CVObjSM6.js → TerminalDock-B6KAXkIU.js} +1 -1
- package/dist/assets/{WorkspaceInspector-Dk5887WR.js → WorkspaceInspector-CkXyD_k4.js} +1 -1
- package/dist/assets/{WorkspaceReaderDialog-D-_BBvud.js → WorkspaceReaderDialog-Dp2QAwBo.js} +1 -1
- package/dist/assets/{diff-line-counts-DagL0jQr.js → diff-line-counts-Dm5kKQOo.js} +1 -1
- package/dist/assets/index-CZb_mGGF.js +63 -0
- package/dist/assets/{mcp-servers-dialog-CJ4HKWVZ.js → mcp-servers-dialog-VbGvNekJ.js} +1 -1
- package/dist/assets/otel-DQf3c6v2.js +3 -0
- package/dist/assets/pi-ai-DjJwSQBQ.js +131 -0
- package/dist/assets/pi-web-ui-DqxtBlZL.js +2803 -0
- package/dist/assets/{skills-dialog-CmCLl7K_.js → skills-dialog-B0jNVGZW.js} +1 -1
- package/dist/assets/{useAppTheme-BwZ5OEf3.js → useAppTheme-DsabFF9D.js} +1 -1
- package/dist/index.html +5 -5
- package/package.json +3 -3
- package/server/ai-http-logger.mjs +1 -1
- package/server/routes/agent-profiles.mjs +1 -1
- package/server/routes/models.mjs +1 -1
- package/server/routes/scheduled-tasks.mjs +1 -1
- package/server/routes/workspace.mjs +1 -1
- package/server/session-utils.mjs +1 -1
- package/server/utils/platform.mjs +25 -2
- package/dist/assets/index-DeUvsbzW.js +0 -63
- package/dist/assets/pi-ai-Cx633yhb.js +0 -134
- package/dist/assets/pi-web-ui-DFNE2m5b.js +0 -2770
- /package/dist/assets/{monaco-FCb94ino.js → monaco-CzxeAjEw.js} +0 -0
- /package/dist/assets/{plugin-api-UKg_cgSG.js → plugin-api-Ds5xGIL7.js} +0 -0
- /package/dist/assets/{xterm-BtSXYfUR.js → xterm-aPHkK8RR.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e,n as t}from"./rolldown-runtime-DWdDZTNf.js";import{Ft as n,Pt as r,Rt as i,_ as a,n as o,z as s}from"./icons-DHoaB5uq.js";import{n as c}from"./react-vendor-BR9MG2D-.js";import{rt as l,st as u,tt as d}from"./index-
|
|
1
|
+
import{i as e,n as t}from"./rolldown-runtime-DWdDZTNf.js";import{Ft as n,Pt as r,Rt as i,_ as a,n as o,z as s}from"./icons-DHoaB5uq.js";import{n as c}from"./react-vendor-BR9MG2D-.js";import{rt as l,st as u,tt as d}from"./index-CZb_mGGF.js";var f=t({SkillsDialog:()=>_,SkillsManagerPanel:()=>g}),p=e(i(),1),m=c();async function h(e){let t=await e.json().catch(()=>null);if(!e.ok)throw Error(t?.error||`HTTP ${e.status}`);return t}function g({active:e=!0,scope:t,project:i,embedded:c=!1,onClose:f,onSaved:g}){let[_,v]=(0,p.useState)([]),[y,b]=(0,p.useState)(()=>new Set),[x,S]=(0,p.useState)(``),[C,w]=(0,p.useState)([]),[T,E]=(0,p.useState)(!1),[D,O]=(0,p.useState)(!1),[k,A]=(0,p.useState)(``),j=t===`project`,[M,N]=(0,p.useState)(null),[P,F]=(0,p.useState)(null),[I,L]=(0,p.useState)(!1),[R,z]=(0,p.useState)(``),B=(0,p.useCallback)(()=>{N(null),F(null),z(``)},[]),V=(0,p.useCallback)(()=>{B(),f?.()},[f,B]);(0,p.useEffect)(()=>{if(!e||j&&!i)return;let t=!1;return(async()=>{E(!0),A(``);try{let e=j?`/api/skills?projectId=${encodeURIComponent(i.id)}`:`/api/skills?scope=global`,n=await h(await fetch(e));if(t)return;v(Array.isArray(n.skills)?n.skills:[]),b(new Set(Array.isArray(n.selectedSkills)?n.selectedSkills:[])),w(Array.isArray(n.searchPaths)?n.searchPaths:[])}catch(e){t||A(e instanceof Error?e.message:u(`failedToLoadSkills`))}finally{t||E(!1)}})(),()=>{t=!0}},[e,i,j]),(0,p.useEffect)(()=>{if(!e||c)return;let t=e=>{e.key===`Escape`&&(M?B():D||V())};return document.addEventListener(`keydown`,t),()=>document.removeEventListener(`keydown`,t)},[e,V,c,D,M,B]);let H=(0,p.useMemo)(()=>{let e=x.trim().toLowerCase();return e?_.filter(t=>[t.name,t.displayName,t.description,t.source,t.compatibility,t.allowedTools,...t.tags??[],...t.triggers??[]].filter(Boolean).join(` `).toLowerCase().includes(e)):_},[x,_]),U=async e=>{N(e),F(null),z(``),L(!0);try{let t=new URLSearchParams({name:e});j&&i?(t.set(`scope`,`project`),t.set(`projectId`,i.id)):t.set(`scope`,`global`),F(await h(await fetch(`/api/skills/content?${t}`)))}catch(e){z(e instanceof Error?e.message:u(`failedToReadSkill`))}finally{L(!1)}};if(!e||j&&!i)return null;let W=e=>{if(D)return;let t=new Set(y);t.has(e)?t.delete(e):t.add(e),b(t),G(t)},G=async e=>{O(!0),A(``);try{let n=await h(await fetch(j?`/api/skills/project`:`/api/skills/global`,{method:`PUT`,headers:{"content-type":`application/json`},body:JSON.stringify(j?{projectId:i.id,selectedSkills:[...e]}:{selectedSkills:[...e]})}));g({scope:t,project:j?n.projects?.find(e=>e.id===i.id)??{...i,skills:n.selectedSkills}:void 0,projects:n.projects,selectedSkills:n.selectedSkills})}catch(e){b(y),A(e instanceof Error?e.message:u(`failedToSaveSkills`))}finally{O(!1)}},K=u(j?`projectSkills`:`globalSkills`),q=j?u(`projectSkillsDescription`,{project:i.name}):u(`globalSkillsDescription`),J=(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`div`,{className:`quickforge-settings-divider p-3`,children:(0,m.jsxs)(`div`,{className:`quickforge-settings-inline-field`,children:[(0,m.jsx)(a,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground/60`}),(0,m.jsx)(`input`,{value:x,onChange:e=>S(e.target.value),placeholder:u(`searchSkills`),className:`quickforge-settings-input`,disabled:T||D})]})}),k?(0,m.jsx)(`div`,{className:`quickforge-settings-alert quickforge-settings-warning-attached`,children:k}):null,(0,m.jsxs)(`div`,{className:`quickforge-settings-toolbar`,children:[(0,m.jsx)(`span`,{className:`quickforge-settings-row-title`,children:u(`availableSkills`)}),(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-info`,children:u(`selectedSkillsCount`,{count:y.size})})]}),(0,m.jsx)(`div`,{className:c?``:`max-h-[46vh] overflow-y-auto`,children:T?(0,m.jsxs)(`div`,{className:`quickforge-settings-empty-row inline-flex items-center gap-2`,children:[(0,m.jsx)(s,{className:`size-4 animate-spin`}),u(`loading`)]}):H.length===0?(0,m.jsx)(`div`,{className:`quickforge-settings-empty-row`,children:u(`noMatchingSkills`)}):H.map(e=>{let t=y.has(e.name);return(0,m.jsxs)(`div`,{className:l(`quickforge-settings-list-item`,t&&`bg-muted/12`),children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-list-item-main`,children:[(0,m.jsx)(`div`,{className:`quickforge-settings-row-title`,children:e.displayName||e.name}),e.description?(0,m.jsx)(`div`,{className:`quickforge-settings-row-description`,children:e.description}):null,(0,m.jsxs)(`div`,{className:`quickforge-settings-meta`,children:[e.source?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e.source}):null,e.compatibility?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e.compatibility}):null,e.allowedTools?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e.allowedTools}):null,e.tags?.slice(0,5).map(e=>(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e},e))]})]}),(0,m.jsxs)(`div`,{className:`quickforge-settings-list-item-actions`,onClick:e=>e.stopPropagation(),children:[(0,m.jsxs)(`label`,{className:`quickforge-settings-switch`,"aria-disabled":D?`true`:`false`,children:[(0,m.jsx)(`input`,{type:`checkbox`,checked:t,disabled:D,onChange:()=>W(e.name),"aria-label":t?`Disable ${e.name}`:`Enable ${e.name}`}),(0,m.jsx)(`span`,{"aria-hidden":`true`})]}),(0,m.jsx)(`button`,{type:`button`,className:`quickforge-settings-icon-action`,onClick:()=>void U(e.name),disabled:D||I,title:u(`readSkill`),"aria-label":`${u(`readSkill`)}: ${e.displayName||e.name}`,children:(0,m.jsx)(r,{className:`size-4`})})]})]},e.name)})})]}),Y=(0,m.jsxs)(m.Fragment,{children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-toolbar`,children:[(0,m.jsxs)(`button`,{type:`button`,className:`quickforge-settings-button quickforge-settings-button-secondary`,onClick:B,disabled:I,children:[(0,m.jsx)(n,{className:`mr-2 size-4`}),u(`backToSkillList`)]}),(0,m.jsx)(`div`,{className:`quickforge-settings-row-main min-w-0`,children:(0,m.jsx)(`div`,{className:`quickforge-settings-row-title truncate`,children:P?.displayName||P?.name||M})})]}),(0,m.jsx)(`div`,{className:`p-4`,children:I?(0,m.jsxs)(`div`,{className:`quickforge-settings-empty-row inline-flex items-center gap-2`,children:[(0,m.jsx)(s,{className:`size-4 animate-spin`}),u(`loading`)]}):R?(0,m.jsx)(`div`,{className:`quickforge-settings-alert quickforge-settings-warning-attached`,children:R}):P?(0,m.jsxs)(m.Fragment,{children:[P.description?(0,m.jsx)(`div`,{className:`quickforge-settings-row-description mb-3`,children:P.description}):null,(0,m.jsxs)(`div`,{className:`quickforge-settings-meta mb-3`,children:[P.version?(0,m.jsxs)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:[`v`,P.version]}):null,P.source?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.source}):null,P.compatibility?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.compatibility}):null,P.allowedTools?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.allowedTools}):null,P.license?(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:P.license}):null,P.tags?.map(e=>(0,m.jsx)(`span`,{className:`quickforge-settings-badge quickforge-settings-badge-muted`,children:e},e))]}),P.triggers?.length?(0,m.jsxs)(`div`,{className:`quickforge-settings-row-description mb-3`,children:[`Triggers: `,P.triggers.join(`, `)]}):null,P.instructions?(0,m.jsx)(`pre`,{className:`whitespace-pre-wrap break-words rounded-md border border-border bg-muted/30 px-4 py-3 font-mono text-sm leading-6 text-foreground/80`,children:P.instructions}):(0,m.jsx)(`div`,{className:`quickforge-settings-empty-row`,children:u(`noSkillContent`)})]}):null})]});return c?(0,m.jsx)(`div`,{className:`quickforge-settings-stack`,children:(0,m.jsx)(`section`,{className:`quickforge-settings-section`,"aria-label":K,children:M?Y:(0,m.jsxs)(m.Fragment,{children:[C.length?(0,m.jsx)(`div`,{className:`px-5 pt-4`,children:(0,m.jsxs)(`span`,{className:`quickforge-settings-row-description break-all`,children:[u(`skillSearchPaths`),`: `,C.join(` · `)]})}):null,J]})})}):(0,m.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4`,onClick:e=>{e.target===e.currentTarget&&!D&&V()},children:(0,m.jsxs)(`div`,{className:`flex max-h-[85vh] w-full max-w-2xl flex-col rounded-lg border border-border bg-background shadow-quickforge`,children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-toolbar`,children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-row-main`,children:[(0,m.jsxs)(`div`,{className:`quickforge-settings-row-title`,children:[K,(0,m.jsx)(d,{label:q})]}),(0,m.jsx)(`div`,{className:`quickforge-settings-row-description`,children:q}),C.length?(0,m.jsxs)(`div`,{className:`quickforge-settings-row-description break-all`,children:[u(`skillSearchPaths`),`: `,C.join(` · `)]}):null]}),(0,m.jsx)(`button`,{type:`button`,className:`quickforge-settings-icon-action`,onClick:V,disabled:D,"aria-label":u(`close`),children:(0,m.jsx)(o,{className:`size-4`})})]}),(0,m.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto`,children:M?Y:J})]})})}function _({open:e,scope:t,project:n,onOpenChange:r,onSaved:i}){return(0,m.jsx)(g,{active:e,scope:t,project:n,onClose:()=>r(!1),onSaved:i})}export{f as n,_ as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{Rt as t}from"./icons-DHoaB5uq.js";import{y as n}from"./index-
|
|
1
|
+
import{i as e}from"./rolldown-runtime-DWdDZTNf.js";import{Rt as t}from"./icons-DHoaB5uq.js";import{y as n}from"./index-CZb_mGGF.js";var r=e(t(),1);function i(){let[e,t]=(0,r.useState)(()=>n());return(0,r.useEffect)(()=>{if(typeof document>`u`)return;let e=document.documentElement,r=()=>t(n());r();let i=new MutationObserver(r);return i.observe(e,{attributes:!0,attributeFilter:[`class`]}),()=>i.disconnect()},[]),e}export{i as t};
|
package/dist/index.html
CHANGED
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
<meta name="apple-mobile-web-app-title" content="QuickForge" />
|
|
12
12
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
13
13
|
<title>速构 QuickForge</title>
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-CZb_mGGF.js"></script>
|
|
15
15
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-DWdDZTNf.js">
|
|
16
|
-
<link rel="modulepreload" crossorigin href="/assets/pi-ai-
|
|
16
|
+
<link rel="modulepreload" crossorigin href="/assets/pi-ai-DjJwSQBQ.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="/assets/lit-vendor-Dr3cpBGF.js">
|
|
18
|
-
<link rel="modulepreload" crossorigin href="/assets/pi-web-ui-
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/assets/pi-web-ui-DqxtBlZL.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="/assets/css-utils-rkE68RDy.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="/assets/icons-DHoaB5uq.js">
|
|
21
21
|
<link rel="modulepreload" crossorigin href="/assets/react-vendor-BR9MG2D-.js">
|
|
22
22
|
<link rel="modulepreload" crossorigin href="/assets/logger-B65Akg8A.js">
|
|
23
|
-
<link rel="modulepreload" crossorigin href="/assets/index-
|
|
24
|
-
<link rel="modulepreload" crossorigin href="/assets/skills-dialog-
|
|
23
|
+
<link rel="modulepreload" crossorigin href="/assets/index-CZb_mGGF.js">
|
|
24
|
+
<link rel="modulepreload" crossorigin href="/assets/skills-dialog-B0jNVGZW.js">
|
|
25
25
|
<link rel="stylesheet" crossorigin href="/assets/index-C77QCHE9.css">
|
|
26
26
|
</head>
|
|
27
27
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shawnstack/quickforge",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.8",
|
|
4
4
|
"description": "AI chat application with Agent access modes for local workspace tools. React + Vite + Tailwind CSS frontend, local Node.js storage server.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"@dnd-kit/core": "^6.3.1",
|
|
52
52
|
"@dnd-kit/sortable": "^10.0.0",
|
|
53
53
|
"@dnd-kit/utilities": "^3.2.2",
|
|
54
|
-
"@earendil-works/pi-agent-core": "^0.
|
|
55
|
-
"@earendil-works/pi-ai": "^0.
|
|
54
|
+
"@earendil-works/pi-agent-core": "^0.80.3",
|
|
55
|
+
"@earendil-works/pi-ai": "^0.80.3",
|
|
56
56
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
57
57
|
"ws": "^8.20.1"
|
|
58
58
|
},
|
|
@@ -2,7 +2,7 @@ import fs from 'node:fs'
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
4
4
|
import { randomUUID } from 'node:crypto'
|
|
5
|
-
import { streamSimple } from '@earendil-works/pi-ai'
|
|
5
|
+
import { streamSimple } from '@earendil-works/pi-ai/compat'
|
|
6
6
|
import { logsDir } from './storage.mjs'
|
|
7
7
|
|
|
8
8
|
const PATCH_MARKER = Symbol.for('quickforge.aiHttpLogger.fetchPatched')
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { streamSimple } from '@earendil-works/pi-ai'
|
|
1
|
+
import { streamSimple } from '@earendil-works/pi-ai/compat'
|
|
2
2
|
import { sendJson, readJsonBody, decodeSegment } from '../utils/response.mjs'
|
|
3
3
|
import { readStore } from '../storage.mjs'
|
|
4
4
|
import { logger } from '../utils/logger.mjs'
|
package/server/routes/models.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { streamSimple } from '@earendil-works/pi-ai'
|
|
1
|
+
import { streamSimple } from '@earendil-works/pi-ai/compat'
|
|
2
2
|
import { readJsonBody, sendJson, decodeSegment } from '../utils/response.mjs'
|
|
3
3
|
import { readStore, atomicUpdate } from '../storage.mjs'
|
|
4
4
|
import { createAgent, getSessionEventBus, agentEvents, persistSessionState } from '../agent-manager.mjs'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { promises as fs } from 'node:fs'
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { spawn } from 'node:child_process'
|
|
4
|
-
import { streamSimple } from '@earendil-works/pi-ai'
|
|
4
|
+
import { streamSimple } from '@earendil-works/pi-ai/compat'
|
|
5
5
|
import { sendJson, readJsonBody } from '../utils/response.mjs'
|
|
6
6
|
import { projectContextFromId } from '../project-config.mjs'
|
|
7
7
|
import { readStore } from '../storage.mjs'
|
package/server/session-utils.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { streamSimple } from '@earendil-works/pi-ai'
|
|
1
|
+
import { streamSimple } from '@earendil-works/pi-ai/compat'
|
|
2
2
|
import { buildInstructionsPayload, projectContextFromId } from './project-config.mjs'
|
|
3
3
|
import { composeSystemPrompt } from './system-prompt.mjs'
|
|
4
4
|
import { listSubagentProfiles } from './agent-profiles.mjs'
|
|
@@ -131,6 +131,29 @@ async function findExistingFile(candidates) {
|
|
|
131
131
|
return undefined
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
async function findIntelliJIdeaExecutable() {
|
|
135
|
+
const roots = [
|
|
136
|
+
process.env.LOCALAPPDATA ? path.join(process.env.LOCALAPPDATA, 'Programs') : undefined,
|
|
137
|
+
process.env.PROGRAMFILES ? path.join(process.env.PROGRAMFILES, 'JetBrains') : undefined,
|
|
138
|
+
process.env['PROGRAMFILES(X86)'] ? path.join(process.env['PROGRAMFILES(X86)'], 'JetBrains') : undefined,
|
|
139
|
+
].filter(Boolean)
|
|
140
|
+
const candidates = []
|
|
141
|
+
|
|
142
|
+
for (const root of roots) {
|
|
143
|
+
const entries = await fs.readdir(root, { withFileTypes: true }).catch(() => [])
|
|
144
|
+
for (const entry of entries) {
|
|
145
|
+
if (!entry.isDirectory() || !entry.name.toLowerCase().includes('intellij idea')) continue
|
|
146
|
+
const dir = path.join(root, entry.name)
|
|
147
|
+
const stat = await fs.stat(dir).catch(() => null)
|
|
148
|
+
candidates.push({ file: path.join(dir, 'bin', 'idea64.exe'), mtimeMs: stat?.mtimeMs ?? 0 })
|
|
149
|
+
candidates.push({ file: path.join(dir, 'bin', 'idea.exe'), mtimeMs: stat?.mtimeMs ?? 0 })
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
candidates.sort((a, b) => b.mtimeMs - a.mtimeMs || Number(b.file.endsWith('idea64.exe')) - Number(a.file.endsWith('idea64.exe')))
|
|
154
|
+
return findExistingFile(candidates.map((candidate) => candidate.file))
|
|
155
|
+
}
|
|
156
|
+
|
|
134
157
|
export async function openPathInFileManager(targetPath) {
|
|
135
158
|
const resolved = path.resolve(String(targetPath || ''))
|
|
136
159
|
const stat = await fs.stat(resolved).catch(() => null)
|
|
@@ -223,7 +246,7 @@ export async function openPathInIDEA(targetPath) {
|
|
|
223
246
|
command = 'open'
|
|
224
247
|
args = ['-a', 'IntelliJ IDEA', resolved]
|
|
225
248
|
} else if (process.platform === 'win32') {
|
|
226
|
-
const
|
|
249
|
+
const fixedCandidates = [
|
|
227
250
|
process.env.LOCALAPPDATA ? path.join(process.env.LOCALAPPDATA, 'Programs', 'IntelliJ IDEA', 'bin', 'idea64.exe') : undefined,
|
|
228
251
|
process.env.LOCALAPPDATA ? path.join(process.env.LOCALAPPDATA, 'Programs', 'IntelliJ IDEA', 'bin', 'idea.exe') : undefined,
|
|
229
252
|
process.env.PROGRAMFILES ? path.join(process.env.PROGRAMFILES, 'JetBrains', 'IntelliJ IDEA', 'bin', 'idea64.exe') : undefined,
|
|
@@ -231,7 +254,7 @@ export async function openPathInIDEA(targetPath) {
|
|
|
231
254
|
process.env['PROGRAMFILES(X86)'] ? path.join(process.env['PROGRAMFILES(X86)'], 'JetBrains', 'IntelliJ IDEA', 'bin', 'idea64.exe') : undefined,
|
|
232
255
|
process.env['PROGRAMFILES(X86)'] ? path.join(process.env['PROGRAMFILES(X86)'], 'JetBrains', 'IntelliJ IDEA', 'bin', 'idea.exe') : undefined,
|
|
233
256
|
].filter(Boolean)
|
|
234
|
-
const ideaExecutable = await findExistingFile(
|
|
257
|
+
const ideaExecutable = await findExistingFile(fixedCandidates) ?? await findIntelliJIdeaExecutable()
|
|
235
258
|
if (ideaExecutable) {
|
|
236
259
|
command = ideaExecutable
|
|
237
260
|
args = [resolved]
|