skill-creator 2.0.0 → 2.0.1
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/CHANGELOG.md +16 -0
- package/dist/cli.js +107 -27
- package/dist/cli.js.map +3 -3
- package/dist/daemon.js +106 -26
- package/dist/daemon.js.map +3 -3
- package/dist/package.json +1 -1
- package/dist/webui/_app/immutable/chunks/{BySEbwqx.js → B0pe_B_o.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{B_YFzSAv.js → BQ8kO0xi.js} +1 -1
- package/dist/webui/_app/immutable/chunks/BZ2Jwl6O.js +1 -0
- package/dist/webui/_app/immutable/chunks/{D25cXQtk.js → Bg2k7op5.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{DWcQbrnv.js → BoMQFGOq.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{DEtYLPO4.js → CGrKeCdk.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{IYkYSIV6.js → COoMyR0G.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{D-ecV3TD.js → CqzSRtkf.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{D0xHg31U.js → CsaIfA9E.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{DJNLWtK-.js → D-Jy42mM.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{B2zyE4XX.js → DPrjly2t.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{BD9g8Udg.js → FuwccWbx.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{BaH4uqzh.js → JcDjicYT.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{BrDKAjtR.js → O2CEZ91h.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{iicbWqXp.js → gkPAnPzC.js} +1 -1
- package/dist/webui/_app/immutable/chunks/{CEpOi93z.js → r1y9r7sj.js} +1 -1
- package/dist/webui/_app/immutable/entry/{app.CbFi8HIH.js → app.BisiObvX.js} +2 -2
- package/dist/webui/_app/immutable/entry/start.uEYh5tXy.js +1 -0
- package/dist/webui/_app/immutable/nodes/{0.C7-AKGsj.js → 0.C8yGM2gr.js} +2 -2
- package/dist/webui/_app/immutable/nodes/{1.raBmjc20.js → 1.BUJKZ337.js} +1 -1
- package/dist/webui/_app/immutable/nodes/{2.ewWz-Ki-.js → 2.Db-aM2Oa.js} +1 -1
- package/dist/webui/_app/version.json +1 -1
- package/dist/webui/index.html +14 -14
- package/package.json +1 -1
- package/dist/webui/_app/immutable/chunks/DLuJKUyD.js +0 -1
- package/dist/webui/_app/immutable/entry/start.C3bV1TCO.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.1 (2026-09-15)
|
|
4
|
+
|
|
5
|
+
Hotfix for the native file picker shipped in 2.0.0.
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **Native file picker never opened (macOS)** — the `@xmorse/rfd` async dialog
|
|
10
|
+
panics off the main thread in non-GUI host processes, leaving the RPC promise
|
|
11
|
+
pending forever: the attach buttons went dead with no dialog, no error, and no
|
|
12
|
+
way to recover without a restart. The picker now runs the synchronous dialog
|
|
13
|
+
in a dedicated child process (main-thread-safe, panic-isolated, watchdog at
|
|
14
|
+
10 minutes). Verified live: dialog opens and returns real paths, and picker
|
|
15
|
+
failures now surface a toast instead of failing silently.
|
|
16
|
+
- Concurrent picker requests from a second client get a typed
|
|
17
|
+
"dialog is already open" rejection instead of queueing invisibly.
|
|
18
|
+
|
|
3
19
|
## 2.0.0 (2026-09-14)
|
|
4
20
|
|
|
5
21
|
A major rewrite of the Skill Creator experience: model configuration rebuilt around
|
package/dist/cli.js
CHANGED
|
@@ -812,7 +812,9 @@ var init_image_codec = __esm({
|
|
|
812
812
|
});
|
|
813
813
|
|
|
814
814
|
// src/daemon/agent-files.ts
|
|
815
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
815
816
|
import { readFile as readFile2, readdir, realpath, stat } from "node:fs/promises";
|
|
817
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
816
818
|
import os3 from "node:os";
|
|
817
819
|
import path6 from "node:path";
|
|
818
820
|
function toDomainError(error, what, target) {
|
|
@@ -854,25 +856,87 @@ function compareEntries(a, b) {
|
|
|
854
856
|
if (a.kind !== b.kind) return a.kind === "dir" ? -1 : 1;
|
|
855
857
|
return a.name.localeCompare(b.name, "en", { sensitivity: "base", numeric: true });
|
|
856
858
|
}
|
|
857
|
-
function
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
859
|
+
function resolveRfdEntry() {
|
|
860
|
+
if (cachedRfdEntry !== null) return cachedRfdEntry;
|
|
861
|
+
try {
|
|
862
|
+
cachedRfdEntry = createRequire2(import.meta.url).resolve("@xmorse/rfd");
|
|
863
|
+
} catch {
|
|
864
|
+
throw new DomainError("UNAVAILABLE", "native file picker runtime is not installed");
|
|
865
|
+
}
|
|
866
|
+
return cachedRfdEntry;
|
|
867
|
+
}
|
|
868
|
+
function runPickerChild(request, options2 = {}) {
|
|
869
|
+
const entry = options2.entry ?? resolveRfdEntry();
|
|
870
|
+
const timeoutMs = options2.timeoutMs ?? PICKER_TIMEOUT_MS;
|
|
871
|
+
const child = spawn3(process.execPath, ["-e", PICKER_CHILD_CODE, JSON.stringify(request), entry], {
|
|
872
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
873
|
+
windowsHide: true
|
|
874
|
+
});
|
|
875
|
+
return new Promise((resolve2) => {
|
|
876
|
+
let stdout = "";
|
|
877
|
+
let stderrTail = "";
|
|
878
|
+
const timer = setTimeout(() => {
|
|
879
|
+
child.kill();
|
|
880
|
+
resolve2({ status: "failed", message: `picker timed out after ${String(timeoutMs)}ms` });
|
|
881
|
+
}, timeoutMs);
|
|
882
|
+
child.stdout.on("data", (chunk) => {
|
|
883
|
+
if (stdout.length < PICKER_STDOUT_LIMIT) stdout += chunk.toString("utf8");
|
|
884
|
+
});
|
|
885
|
+
child.stderr.on("data", (chunk) => {
|
|
886
|
+
stderrTail = (stderrTail + chunk.toString("utf8")).slice(-300);
|
|
887
|
+
});
|
|
888
|
+
child.on("error", (error) => {
|
|
889
|
+
clearTimeout(timer);
|
|
890
|
+
resolve2({ status: "failed", message: String(error) });
|
|
891
|
+
});
|
|
892
|
+
child.on("close", (code) => {
|
|
893
|
+
clearTimeout(timer);
|
|
870
894
|
try {
|
|
871
|
-
|
|
895
|
+
const parsed = JSON.parse(stdout);
|
|
896
|
+
if (parsed.ok === true && Array.isArray(parsed.paths)) {
|
|
897
|
+
const paths = parsed.paths.filter((value) => typeof value === "string");
|
|
898
|
+
resolve2(paths.length === 0 ? { status: "canceled" } : { status: "picked", paths });
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
if (parsed.ok === false && typeof parsed.message === "string") {
|
|
902
|
+
resolve2({ status: "failed", message: parsed.message });
|
|
903
|
+
return;
|
|
904
|
+
}
|
|
872
905
|
} catch {
|
|
873
906
|
}
|
|
907
|
+
const detail = stderrTail.trim();
|
|
908
|
+
resolve2({
|
|
909
|
+
status: "failed",
|
|
910
|
+
message: `picker exited with code ${String(code)}${detail.length > 0 ? `: ${detail}` : ""}`
|
|
911
|
+
});
|
|
912
|
+
});
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
function createAgentFilesService(deps = {}) {
|
|
916
|
+
const defaultDir = deps.defaultDir ?? (() => os3.homedir());
|
|
917
|
+
const runNativePicker = deps.runNativePicker ?? runPickerChild;
|
|
918
|
+
let pickerInFlight = null;
|
|
919
|
+
async function pickFiles(input) {
|
|
920
|
+
if (pickerInFlight !== null) {
|
|
921
|
+
throw new DomainError("INVALID_OPERATION", "file picker dialog is already open");
|
|
922
|
+
}
|
|
923
|
+
const request = input.mode === "image" ? {
|
|
924
|
+
title: "Select images",
|
|
925
|
+
filters: [{ name: "Images", exts: ["png", "jpg", "jpeg", "webp", "gif"] }]
|
|
926
|
+
} : { title: "Select files", filters: [] };
|
|
927
|
+
const inFlight = runNativePicker(request);
|
|
928
|
+
pickerInFlight = inFlight;
|
|
929
|
+
try {
|
|
930
|
+
const outcome = await inFlight;
|
|
931
|
+
if (outcome.status === "picked") return { paths: outcome.paths ?? [] };
|
|
932
|
+
if (outcome.status === "canceled") return { paths: [] };
|
|
933
|
+
throw new DomainError(
|
|
934
|
+
"UNAVAILABLE",
|
|
935
|
+
`native file picker failed: ${outcome.message ?? "unknown error"}`
|
|
936
|
+
);
|
|
937
|
+
} finally {
|
|
938
|
+
if (pickerInFlight === inFlight) pickerInFlight = null;
|
|
874
939
|
}
|
|
875
|
-
return { paths };
|
|
876
940
|
}
|
|
877
941
|
async function list2(input) {
|
|
878
942
|
const target = input.dir === void 0 ? defaultDir() : input.dir;
|
|
@@ -1022,7 +1086,7 @@ function createAgentFilesService(deps = {}) {
|
|
|
1022
1086
|
}
|
|
1023
1087
|
return { pickFiles, list: list2, preview: preview2, resolvePromptAttachments };
|
|
1024
1088
|
}
|
|
1025
|
-
var LIST_ENTRY_LIMIT, PREVIEW_IMAGE_MAX_BYTES, PREVIEW_TEXT_MAX_BYTES, PREVIEW_TEXT_HEAD_BYTES, PROMPT_IMAGE_MAX_BYTES, PROMPT_FILE_MAX_BYTES;
|
|
1089
|
+
var LIST_ENTRY_LIMIT, PREVIEW_IMAGE_MAX_BYTES, PREVIEW_TEXT_MAX_BYTES, PREVIEW_TEXT_HEAD_BYTES, PROMPT_IMAGE_MAX_BYTES, PROMPT_FILE_MAX_BYTES, PICKER_CHILD_CODE, PICKER_TIMEOUT_MS, PICKER_STDOUT_LIMIT, cachedRfdEntry;
|
|
1026
1090
|
var init_agent_files = __esm({
|
|
1027
1091
|
"src/daemon/agent-files.ts"() {
|
|
1028
1092
|
"use strict";
|
|
@@ -1034,6 +1098,22 @@ var init_agent_files = __esm({
|
|
|
1034
1098
|
PREVIEW_TEXT_HEAD_BYTES = 4096;
|
|
1035
1099
|
PROMPT_IMAGE_MAX_BYTES = 4 * 1024 * 1024;
|
|
1036
1100
|
PROMPT_FILE_MAX_BYTES = 512 * 1024;
|
|
1101
|
+
PICKER_CHILD_CODE = `"use strict";
|
|
1102
|
+
const write = (payload) => process.stdout.write(JSON.stringify(payload));
|
|
1103
|
+
try {
|
|
1104
|
+
const spec = JSON.parse(process.argv[1]);
|
|
1105
|
+
const rfd = require(process.argv[2]);
|
|
1106
|
+
let dialog = new rfd.FileDialog();
|
|
1107
|
+
if (spec.title) dialog = dialog.setTitle(spec.title);
|
|
1108
|
+
for (const filter of spec.filters) dialog = dialog.addFilter(filter.name, filter.exts);
|
|
1109
|
+
const paths = dialog.pickFiles();
|
|
1110
|
+
write({ ok: true, paths: Array.isArray(paths) ? paths : [] });
|
|
1111
|
+
} catch (error) {
|
|
1112
|
+
write({ ok: false, message: String((error && error.message) || error).slice(0, 300) });
|
|
1113
|
+
}`;
|
|
1114
|
+
PICKER_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
1115
|
+
PICKER_STDOUT_LIMIT = 64 * 1024;
|
|
1116
|
+
cachedRfdEntry = null;
|
|
1037
1117
|
}
|
|
1038
1118
|
});
|
|
1039
1119
|
|
|
@@ -1327,7 +1407,7 @@ var init_creator_service = __esm({
|
|
|
1327
1407
|
});
|
|
1328
1408
|
|
|
1329
1409
|
// node_modules/.pnpm/ccski@2.5.0/node_modules/ccski/dist/create-prompt-CIJV_96B.mjs
|
|
1330
|
-
import { createRequire as
|
|
1410
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
1331
1411
|
import { stripVTControlCharacters } from "node:util";
|
|
1332
1412
|
import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
|
|
1333
1413
|
import process$1 from "node:process";
|
|
@@ -1609,7 +1689,7 @@ var init_create_prompt_CIJV_96B = __esm({
|
|
|
1609
1689
|
value: mod,
|
|
1610
1690
|
enumerable: true
|
|
1611
1691
|
}) : target, mod));
|
|
1612
|
-
__require2 = /* @__PURE__ */
|
|
1692
|
+
__require2 = /* @__PURE__ */ createRequire3(import.meta.url);
|
|
1613
1693
|
isUpKey = (key, keybindings = []) => key.name === "up" || keybindings.includes("vim") && key.name === "k" || keybindings.includes("emacs") && key.ctrl && key.name === "p";
|
|
1614
1694
|
isDownKey = (key, keybindings = []) => key.name === "down" || keybindings.includes("vim") && key.name === "j" || keybindings.includes("emacs") && key.ctrl && key.name === "n";
|
|
1615
1695
|
isSpaceKey = (key) => key.name === "space";
|
|
@@ -5026,7 +5106,7 @@ import { TextDecoder } from "node:util";
|
|
|
5026
5106
|
import { homedir, tmpdir } from "node:os";
|
|
5027
5107
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5028
5108
|
import * as tty from "tty";
|
|
5029
|
-
import { spawn as
|
|
5109
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
5030
5110
|
import process$12 from "node:process";
|
|
5031
5111
|
import { randomUUID } from "node:crypto";
|
|
5032
5112
|
import { URL as URL$1 } from "url";
|
|
@@ -6792,7 +6872,7 @@ function registerInstallCleanupHandlers() {
|
|
|
6792
6872
|
}
|
|
6793
6873
|
async function getRemoteCommitHash(repo, ref = "HEAD", timeoutMs = 3e4) {
|
|
6794
6874
|
return new Promise((resolve$3, reject) => {
|
|
6795
|
-
const child =
|
|
6875
|
+
const child = spawn4("git", [
|
|
6796
6876
|
"ls-remote",
|
|
6797
6877
|
repo,
|
|
6798
6878
|
ref
|
|
@@ -6845,7 +6925,7 @@ async function gitCloneWithTimeout(repo, dest, branch, timeoutMs, output) {
|
|
|
6845
6925
|
];
|
|
6846
6926
|
if (branch) args.push("--branch", branch);
|
|
6847
6927
|
args.push(repo, dest);
|
|
6848
|
-
const child =
|
|
6928
|
+
const child = spawn4("git", args, { stdio: [
|
|
6849
6929
|
"ignore",
|
|
6850
6930
|
"pipe",
|
|
6851
6931
|
"pipe"
|
|
@@ -47635,7 +47715,7 @@ var init_provider_icons_generated = __esm({
|
|
|
47635
47715
|
// src/daemon/model-catalog.ts
|
|
47636
47716
|
import fs18 from "node:fs";
|
|
47637
47717
|
import path22 from "node:path";
|
|
47638
|
-
import { createRequire as
|
|
47718
|
+
import { createRequire as createRequire4 } from "node:module";
|
|
47639
47719
|
function labelOf(provider) {
|
|
47640
47720
|
for (const [id, label] of KNOWN_LABELS) {
|
|
47641
47721
|
if (id === provider) return label;
|
|
@@ -47646,7 +47726,7 @@ function labelOf(provider) {
|
|
|
47646
47726
|
return cn ? `${pretty} \xB7 CN` : pretty;
|
|
47647
47727
|
}
|
|
47648
47728
|
function resolveCatalogDataDir() {
|
|
47649
|
-
const require2 =
|
|
47729
|
+
const require2 = createRequire4(import.meta.url);
|
|
47650
47730
|
const basePkg = require2.resolve("@deepseek-ai/dsh-base/package.json");
|
|
47651
47731
|
const baseNm = path22.dirname(path22.dirname(path22.dirname(basePkg)));
|
|
47652
47732
|
const hostReal = fs18.realpathSync(path22.join(baseNm, "@deepseek-ai/dsh-llm-pi-ai"));
|
|
@@ -48765,7 +48845,7 @@ var init_proposals = __esm({
|
|
|
48765
48845
|
});
|
|
48766
48846
|
|
|
48767
48847
|
// src/daemon/steward/jsonrpc-stdio.ts
|
|
48768
|
-
import { spawn as
|
|
48848
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
48769
48849
|
function parseFrame2(raw) {
|
|
48770
48850
|
let value;
|
|
48771
48851
|
try {
|
|
@@ -48784,7 +48864,7 @@ function onceAbort(signal, onAbort) {
|
|
|
48784
48864
|
return () => signal.removeEventListener("abort", listener);
|
|
48785
48865
|
}
|
|
48786
48866
|
function defaultStdioSpawn(command, args, options2) {
|
|
48787
|
-
return
|
|
48867
|
+
return spawn5(command, args, { cwd: options2.cwd, stdio: ["pipe", "pipe", "pipe"] });
|
|
48788
48868
|
}
|
|
48789
48869
|
function parseCommandSpec(spec) {
|
|
48790
48870
|
const trimmed = spec.trim();
|
|
@@ -50376,7 +50456,7 @@ var init_skill_creator_mcp = __esm({
|
|
|
50376
50456
|
|
|
50377
50457
|
// src/cli/cli.ts
|
|
50378
50458
|
init_daemon();
|
|
50379
|
-
import { spawn as
|
|
50459
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
50380
50460
|
import fs22 from "node:fs";
|
|
50381
50461
|
import path28 from "node:path";
|
|
50382
50462
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
@@ -50707,7 +50787,7 @@ function spawnDaemon(webFlag = void 0) {
|
|
|
50707
50787
|
const isTs = entry.endsWith(".ts");
|
|
50708
50788
|
const baseEnv = { ...process.env };
|
|
50709
50789
|
const env2 = webFlag === void 0 ? baseEnv : { ...baseEnv, [SKILL_CREATOR_WEB_ENV]: webFlag ? "1" : "0" };
|
|
50710
|
-
const child = isTs ?
|
|
50790
|
+
const child = isTs ? spawn6("bun", [entry], { detached: true, stdio: "ignore", env: env2 }) : spawn6(process.execPath, [entry], { detached: true, stdio: "ignore", env: env2 });
|
|
50711
50791
|
child.unref();
|
|
50712
50792
|
}
|
|
50713
50793
|
async function ipcRequest(command, timeoutMs = 4e3, endpoint = socketPath()) {
|