mirror of
https://github.com/kunkunsh/kunkun.git
synced 2025-04-03 22:26:43 +00:00
Feature: add extension api (hide and paste) (#210)
* feat: add paste API to extension API * feat(desktop): enhance clipboard and hotkey utilities - Add `hideAndPaste` utility function to simplify window hiding and clipboard pasting - Adjust key press and sleep timings for more reliable input simulation - Implement window focus listener in clipboard extension - Bind input element reference for automatic focus management * feat(permissions): enhance clipboard permission handling - Update clipboard permission schema to include paste permission - Modify clipboard API to check for paste permission before executing - Refactor permission map and schema for more flexible permission management * feat(desktop): refactor extension command search and rendering - Add `svelte-inspect-value` for debugging - Implement new `ExtCmds` component to replace `ExtCmdsGroup` - Enhance extension command search with separate Fuse.js instances for installed and dev extensions - Simplify extension command filtering and rendering logic - Add derived stores for extension commands with improved type safety * feat(desktop): improve extension command search filtering * bump @kksh/api version * feat(permissions): add clipboard paste permission description
This commit is contained in:
parent
a92c266d32
commit
97cd20906f
@ -1,5 +1,12 @@
|
||||
# kksh
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "kksh",
|
||||
"module": "dist/cli.js",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"kksh": "./dist/cli.js",
|
||||
|
@ -1,5 +1,12 @@
|
||||
# create-kunkun
|
||||
|
||||
## 0.1.49
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.1.48
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "create-kunkun",
|
||||
"type": "module",
|
||||
"version": "0.1.48",
|
||||
"version": "0.1.49",
|
||||
"bin": {
|
||||
"create-kunkun": "dist/index.mjs"
|
||||
},
|
||||
|
@ -37,6 +37,7 @@
|
||||
"lz-string": "^1.5.0",
|
||||
"pretty-bytes": "^6.1.1",
|
||||
"semver": "^7.6.3",
|
||||
"svelte-inspect-value": "^0.2.2",
|
||||
"svelte-sonner": "^0.3.28",
|
||||
"sveltekit-superforms": "^2.22.1",
|
||||
"tauri-plugin-clipboard-api": "^2.1.11",
|
||||
|
@ -2,6 +2,8 @@ import { i18n } from "@/i18n"
|
||||
import { appState } from "@/stores"
|
||||
import { winExtMap } from "@/stores/winExtMap"
|
||||
import { helperAPI } from "@/utils/helper"
|
||||
import { paste } from "@/utils/hotkey"
|
||||
import { sleep } from "@/utils/time"
|
||||
import { trimSlash } from "@/utils/url"
|
||||
import { constructExtensionSupportDir } from "@kksh/api"
|
||||
import { db, spawnExtensionFileServer } from "@kksh/api/commands"
|
||||
@ -12,6 +14,7 @@ import { launchNewExtWindow, loadExtensionManifestFromDisk } from "@kksh/extensi
|
||||
import type { IKunkunFullServerAPI } from "@kunkunapi/src/api/server"
|
||||
import { convertFileSrc } from "@tauri-apps/api/core"
|
||||
import * as path from "@tauri-apps/api/path"
|
||||
import { getCurrentWindow } from "@tauri-apps/api/window"
|
||||
import * as fs from "@tauri-apps/plugin-fs"
|
||||
import { platform } from "@tauri-apps/plugin-os"
|
||||
import { goto } from "$app/navigation"
|
||||
@ -101,6 +104,11 @@ export async function onHeadlessCmdSelect(
|
||||
getSpawnedProcesses: async () => {
|
||||
console.log("getSpawnedProcesses")
|
||||
return []
|
||||
},
|
||||
paste: async () => {
|
||||
await getCurrentWindow().hide()
|
||||
await sleep(200)
|
||||
return paste()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -1,21 +1,12 @@
|
||||
import { getExtensionsFolder } from "@/constants"
|
||||
import { db } from "@kksh/api/commands"
|
||||
import type { ExtPackageJson, ExtPackageJsonExtra } from "@kksh/api/models"
|
||||
import type { CustomUiCmd, ExtPackageJsonExtra, HeadlessCmd, TemplateUiCmd } from "@kksh/api/models"
|
||||
import * as extAPI from "@kksh/extension"
|
||||
import { commandScore } from "@kksh/ui/utils"
|
||||
import * as path from "@tauri-apps/api/path"
|
||||
import * as fs from "@tauri-apps/plugin-fs"
|
||||
import Fuse from "fuse.js"
|
||||
import { derived, get, writable, type Readable, type Writable } from "svelte/store"
|
||||
import { derived, get, writable, type Writable } from "svelte/store"
|
||||
import { appConfig } from "./appConfig"
|
||||
import { appState } from "./appState"
|
||||
|
||||
export const fuse = new Fuse<ExtPackageJsonExtra>([], {
|
||||
includeScore: true,
|
||||
threshold: 0.2,
|
||||
keys: ["name"]
|
||||
})
|
||||
|
||||
function createExtensionsStore(): Writable<ExtPackageJsonExtra[]> & {
|
||||
init: () => Promise<void>
|
||||
getExtensionsFromStore: () => ExtPackageJsonExtra[]
|
||||
@ -47,7 +38,6 @@ function createExtensionsStore(): Writable<ExtPackageJsonExtra[]> & {
|
||||
function init() {
|
||||
return extAPI.loadAllExtensionsFromDb().then((exts) => {
|
||||
store.set(exts)
|
||||
fuse.setCollection(exts)
|
||||
})
|
||||
}
|
||||
|
||||
@ -235,62 +225,62 @@ function createExtensionsStore(): Writable<ExtPackageJsonExtra[]> & {
|
||||
}
|
||||
|
||||
export const extensions = createExtensionsStore()
|
||||
export const installedStoreExts = derived(extensions, ($extensions) => {
|
||||
const extContainerPath = get(appConfig).extensionsInstallDir
|
||||
if (!extContainerPath) return []
|
||||
return $extensions.filter((ext) => !extAPI.isExtPathInDev(extContainerPath, ext.extPath))
|
||||
})
|
||||
export const devStoreExts = derived(extensions, ($extensions) => {
|
||||
const extContainerPath = get(appConfig).extensionsInstallDir
|
||||
if (!extContainerPath) return []
|
||||
return $extensions.filter((ext) => extAPI.isExtPathInDev(extContainerPath, ext.extPath))
|
||||
})
|
||||
|
||||
export const installedStoreExts: Readable<ExtPackageJsonExtra[]> = derived(
|
||||
extensions,
|
||||
($extensionsStore) => {
|
||||
const extContainerPath = get(appConfig).extensionsInstallDir
|
||||
if (!extContainerPath) return []
|
||||
return $extensionsStore.filter((ext) => !extAPI.isExtPathInDev(extContainerPath, ext.extPath))
|
||||
}
|
||||
)
|
||||
export const devStoreExts: Readable<ExtPackageJsonExtra[]> = derived(
|
||||
extensions,
|
||||
($extensionsStore) => {
|
||||
const extContainerPath = get(appConfig).extensionsInstallDir
|
||||
if (!extContainerPath) return []
|
||||
return $extensionsStore.filter((ext) => extAPI.isExtPathInDev(extContainerPath, ext.extPath))
|
||||
}
|
||||
)
|
||||
export type StoreExtCmd = (CustomUiCmd | TemplateUiCmd | HeadlessCmd) & {
|
||||
ext: ExtPackageJsonExtra
|
||||
}
|
||||
|
||||
export const installedStoreExtsFiltered = derived(
|
||||
[installedStoreExts, appState],
|
||||
([$installedStoreExts, $appState]) => {
|
||||
return $appState.searchTerm
|
||||
? fuse.search($appState.searchTerm).map((result) => result.item)
|
||||
: $installedStoreExts
|
||||
}
|
||||
)
|
||||
export const cmdsFuse = new Fuse<StoreExtCmd>([], {
|
||||
includeScore: true,
|
||||
threshold: 0.2,
|
||||
keys: ["name"]
|
||||
})
|
||||
export const devCmdsFuse = new Fuse<StoreExtCmd>([], {
|
||||
includeScore: true,
|
||||
threshold: 0.2,
|
||||
keys: ["name"]
|
||||
})
|
||||
|
||||
export const devStoreExtsFiltered = derived(
|
||||
[devStoreExts, appState],
|
||||
([$devStoreExts, $appState]) => {
|
||||
return $appState.searchTerm
|
||||
? fuse.search($appState.searchTerm).map((result) => result.item)
|
||||
: $devStoreExts
|
||||
}
|
||||
)
|
||||
export const storeExtCmds = derived(installedStoreExts, ($exts) => {
|
||||
const cmds = $exts.flatMap((ext) => {
|
||||
return [
|
||||
...(ext.kunkun.customUiCmds ?? []),
|
||||
...(ext.kunkun.templateUiCmds ?? []),
|
||||
...(ext.kunkun.headlessCmds ?? [])
|
||||
].map((cmd) => ({ ...cmd, ext }))
|
||||
})
|
||||
cmdsFuse.setCollection(cmds)
|
||||
return cmds
|
||||
})
|
||||
export const devStoreExtCmds = derived(devStoreExts, ($exts) => {
|
||||
const cmds = $exts.flatMap((ext) => {
|
||||
return [
|
||||
...(ext.kunkun.customUiCmds ?? []),
|
||||
...(ext.kunkun.templateUiCmds ?? []),
|
||||
...(ext.kunkun.headlessCmds ?? [])
|
||||
].map((cmd) => ({ ...cmd, ext }))
|
||||
})
|
||||
devCmdsFuse.setCollection(cmds)
|
||||
return cmds
|
||||
})
|
||||
|
||||
// export const installedStoreExtsFiltered = derived(
|
||||
// [installedStoreExts, appState],
|
||||
// ([$installedStoreExts, $appState]) => {
|
||||
// return $installedStoreExts.filter(
|
||||
// (ext) => commandScore(ext.kunkun.name, $appState.searchTerm) > 0.5
|
||||
// )
|
||||
// }
|
||||
// )
|
||||
|
||||
// export const devStoreExtsFiltered = derived(
|
||||
// [devStoreExts, appState],
|
||||
// ([$devStoreExts, $appState]) => {
|
||||
// return $devStoreExts.filter((ext) => {
|
||||
// console.log(
|
||||
// "commandScore",
|
||||
// ext.kunkun.name,
|
||||
// $appState.searchTerm,
|
||||
// commandScore(ext.kunkun.name, $appState.searchTerm)
|
||||
// )
|
||||
// return commandScore(ext.kunkun.name, $appState.searchTerm) > 0.1
|
||||
// })
|
||||
// }
|
||||
// )
|
||||
export const storeSearchExtCmds = derived([storeExtCmds, appState], ([$extCmds, $appState]) => {
|
||||
return $appState.searchTerm
|
||||
? cmdsFuse.search($appState.searchTerm).map((result) => result.item)
|
||||
: $extCmds
|
||||
})
|
||||
export const devSearchExtCmds = derived([devStoreExtCmds, appState], ([$extCmds, $appState]) => {
|
||||
return $appState.searchTerm
|
||||
? devCmdsFuse.search($appState.searchTerm).map((result) => result.item)
|
||||
: $extCmds
|
||||
})
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { getAllWindows } from "@tauri-apps/api/window"
|
||||
import { app } from "@tauri-apps/api"
|
||||
import { getAllWindows, getCurrentWindow, type Window } from "@tauri-apps/api/window"
|
||||
import { isRegistered, register, unregister } from "@tauri-apps/plugin-global-shortcut"
|
||||
import { debug, info, warn } from "@tauri-apps/plugin-log"
|
||||
import * as os from "@tauri-apps/plugin-os"
|
||||
@ -78,12 +79,12 @@ export async function applyKeyComb(keys: userInput.Key[]) {
|
||||
// await Promise.all(keys.map((key) => userInput.key("KeyPress", key)))
|
||||
for (const key of keys) {
|
||||
await userInput.key("KeyPress", key)
|
||||
await sleep(20)
|
||||
await sleep(100)
|
||||
}
|
||||
await sleep(100)
|
||||
await sleep(150)
|
||||
for (const key of keys) {
|
||||
await userInput.key("KeyRelease", key)
|
||||
await sleep(20)
|
||||
await sleep(100)
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,3 +102,12 @@ export async function paste() {
|
||||
console.error("Unsupported platform: " + _platform)
|
||||
}
|
||||
}
|
||||
|
||||
export async function hideAndPaste(win?: Window) {
|
||||
return app
|
||||
.hide()
|
||||
.then(() => sleep(60))
|
||||
.then(() => (win ?? getCurrentWindow()).hide())
|
||||
.then(() => sleep(60))
|
||||
.then(() => paste())
|
||||
}
|
||||
|
@ -10,16 +10,12 @@
|
||||
appConfig,
|
||||
appConfigLoaded,
|
||||
appsFiltered,
|
||||
// appsFiltered,
|
||||
appsLoader,
|
||||
appState,
|
||||
devStoreExts,
|
||||
devStoreExtsFiltered,
|
||||
installedStoreExts,
|
||||
installedStoreExtsFiltered,
|
||||
quickLinks,
|
||||
quickLinksFiltered
|
||||
// quickLinksFiltered
|
||||
devSearchExtCmds,
|
||||
devStoreExtCmds,
|
||||
quickLinksFiltered,
|
||||
storeExtCmds,
|
||||
storeSearchExtCmds
|
||||
} from "@/stores"
|
||||
import { cmdQueries } from "@/stores/cmdQuery"
|
||||
import { isKeyboardEventFromInputElement } from "@/utils/dom"
|
||||
@ -29,13 +25,12 @@
|
||||
import {
|
||||
BuiltinCmds,
|
||||
CustomCommandInput,
|
||||
ExtCmdsGroup,
|
||||
ExtCmds,
|
||||
GlobalCommandPaletteFooter,
|
||||
QuickLinks,
|
||||
SystemCmds
|
||||
} from "@kksh/ui/main"
|
||||
import { cn } from "@kksh/ui/utils"
|
||||
import { Channel, invoke } from "@tauri-apps/api/core"
|
||||
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"
|
||||
import { getCurrentWindow, Window } from "@tauri-apps/api/window"
|
||||
import { platform } from "@tauri-apps/plugin-os"
|
||||
@ -43,7 +38,7 @@
|
||||
import { goto } from "$app/navigation"
|
||||
import { ArrowBigUpIcon, CircleXIcon, EllipsisVerticalIcon, RefreshCcwIcon } from "lucide-svelte"
|
||||
import { onMount } from "svelte"
|
||||
import * as shell from "tauri-plugin-shellx-api"
|
||||
import { Inspect } from "svelte-inspect-value"
|
||||
|
||||
const win = getCurrentWindow()
|
||||
let inputEle: HTMLInputElement | null = $state(null)
|
||||
@ -84,43 +79,6 @@
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
async function spawn() {
|
||||
const cmd = shell.Command.create("deno", ["run", "/Users/hk/Dev/kunkun/deno.ts"])
|
||||
cmd.stdout.on("data", (data) => {
|
||||
console.log("stdout", data)
|
||||
})
|
||||
const child = await cmd.spawn()
|
||||
console.log("child", child)
|
||||
setTimeout(() => {
|
||||
child
|
||||
.kill()
|
||||
.then(() => {
|
||||
console.log("child killed")
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("child kill error", err)
|
||||
})
|
||||
}, 5000)
|
||||
// invoke<number>("plugin:shellx|spawn", {
|
||||
// program: "deno",
|
||||
// args: ["run", "/Users/hk/Dev/kunkun/deno.ts"],
|
||||
// options: {},
|
||||
// onEvent: new Channel<CommandEvent<string>>()
|
||||
// }).then((pid) => {
|
||||
// console.log("spawned process (shell server) pid:", pid)
|
||||
// setTimeout(() => {
|
||||
// console.log("killing process (shell server) pid:", pid)
|
||||
// killPid(pid)
|
||||
// .then(() => {
|
||||
// console.log("killed process (shell server) pid:", pid)
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.error("kill process (shell server) pid:", pid, err)
|
||||
// })
|
||||
// }, 3000)
|
||||
// })
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window
|
||||
@ -135,6 +93,16 @@
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<!--
|
||||
<Inspect name="devStoreExts" value={$devStoreExts} />
|
||||
<Inspect name="extensions" value={$extensions} />
|
||||
<Inspect name="installedStoreExts" value={$installedStoreExts} />
|
||||
<Inspect name="storeSearchExtCmds" value={$storeSearchExtCmds} />
|
||||
<Inspect name="devSearchExtCmds" value={$devSearchExtCmds} />
|
||||
<Inspect name="storeExtCmds" value={$storeExtCmds} />
|
||||
<Inspect name="devStoreExtCmds" value={$devStoreExtCmds} />
|
||||
<Inspect name="$appState.searchTerm" value={$appState.searchTerm} />
|
||||
-->
|
||||
<Command.Root
|
||||
class={cn("h-screen rounded-lg shadow-md")}
|
||||
bind:value={$appState.highlightedCmd}
|
||||
@ -237,25 +205,23 @@
|
||||
</DropdownMenu.Root>
|
||||
{/snippet}
|
||||
</CustomCommandInput>
|
||||
<Button onclick={spawn}>Spawn</Button>
|
||||
<Command.List class="max-h-screen grow">
|
||||
<Command.Empty data-tauri-drag-region>No results found.</Command.Empty>
|
||||
{#if $appConfig.extensionsInstallDir && $devStoreExtsFiltered.length > 0}
|
||||
<ExtCmdsGroup
|
||||
extensions={$devStoreExtsFiltered}
|
||||
{#if $devStoreExtCmds.length > 0}
|
||||
<ExtCmds
|
||||
heading={m.command_group_heading_dev_ext()}
|
||||
extCmds={$devSearchExtCmds}
|
||||
hmr={$appConfig.hmr}
|
||||
isDev={true}
|
||||
onExtCmdSelect={commandLaunchers.onExtCmdSelect}
|
||||
hmr={$appConfig.hmr}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if $appConfig.extensionsInstallDir && $installedStoreExtsFiltered.length > 0}
|
||||
<ExtCmdsGroup
|
||||
extensions={$installedStoreExtsFiltered}
|
||||
{#if $storeExtCmds.length > 0}
|
||||
<ExtCmds
|
||||
heading={m.command_group_heading_ext()}
|
||||
isDev={false}
|
||||
extCmds={$storeSearchExtCmds}
|
||||
hmr={false}
|
||||
isDev={false}
|
||||
onExtCmdSelect={commandLaunchers.onExtCmdSelect}
|
||||
/>
|
||||
{/if}
|
||||
|
@ -1,15 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { paste } from "@/utils/hotkey"
|
||||
import { goBack, goHome } from "@/utils/route"
|
||||
import { listenToNewClipboardItem } from "@/utils/tauri-events"
|
||||
import { sleep } from "@/utils/time"
|
||||
import { hideAndPaste } from "@/utils/hotkey"
|
||||
import { goHome } from "@/utils/route"
|
||||
import { listenToNewClipboardItem, listenToWindowFocus } from "@/utils/tauri-events"
|
||||
import Icon from "@iconify/svelte"
|
||||
import { ClipboardContentType, db } from "@kksh/api/commands"
|
||||
import { SearchModeEnum, SQLSortOrderEnum, type ExtData } from "@kksh/api/models"
|
||||
import { Button, Command, Resizable } from "@kksh/svelte5"
|
||||
import { Constants } from "@kksh/ui"
|
||||
import { CustomCommandInput, GlobalCommandPaletteFooter } from "@kksh/ui/main"
|
||||
import { app } from "@tauri-apps/api"
|
||||
import type { UnlistenFn } from "@tauri-apps/api/event"
|
||||
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"
|
||||
import { platform } from "@tauri-apps/plugin-os"
|
||||
@ -20,12 +18,14 @@
|
||||
import ContentPreview from "./content-preview.svelte"
|
||||
|
||||
const _platform = platform()
|
||||
let inputEle = $state<HTMLInputElement | null>(null)
|
||||
const curWin = getCurrentWebviewWindow()
|
||||
let searchTerm = $state("")
|
||||
let clipboardHistoryList = $state<ExtData[]>([])
|
||||
let highlightedItemValue = $state<string>("")
|
||||
let highlighted = $state<ExtData | null>(null)
|
||||
let unlistenClipboard = $state<UnlistenFn | null>(null)
|
||||
let unlistenFocusEvt = $state<UnlistenFn | null>(null)
|
||||
let isScrolling = $state(false)
|
||||
let page = $state(1)
|
||||
|
||||
@ -74,10 +74,19 @@
|
||||
}).then((unlisten) => {
|
||||
unlistenClipboard = unlisten
|
||||
})
|
||||
|
||||
listenToWindowFocus(async () => {
|
||||
if (inputEle) {
|
||||
inputEle.focus()
|
||||
}
|
||||
}).then((unlisten) => {
|
||||
unlistenFocusEvt = unlisten
|
||||
})
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
unlistenClipboard?.()
|
||||
unlistenFocusEvt?.()
|
||||
})
|
||||
|
||||
$effect(() => {
|
||||
@ -191,11 +200,7 @@
|
||||
return Promise.reject(new Error("No data found"))
|
||||
}
|
||||
return writeToClipboard(data).then(async () => {
|
||||
return app
|
||||
.hide()
|
||||
.then(() => sleep(100))
|
||||
.then(() => curWin.hide())
|
||||
.then(() => paste())
|
||||
return hideAndPaste(curWin)
|
||||
})
|
||||
})
|
||||
.then(() => toast.success("Copied to clipboard"))
|
||||
@ -242,6 +247,7 @@
|
||||
autofocus
|
||||
placeholder="Type a command or search..."
|
||||
leftSlot={leftSlot as Snippet}
|
||||
bind:ref={inputEle}
|
||||
bind:value={searchTerm}
|
||||
/>
|
||||
<Resizable.PaneGroup direction="horizontal" class="w-full rounded-lg">
|
||||
|
@ -3,9 +3,11 @@
|
||||
import { i18n } from "@/i18n"
|
||||
import { appConfig, winExtMap } from "@/stores"
|
||||
import { helperAPI } from "@/utils/helper"
|
||||
import { paste } from "@/utils/hotkey"
|
||||
import { goBackOnEscape } from "@/utils/key"
|
||||
import { goHome } from "@/utils/route"
|
||||
import { positionToCssStyleString, positionToTailwindClasses } from "@/utils/style"
|
||||
import { sleep } from "@/utils/time"
|
||||
import { isInMainWindow } from "@/utils/window"
|
||||
import { db } from "@kksh/api/commands"
|
||||
import { CustomPosition, ThemeColor, type Position } from "@kksh/api/models"
|
||||
@ -19,6 +21,11 @@
|
||||
import { Button } from "@kksh/svelte5"
|
||||
import { cn } from "@kksh/ui/utils"
|
||||
import type { IKunkunFullServerAPI } from "@kunkunapi/src/api/server"
|
||||
import {
|
||||
RECORD_EXTENSION_PROCESS_EVENT,
|
||||
type IRecordExtensionProcessEvent
|
||||
} from "@kunkunapi/src/events"
|
||||
import { emitTo } from "@tauri-apps/api/event"
|
||||
import { getCurrentWindow } from "@tauri-apps/api/window"
|
||||
import { goto } from "$app/navigation"
|
||||
import { IframeParentIO, RPCChannel } from "kkrpc/browser"
|
||||
@ -28,6 +35,7 @@
|
||||
|
||||
let { data }: { data: PageData } = $props()
|
||||
const { loadedExt, url, extPath, extInfoInDB } = data
|
||||
let extSpawnedProcesses = $state<number[]>([])
|
||||
const appWin = getCurrentWindow()
|
||||
let iframeRef: HTMLIFrameElement
|
||||
let uiControl = $state<{
|
||||
@ -107,7 +115,25 @@
|
||||
|
||||
const serverAPI: IKunkunFullServerAPI = constructJarvisServerAPIWithPermissions(
|
||||
loadedExt.kunkun.permissions,
|
||||
loadedExt.extPath
|
||||
loadedExt.extPath,
|
||||
{
|
||||
recordSpawnedProcess: async (pid: number) => {
|
||||
extSpawnedProcesses = [...extSpawnedProcesses, pid]
|
||||
// winExtMap.registerProcess(appWin.label, pid)
|
||||
const curWin = await getCurrentWindow()
|
||||
await emitTo("main", RECORD_EXTENSION_PROCESS_EVENT, {
|
||||
windowLabel: curWin.label,
|
||||
pid
|
||||
} satisfies IRecordExtensionProcessEvent)
|
||||
// TODO: record process in a store
|
||||
},
|
||||
getSpawnedProcesses: () => Promise.resolve(extSpawnedProcesses),
|
||||
paste: async () => {
|
||||
await appWin.hide()
|
||||
await sleep(200)
|
||||
return paste()
|
||||
}
|
||||
}
|
||||
)
|
||||
const serverAPI2 = {
|
||||
...serverAPI,
|
||||
|
@ -3,13 +3,14 @@
|
||||
import { appState } from "@/stores/appState.js"
|
||||
import { keys } from "@/stores/keys"
|
||||
import { winExtMap } from "@/stores/winExtMap.js"
|
||||
import { WatchEvent } from "@/types/fs.js"
|
||||
import { helperAPI } from "@/utils/helper.js"
|
||||
import { paste } from "@/utils/hotkey"
|
||||
import {
|
||||
emitReloadOneExtension,
|
||||
listenToFileDrop,
|
||||
listenToRefreshDevExt
|
||||
} from "@/utils/tauri-events.js"
|
||||
import { sleep } from "@/utils/time.js"
|
||||
import { isInMainWindow } from "@/utils/window.js"
|
||||
import { db } from "@kksh/api/commands"
|
||||
import {
|
||||
@ -241,7 +242,12 @@
|
||||
} satisfies IRecordExtensionProcessEvent)
|
||||
// TODO: record process in a store
|
||||
},
|
||||
getSpawnedProcesses: () => Promise.resolve(extSpawnedProcesses)
|
||||
getSpawnedProcesses: () => Promise.resolve(extSpawnedProcesses),
|
||||
paste: async () => {
|
||||
await appWin.hide()
|
||||
await sleep(200)
|
||||
return paste()
|
||||
}
|
||||
}
|
||||
)
|
||||
const serverAPI2 = {
|
||||
|
5
deno.lock
generated
5
deno.lock
generated
@ -15177,6 +15177,7 @@
|
||||
"npm:eslint-config-prettier@^9.1.0",
|
||||
"npm:eslint-plugin-svelte@^2.46.1",
|
||||
"npm:eslint@^9.21.0",
|
||||
"npm:fuse.js@^7.1.0",
|
||||
"npm:globals@^15.14.0",
|
||||
"npm:gsap@^3.12.5",
|
||||
"npm:kkrpc@~0.1.1",
|
||||
@ -15193,6 +15194,7 @@
|
||||
"npm:tailwindcss-animate@^1.0.7",
|
||||
"npm:tailwindcss@^3.4.17",
|
||||
"npm:tauri-plugin-clipboard-api@^2.1.11",
|
||||
"npm:tauri-plugin-shellx-api@^2.0.15",
|
||||
"npm:tslib@^2.8.1",
|
||||
"npm:typescript-eslint@^8.20.0",
|
||||
"npm:typescript@^5.6.3",
|
||||
@ -15236,7 +15238,7 @@
|
||||
"npm:svelte-sonner@~0.3.28",
|
||||
"npm:tauri-api-adapter@~0.3.23",
|
||||
"npm:tauri-plugin-network-api@2.0.5",
|
||||
"npm:tauri-plugin-shellx-api@2.0.15",
|
||||
"npm:tauri-plugin-shellx-api@^2.0.15",
|
||||
"npm:tauri-plugin-system-info-api@2.0.8",
|
||||
"npm:typedoc@~0.27.6",
|
||||
"npm:typescript@5",
|
||||
@ -15574,6 +15576,7 @@
|
||||
"npm:tailwind-variants@0.3",
|
||||
"npm:tailwindcss-animate@^1.0.7",
|
||||
"npm:tailwindcss@^3.4.17",
|
||||
"npm:tauri-plugin-shellx-api@^2.0.15",
|
||||
"npm:typescript-eslint@^8.20.0",
|
||||
"npm:valibot@1.0.0-beta.12",
|
||||
"npm:zod@^3.24.1"
|
||||
|
@ -1,5 +1,11 @@
|
||||
# @kksh/api
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Add clipboard.paste() API
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@kksh/api",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.5",
|
||||
"type": "module",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -14,19 +14,11 @@ import type {
|
||||
writeFile,
|
||||
writeTextFile
|
||||
} from "@tauri-apps/plugin-fs"
|
||||
import type { IShell as IShell1, IPath as ITauriPath } from "tauri-api-adapter"
|
||||
import type {
|
||||
Child,
|
||||
ChildProcess,
|
||||
CommandEvents,
|
||||
hasCommand,
|
||||
InternalSpawnOptions,
|
||||
IOPayload,
|
||||
likelyOnWindows,
|
||||
OutputEvents,
|
||||
SpawnOptions
|
||||
} from "tauri-plugin-shellx-api"
|
||||
import { EventEmitter, open as shellxOpen } from "tauri-plugin-shellx-api"
|
||||
IClipboard as _IClipboard,
|
||||
IShell as IShell1,
|
||||
IPath as ITauriPath
|
||||
} from "tauri-api-adapter"
|
||||
import * as v from "valibot"
|
||||
import { KV, type JarvisExtDB } from "../commands/db"
|
||||
import type { fileSearch } from "../commands/fileSearch"
|
||||
@ -34,6 +26,10 @@ import { type AppInfo } from "../models/apps"
|
||||
import type { LightMode, Position, Radius, ThemeColor } from "../models/styles"
|
||||
import type { DenoSysOptions } from "../permissions/schema"
|
||||
|
||||
export type IClipboard = _IClipboard & {
|
||||
paste: (options?: {}) => Promise<void>
|
||||
}
|
||||
|
||||
type PromiseWrap<T extends (...args: any[]) => any> = (
|
||||
...args: Parameters<T>
|
||||
) => Promise<ReturnType<T>>
|
||||
|
18
packages/api/src/api/server/clipboard.ts
Normal file
18
packages/api/src/api/server/clipboard.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { constructClipboardApi as _constructClipboardApi } from "tauri-api-adapter"
|
||||
import { type ClipboardPermission as _ClipboardPermission } from "tauri-api-adapter/permissions"
|
||||
import type { ClipboardPermission } from "../../permissions/schema"
|
||||
import { checkPermission } from "../../utils/permission-check"
|
||||
import type { IClipboard } from "../client"
|
||||
|
||||
export function constructClipboardApi(
|
||||
permissions: ClipboardPermission[],
|
||||
paste: (options?: {}) => Promise<void>
|
||||
): IClipboard {
|
||||
return {
|
||||
..._constructClipboardApi(permissions.filter((p) => p !== "clipboard:paste")), // this constructor has no paste API
|
||||
paste: (options?: {}) => {
|
||||
checkPermission(permissions, ["clipboard:paste"])
|
||||
return paste(options)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
import {
|
||||
constructClipboardApi,
|
||||
constructDialogApi,
|
||||
constructFetchApi,
|
||||
// constructFsApi, // a local constructFsApi is defined
|
||||
@ -11,7 +10,7 @@ import {
|
||||
// constructShellApi, // a local custom constructShellApi is defined
|
||||
constructSystemInfoApi,
|
||||
constructUpdownloadApi,
|
||||
type IClipboard,
|
||||
// type IClipboard,
|
||||
type IDialog,
|
||||
type IFetchInternal,
|
||||
type ILogger,
|
||||
@ -37,7 +36,6 @@ import {
|
||||
type SystemInfoPermission,
|
||||
type UpdownloadPermission
|
||||
} from "tauri-api-adapter/permissions"
|
||||
import type { IEvent, IFs, IOpen, ISecurity, ISystem, IToast, IUtils } from "../../api/client"
|
||||
import type { IUiCustomServer1 } from "../../api/server-types"
|
||||
import {
|
||||
AllKunkunPermission,
|
||||
@ -50,6 +48,8 @@ import {
|
||||
type ShellPermissionScoped,
|
||||
type SystemPermission
|
||||
} from "../../permissions"
|
||||
import type { IClipboard, IEvent, IFs, IOpen, ISecurity, ISystem, IToast, IUtils } from "../client"
|
||||
import { constructClipboardApi } from "./clipboard"
|
||||
// import type { IDbServer } from "./db"
|
||||
import { constructEventApi } from "./event"
|
||||
import { constructFsApi } from "./fs"
|
||||
@ -130,13 +130,15 @@ export function constructJarvisServerAPIWithPermissions(
|
||||
customFunctions: {
|
||||
recordSpawnedProcess: (pid: number) => Promise<void>
|
||||
getSpawnedProcesses: () => Promise<number[]>
|
||||
paste: (options?: {}) => Promise<void>
|
||||
}
|
||||
): IKunkunFullServerAPI {
|
||||
return {
|
||||
clipboard: constructClipboardApi(
|
||||
getStringPermissions(permissions).filter((p) =>
|
||||
p.startsWith("clipboard:")
|
||||
) as ClipboardPermission[]
|
||||
) as ClipboardPermission[],
|
||||
customFunctions.paste
|
||||
),
|
||||
fetch: constructFetchApi(
|
||||
getStringPermissions(permissions).filter((p) => p.startsWith("fetch:")) as FetchPermission[]
|
||||
|
@ -46,7 +46,7 @@ export async function refreshTemplateWorkerCommandViaServer() {
|
||||
const ports = await findLocalhostKunkunPorts()
|
||||
console.log("Kunkun ports", ports)
|
||||
if (ports.length === 0) {
|
||||
console.error("Failed to find localhost kunkun ports")
|
||||
console.warn("\x1b[33mFailed to find localhost kunkun ports\x1b[0m")
|
||||
return
|
||||
} else if (ports.length > 1) {
|
||||
console.warn("Found multiple localhost kunkun ports", ports)
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { RPCChannel, WorkerChildIO, type DestroyableIoInterface } from "kkrpc/browser"
|
||||
import type {
|
||||
IClipboard,
|
||||
IDialog,
|
||||
// IEventInternal,
|
||||
IFetchInternal,
|
||||
@ -17,6 +16,7 @@ import type {
|
||||
import { constructFetchAPI, constructUpdownloadAPI } from "tauri-api-adapter/client"
|
||||
import type {
|
||||
IApp,
|
||||
IClipboard,
|
||||
IDb,
|
||||
IEvent,
|
||||
IFs,
|
||||
|
@ -17,6 +17,7 @@ export const permissionDescriptions: PermissionDescriptions = {
|
||||
"clipboard:write-image": "Allows writing images to the clipboard",
|
||||
"clipboard:read-files": "Allows reading copied files from the clipboard",
|
||||
"clipboard:write-files": "Allows writing files to the clipboard",
|
||||
"clipboard:paste": "Allows simulating paste operation",
|
||||
"dialog:all": "Allows access to system dialog APIs, e.g. confirm, save, open, etc.",
|
||||
"notification:all": "Allows sending system notifications",
|
||||
"os:all": "Allows access to all operating system information",
|
||||
|
@ -1,4 +1,9 @@
|
||||
import type { IShellServer } from "tauri-api-adapter"
|
||||
import {
|
||||
ClipboardPermissionMap as _ClipboardPermissionMap,
|
||||
ClipboardPermissionSchema as _ClipboardPermissionSchema
|
||||
} from "tauri-api-adapter/permissions"
|
||||
import * as v from "valibot"
|
||||
// import type { IEventServer, IFsServer, ISystemServer } from "../ui/server/server-types"
|
||||
import type { IEvent, IFs, ISecurity, ISystem } from "../api/client"
|
||||
import type {
|
||||
@ -13,7 +18,6 @@ import type {
|
||||
/* Re-export */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
export {
|
||||
ClipboardPermissionMap,
|
||||
DialogPermissionMap,
|
||||
NotificationPermissionMap,
|
||||
// FsPermissionMap,
|
||||
@ -24,6 +28,16 @@ export {
|
||||
UpdownloadPermissionMap
|
||||
} from "tauri-api-adapter/permissions"
|
||||
|
||||
// export const ClipboardPermissionMap = v.union([
|
||||
// _ClipboardPermissionSchema,
|
||||
// v.literal("clipboard:paste")
|
||||
// ])
|
||||
// export type ClipboardPermission = v.InferOutput<typeof ClipboardPermissionMap>
|
||||
export const ClipboardPermissionMap = {
|
||||
..._ClipboardPermissionMap,
|
||||
paste: ["clipboard:paste"]
|
||||
}
|
||||
|
||||
export const SecurityPermissionMap: {
|
||||
mac: Record<keyof ISecurity["mac"], SecurityPermission[]>
|
||||
} = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {
|
||||
ClipboardPermissionSchema,
|
||||
ClipboardPermissionSchema as _ClipboardPermissionSchema,
|
||||
DialogPermissionSchema,
|
||||
FetchPermissionSchema,
|
||||
FsPermissionSchema,
|
||||
@ -13,6 +13,12 @@ import {
|
||||
} from "tauri-api-adapter/permissions"
|
||||
import * as v from "valibot"
|
||||
|
||||
export const ClipboardPermissionSchema = v.union([
|
||||
_ClipboardPermissionSchema,
|
||||
v.literal("clipboard:paste")
|
||||
])
|
||||
export type ClipboardPermission = v.InferOutput<typeof ClipboardPermissionSchema>
|
||||
|
||||
export const SystemPermissionSchema = v.union([
|
||||
v.literal("system:volumn"),
|
||||
v.literal("system:boot"),
|
||||
|
@ -1,7 +1,6 @@
|
||||
// import { windowEndpoint, wrap, type Remote } from "@huakunshen/comlink"
|
||||
import { IframeChildIO, RPCChannel, type DestroyableIoInterface } from "kkrpc/browser"
|
||||
import type {
|
||||
IClipboard,
|
||||
IDialog,
|
||||
// IEventInternal,
|
||||
IFetchInternal,
|
||||
@ -22,6 +21,7 @@ import {
|
||||
} from "tauri-api-adapter/client"
|
||||
import type {
|
||||
IApp,
|
||||
IClipboard,
|
||||
IDb,
|
||||
IEvent,
|
||||
IFs,
|
||||
|
@ -5,7 +5,6 @@
|
||||
// import { RPCChannel, WorkerChildIO, type DestroyableIoInterface } from "kkrpc/browser"
|
||||
import { RPCChannel, WorkerChildIO, type DestroyableIoInterface } from "kkrpc/browser"
|
||||
import type {
|
||||
IClipboard,
|
||||
IDialog,
|
||||
// IEventInternal,
|
||||
IFetchInternal,
|
||||
@ -27,6 +26,7 @@ import {
|
||||
} from "tauri-api-adapter/client"
|
||||
import type {
|
||||
IApp,
|
||||
IClipboard,
|
||||
IDb,
|
||||
IEvent,
|
||||
IFs,
|
||||
|
@ -1,5 +1,12 @@
|
||||
# demo-template-extension
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../../schema/manifest-json-schema.json",
|
||||
"name": "demo-template-extension",
|
||||
"version": "0.0.10",
|
||||
"version": "0.0.11",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"kunkun": {
|
||||
|
@ -55,6 +55,7 @@ class ExtensionTemplate extends TemplateUiCommand {
|
||||
ui.showLoadingBar(true)
|
||||
setTimeout(() => {
|
||||
ui.showLoadingBar(false)
|
||||
clipboard.paste()
|
||||
}, 2000)
|
||||
const extPath = await path.extensionDir()
|
||||
const cmd = shell.createCommand("deno", ["run", "/Users/hk/Dev/kunkun/deno.ts"])
|
||||
|
@ -1,5 +1,12 @@
|
||||
# template-ext-sveltekit
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.kunkun.sh",
|
||||
"name": "ext-sveltekit-exp",
|
||||
"version": "0.0.10",
|
||||
"version": "0.0.11",
|
||||
"license": "MIT",
|
||||
"kunkun": {
|
||||
"name": "TODO: Change Display Name",
|
||||
@ -15,6 +15,7 @@
|
||||
"demoImages": [],
|
||||
"permissions": [
|
||||
"clipboard:read-text",
|
||||
"clipboard:paste",
|
||||
"notification:all",
|
||||
"dialog:all",
|
||||
"shell:kill",
|
||||
|
@ -12,75 +12,19 @@
|
||||
} from '@kksh/svelte5';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
onMount(() => {
|
||||
clipboard.readText().then((text) => {
|
||||
console.log('clipboard text', text);
|
||||
});
|
||||
});
|
||||
|
||||
function showDialog() {
|
||||
dialog
|
||||
.open({ directory: false })
|
||||
.then((res: any) => console.log(res))
|
||||
.catch((err: any) => {
|
||||
async function paste() {
|
||||
await clipboard
|
||||
.paste()
|
||||
.then(() => {
|
||||
console.log('pasted');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
async function testKkrpc() {
|
||||
const { rpcChannel, process, command } = await shell.createDenoRpcChannel<
|
||||
{},
|
||||
{
|
||||
echo: (paths: string[]) => Promise<string[]>;
|
||||
}
|
||||
>('$EXTENSION/deno-src/index.ts', [], {}, {});
|
||||
command.stderr.on('data', (data) => {
|
||||
'';
|
||||
console.log('stderr', data);
|
||||
});
|
||||
// command.stdout.on('data', (data) => {
|
||||
// console.log('stdout', data);
|
||||
// });
|
||||
const api = rpcChannel.getAPI();
|
||||
await api
|
||||
.echo([
|
||||
'/Users/hk/Desktop/_DSC2594.ARW',
|
||||
'/Users/hk/Desktop/_DSC2597.ARW',
|
||||
'/Users/hk/Desktop/_DSC2598.ARW',
|
||||
'/Users/hk/Desktop/DJI_20241128180028_0198_D.JPG',
|
||||
'/Users/hk/Desktop/_DSC2594.ARW',
|
||||
'/Users/hk/Desktop/_DSC2597.ARW',
|
||||
'/Users/hk/Desktop/_DSC2598.ARW',
|
||||
'/Users/hk/Desktop/DJI_20241128180028_0198_D.JPG',
|
||||
'/Users/hk/Desktop/_DSC2594.ARW',
|
||||
'/Users/hk/Desktop/_DSC2597.ARW',
|
||||
'/Users/hk/Desktop/_DSC2598.ARW',
|
||||
'/Users/hk/Desktop/DJI_20241128180028_0198_D.JPG',
|
||||
'/Users/hk/Desktop/_DSC2594.ARW',
|
||||
'/Users/hk/Desktop/_DSC2597.ARW',
|
||||
'/Users/hk/Desktop/_DSC2598.ARW',
|
||||
'/Users/hk/Desktop/DJI_20241128180028_0198_D.JPG',
|
||||
'/Users/hk/Desktop/_DSC2594.ARW',
|
||||
'/Users/hk/Desktop/_DSC2597.ARW',
|
||||
'/Users/hk/Desktop/_DSC2598.ARW',
|
||||
'/Users/hk/Desktop/DJI_20241128180028_0198_D.JPG',
|
||||
'/Users/hk/Desktop/_DSC2594.ARW',
|
||||
'/Users/hk/Desktop/_DSC2597.ARW',
|
||||
'/Users/hk/Desktop/_DSC2598.ARW',
|
||||
'/Users/hk/Desktop/DJI_20241128180028_0198_D.JPG',
|
||||
'/Users/hk/Desktop/_DSC2594.ARW',
|
||||
'/Users/hk/Desktop/_DSC2597.ARW',
|
||||
'/Users/hk/Desktop/_DSC2598.ARW',
|
||||
'/Users/hk/Desktop/DJI_20241128180028_0198_D.JPG'
|
||||
])
|
||||
.then(console.log)
|
||||
.catch(console.error);
|
||||
process.kill();
|
||||
}
|
||||
</script>
|
||||
|
||||
<div data-kunkun-drag-region class="h-12"></div>
|
||||
<div class="container">
|
||||
<Button onclick={showDialog}>Show Dialog</Button>
|
||||
<Button onclick={testKkrpc}>Test kkrpc</Button>
|
||||
<Button onclick={paste}>Paste</Button>
|
||||
</div>
|
||||
|
@ -1,5 +1,12 @@
|
||||
# template-ext-worker
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "./node_modules/@kksh/api/dist/schema.json",
|
||||
"name": "template-ext-headless",
|
||||
"version": "0.0.9",
|
||||
"version": "0.0.10",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"kunkun": {
|
||||
|
@ -1,5 +1,12 @@
|
||||
# template-ext-next
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "./node_modules/@kksh/api/dist/schema.json",
|
||||
"name": "template-ext-next",
|
||||
"version": "0.1.8",
|
||||
"version": "0.1.9",
|
||||
"license": "MIT",
|
||||
"kunkun": {
|
||||
"name": "TODO: Change Display Name",
|
||||
|
@ -1,5 +1,12 @@
|
||||
# template-ext-nuxt
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "./node_modules/@kksh/api/dist/schema.json",
|
||||
"name": "template-ext-nuxt",
|
||||
"version": "0.0.10",
|
||||
"version": "0.0.11",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"kunkun": {
|
||||
|
@ -1,5 +1,12 @@
|
||||
# template-ext-react
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
@ -2,7 +2,7 @@
|
||||
"$schema": "./node_modules/@kksh/api/dist/schema.json",
|
||||
"name": "template-ext-react",
|
||||
"license": "MIT",
|
||||
"version": "0.0.9",
|
||||
"version": "0.0.10",
|
||||
"type": "module",
|
||||
"kunkun": {
|
||||
"name": "TODO: Change Display Name",
|
||||
|
@ -1,5 +1,12 @@
|
||||
# template-ext-svelte
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
@ -2,7 +2,7 @@
|
||||
"$schema": "./node_modules/@kksh/api/dist/schema.json",
|
||||
"name": "template-ext-svelte",
|
||||
"license": "MIT",
|
||||
"version": "0.0.9",
|
||||
"version": "0.0.10",
|
||||
"type": "module",
|
||||
"kunkun": {
|
||||
"name": "TODO: Change Display Name",
|
||||
|
@ -1,5 +1,12 @@
|
||||
# template-ext-sveltekit
|
||||
|
||||
## 0.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "./node_modules/@kksh/api/dist/schema.json",
|
||||
"name": "template-ext-sveltekit",
|
||||
"version": "0.0.10",
|
||||
"version": "0.0.11",
|
||||
"license": "MIT",
|
||||
"kunkun": {
|
||||
"name": "TODO: Change Display Name",
|
||||
|
@ -1,5 +1,12 @@
|
||||
# template-ext-vue
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "template-ext-vue",
|
||||
"license": "MIT",
|
||||
"version": "0.0.7",
|
||||
"version": "0.0.8",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
@ -1,5 +1,12 @@
|
||||
# template-ext-worker
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @kksh/api@0.1.5
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "./node_modules/@kksh/api/dist/schema.json",
|
||||
"name": "template-ext-worker",
|
||||
"version": "0.0.9",
|
||||
"version": "0.0.10",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"kunkun": {
|
||||
|
71
packages/ui/src/components/main/ExtCmds.svelte
Normal file
71
packages/ui/src/components/main/ExtCmds.svelte
Normal file
@ -0,0 +1,71 @@
|
||||
<!-- This file renders a group of extension commands -->
|
||||
<!-- Input props to this component is an array of ExtPackageJsonExtra[] -->
|
||||
<script lang="ts">
|
||||
import {
|
||||
CmdTypeEnum,
|
||||
CustomUiCmd,
|
||||
ExtPackageJsonExtra,
|
||||
HeadlessCmd,
|
||||
TemplateUiCmd
|
||||
} from "@kksh/api/models"
|
||||
import { Badge, Command } from "@kksh/svelte5"
|
||||
import { IconMultiplexer } from "@kksh/ui"
|
||||
import { DraggableCommandGroup } from "../custom"
|
||||
import type { CmdValue, OnExtCmdSelect } from "./types"
|
||||
|
||||
type Cmd = (CustomUiCmd | TemplateUiCmd | HeadlessCmd) & { ext: ExtPackageJsonExtra }
|
||||
const {
|
||||
extCmds,
|
||||
heading,
|
||||
isDev,
|
||||
hmr,
|
||||
onExtCmdSelect
|
||||
}: {
|
||||
extCmds: Cmd[]
|
||||
heading: string
|
||||
isDev: boolean
|
||||
hmr: boolean
|
||||
onExtCmdSelect: OnExtCmdSelect
|
||||
} = $props()
|
||||
</script>
|
||||
|
||||
{#snippet cmd(cmd: Cmd)}
|
||||
<Command.Item
|
||||
class="flex justify-between"
|
||||
onSelect={() => {
|
||||
onExtCmdSelect(cmd.ext, cmd, { isDev, hmr })
|
||||
}}
|
||||
value={`${isDev ? "dev-ext" : "ext"}-${cmd.name}`}
|
||||
>
|
||||
<span class="flex gap-2">
|
||||
<IconMultiplexer icon={cmd.icon ?? cmd.ext.kunkun.icon} class="!h-5 !w-5 shrink-0" />
|
||||
<span>{cmd.name}</span>
|
||||
</span>
|
||||
<span class="flex gap-1">
|
||||
{#if isDev}
|
||||
<Badge class="scale-75 rounded-sm bg-green-500 px-1">Dev</Badge>
|
||||
{/if}
|
||||
{#if hmr}
|
||||
<Badge class="scale-75 rounded-sm px-1">HMR</Badge>
|
||||
{/if}
|
||||
</span>
|
||||
</Command.Item>
|
||||
{/snippet}
|
||||
<!--
|
||||
{#snippet ext(ext: ExtPackageJsonExtra)}
|
||||
{#each ext.kunkun.customUiCmds ?? [] as _cmd}
|
||||
{@render cmd(ext, _cmd)}
|
||||
{/each}
|
||||
{#each ext.kunkun.templateUiCmds ?? [] as _cmd}
|
||||
{@render cmd(ext, _cmd)}
|
||||
{/each}
|
||||
{#each ext.kunkun.headlessCmds ?? [] as _cmd}
|
||||
{@render cmd(ext, _cmd)}
|
||||
{/each}
|
||||
{/snippet} -->
|
||||
|
||||
<DraggableCommandGroup {heading}>
|
||||
{#each extCmds as _extCmd}
|
||||
{@render cmd(_extCmd)}
|
||||
{/each}
|
||||
</DraggableCommandGroup>
|
@ -4,4 +4,5 @@ export { default as GlobalCommandPaletteFooter } from "./GlobalCommandPaletteFoo
|
||||
export { default as ExtCmdsGroup } from "./ExtCmdsGroup.svelte"
|
||||
export { default as SystemCmds } from "./SystemCmds.svelte"
|
||||
export { default as QuickLinks } from "./QuickLinks.svelte"
|
||||
export { default as ExtCmds } from "./ExtCmds.svelte"
|
||||
export * from "./types"
|
||||
|
25
pnpm-lock.yaml
generated
25
pnpm-lock.yaml
generated
@ -266,6 +266,9 @@ importers:
|
||||
semver:
|
||||
specifier: ^7.6.3
|
||||
version: 7.6.3
|
||||
svelte-inspect-value:
|
||||
specifier: ^0.2.2
|
||||
version: 0.2.2(svelte@5.16.6)
|
||||
svelte-sonner:
|
||||
specifier: ^0.3.28
|
||||
version: 0.3.28(svelte@5.16.6)
|
||||
@ -7967,6 +7970,10 @@ packages:
|
||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||
hasBin: true
|
||||
|
||||
highlight.js@11.11.1:
|
||||
resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
hookable@5.5.3:
|
||||
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
|
||||
|
||||
@ -10676,6 +10683,11 @@ packages:
|
||||
svelte:
|
||||
optional: true
|
||||
|
||||
svelte-inspect-value@0.2.2:
|
||||
resolution: {integrity: sha512-Ly4QcIDoPo2O81CdIhx600bBaQdla65VXvXEMA9So947In8773Ey56k6A1WTsZiljAabxZFChBRqOt9nOYczuA==}
|
||||
peerDependencies:
|
||||
svelte: ^5.19.0
|
||||
|
||||
svelte-markdown@0.4.1:
|
||||
resolution: {integrity: sha512-pOlLY6EruKJaWI9my/2bKX8PdTeP5CM0s4VMmwmC2prlOkjAf+AOmTM4wW/l19Y6WZ87YmP8+ZCJCCwBChWjYw==}
|
||||
peerDependencies:
|
||||
@ -20361,6 +20373,8 @@ snapshots:
|
||||
|
||||
he@1.2.0: {}
|
||||
|
||||
highlight.js@11.11.1: {}
|
||||
|
||||
hookable@5.5.3: {}
|
||||
|
||||
hosted-git-info@7.0.2:
|
||||
@ -22827,12 +22841,12 @@ snapshots:
|
||||
|
||||
runed@0.20.0(svelte@5.16.6):
|
||||
dependencies:
|
||||
esm-env: 1.2.1
|
||||
esm-env: 1.2.2
|
||||
svelte: 5.16.6
|
||||
|
||||
runed@0.22.0(svelte@5.16.6):
|
||||
dependencies:
|
||||
esm-env: 1.2.1
|
||||
esm-env: 1.2.2
|
||||
svelte: 5.16.6
|
||||
|
||||
runed@0.23.2(svelte@5.16.6):
|
||||
@ -23286,6 +23300,13 @@ snapshots:
|
||||
optionalDependencies:
|
||||
svelte: 5.16.6
|
||||
|
||||
svelte-inspect-value@0.2.2(svelte@5.16.6):
|
||||
dependencies:
|
||||
esm-env: 1.2.2
|
||||
fast-deep-equal: 3.1.3
|
||||
highlight.js: 11.11.1
|
||||
svelte: 5.16.6
|
||||
|
||||
svelte-markdown@0.4.1(svelte@5.16.6):
|
||||
dependencies:
|
||||
'@types/marked': 5.0.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user