dsh-office-kit 0.0.0-stage → 0.2.0
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/CAPABILITY.md +75 -0
- package/LICENSE.md +21 -0
- package/README.md +105 -2
- package/assets/icons/LICENSE +21 -0
- package/assets/icons/README.md +9 -0
- package/assets/icons/comment-fill.svg +1 -0
- package/assets/icons/display.svg +1 -0
- package/assets/icons/file-letter-p.svg +1 -0
- package/assets/icons/file-text.svg +1 -0
- package/assets/icons/layout-cells.svg +1 -0
- package/assets/skills/office-documents/SKILL.md +101 -0
- package/assets/skills/office-pdf/SKILL.md +86 -0
- package/assets/skills/office-presentations/SKILL.md +110 -0
- package/assets/skills/office-spreadsheets/SKILL.md +110 -0
- package/cordis.patch.yml +3 -0
- package/dist/client.js +267 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +408 -0
- package/package.json +143 -3
- package/postinstall.mjs +363 -0
- package/python/office_cli.py +1355 -0
- package/python/requirements.txt +10 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { BUNDLED_SKILL_RANK } from "@deepseek-ai/dsh-skill";
|
|
8
|
+
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
//#region src/features.ts
|
|
12
|
+
/** The four entries, in menu order. */
|
|
13
|
+
const OFFICE_FEATURES = [
|
|
14
|
+
{
|
|
15
|
+
id: "documents",
|
|
16
|
+
label: "Documents",
|
|
17
|
+
description: "Create, edit, render, and verify Word documents (.docx).",
|
|
18
|
+
hint: "DOCX",
|
|
19
|
+
skill: "office-documents",
|
|
20
|
+
command: "documents",
|
|
21
|
+
extensions: [".docx"]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "pdf",
|
|
25
|
+
label: "PDF",
|
|
26
|
+
description: "Create, read, edit, render, and verify PDF files.",
|
|
27
|
+
hint: "PDF",
|
|
28
|
+
skill: "office-pdf",
|
|
29
|
+
command: "pdf",
|
|
30
|
+
extensions: [".pdf"]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "presentations",
|
|
34
|
+
label: "Presentations",
|
|
35
|
+
description: "Create, edit, render, and verify slide decks (.pptx).",
|
|
36
|
+
hint: "PPTX",
|
|
37
|
+
skill: "office-presentations",
|
|
38
|
+
command: "presentations",
|
|
39
|
+
extensions: [".pptx"]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "spreadsheets",
|
|
43
|
+
label: "Spreadsheets",
|
|
44
|
+
description: "Create, edit, recalculate, render, and verify workbooks (.xlsx).",
|
|
45
|
+
hint: "XLSX",
|
|
46
|
+
skill: "office-spreadsheets",
|
|
47
|
+
command: "spreadsheets",
|
|
48
|
+
extensions: [".xlsx"]
|
|
49
|
+
}
|
|
50
|
+
];
|
|
51
|
+
/** Python packages the helper CLI needs. */
|
|
52
|
+
const PYTHON_PACKAGES = [
|
|
53
|
+
{
|
|
54
|
+
importName: "docx",
|
|
55
|
+
package: "python-docx"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
importName: "openpyxl",
|
|
59
|
+
package: "openpyxl"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
importName: "pptx",
|
|
63
|
+
package: "python-pptx"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
importName: "pypdf",
|
|
67
|
+
package: "pypdf"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
importName: "reportlab",
|
|
71
|
+
package: "reportlab"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
importName: "pdfplumber",
|
|
75
|
+
package: "pdfplumber"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
importName: "pymupdf",
|
|
79
|
+
package: "pymupdf"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
importName: "PIL",
|
|
83
|
+
package: "pillow"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
importName: "latex2mathml",
|
|
87
|
+
package: "latex2mathml"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
importName: "mathml2omml",
|
|
91
|
+
package: "mathml2omml"
|
|
92
|
+
}
|
|
93
|
+
];
|
|
94
|
+
/** Resolve per-OS config/data directories and bundled resources. */
|
|
95
|
+
function officePaths() {
|
|
96
|
+
const packageRoot = fileURLToPath(new URL("..", import.meta.url));
|
|
97
|
+
const home = homedir();
|
|
98
|
+
const configDir = process.platform === "win32" ? join(process.env.APPDATA ?? join(home, "AppData", "Roaming"), "dsh-office-kit") : process.platform === "darwin" ? join(home, "Library", "Application Support", "dsh-office-kit") : join(process.env.XDG_CONFIG_HOME ?? join(home, ".config"), "dsh-office-kit");
|
|
99
|
+
const dataDir = process.platform === "win32" ? join(process.env.LOCALAPPDATA ?? join(home, "AppData", "Local"), "dsh-office-kit") : process.platform === "darwin" ? join(home, "Library", "Application Support", "dsh-office-kit") : join(process.env.XDG_DATA_HOME ?? join(home, ".local", "share"), "dsh-office-kit");
|
|
100
|
+
return {
|
|
101
|
+
configFile: join(configDir, "config.json"),
|
|
102
|
+
dataDir,
|
|
103
|
+
cli: join(packageRoot, "python", "office_cli.py"),
|
|
104
|
+
skillsDir: join(packageRoot, "assets", "skills")
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function isFile(path) {
|
|
108
|
+
try {
|
|
109
|
+
return statSync(path).isFile();
|
|
110
|
+
} catch {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function run(file, args, timeout = 15e3) {
|
|
115
|
+
return new Promise((resolve, reject) => {
|
|
116
|
+
execFile(file, args, {
|
|
117
|
+
timeout,
|
|
118
|
+
windowsHide: true,
|
|
119
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
120
|
+
env: {
|
|
121
|
+
...process.env,
|
|
122
|
+
PYTHONIOENCODING: "utf-8"
|
|
123
|
+
}
|
|
124
|
+
}, (error, stdout) => {
|
|
125
|
+
if (error != null) {
|
|
126
|
+
reject(error);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
resolve(String(stdout).trim());
|
|
130
|
+
}).stdin?.end();
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
const VERSION_SCRIPT = "import json,sys;print(json.dumps({\"version\":sys.version.split()[0],\"executable\":sys.executable}))";
|
|
134
|
+
/** Inspect an absolute interpreter without trusting its path alone. */
|
|
135
|
+
async function inspectPython(path) {
|
|
136
|
+
try {
|
|
137
|
+
const raw = await run(path, ["-c", VERSION_SCRIPT]);
|
|
138
|
+
const parsed = JSON.parse(raw);
|
|
139
|
+
if (typeof parsed.version !== "string" || typeof parsed.executable !== "string") throw new Error("unexpected interpreter response");
|
|
140
|
+
const [majorText, minorText] = parsed.version.split(".");
|
|
141
|
+
const major = Number(majorText);
|
|
142
|
+
const minor = Number(minorText);
|
|
143
|
+
const compatible = major === 3 && minor >= 10 && minor < 14;
|
|
144
|
+
return {
|
|
145
|
+
path: parsed.executable,
|
|
146
|
+
version: parsed.version,
|
|
147
|
+
major,
|
|
148
|
+
minor,
|
|
149
|
+
compatible
|
|
150
|
+
};
|
|
151
|
+
} catch (error) {
|
|
152
|
+
return {
|
|
153
|
+
path,
|
|
154
|
+
version: "",
|
|
155
|
+
major: 0,
|
|
156
|
+
minor: 0,
|
|
157
|
+
compatible: false,
|
|
158
|
+
error: error instanceof Error ? error.message : String(error)
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/** Read the interpreter path postinstall recorded; malformed files are ignored. */
|
|
163
|
+
function savedPython(configFile) {
|
|
164
|
+
if (!isFile(configFile)) return void 0;
|
|
165
|
+
try {
|
|
166
|
+
const parsed = JSON.parse(readFileSync(configFile, "utf8"));
|
|
167
|
+
return typeof parsed.python === "string" && parsed.python.length > 0 ? parsed.python : void 0;
|
|
168
|
+
} catch {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/** PATH-independent candidate list, most specific first. */
|
|
173
|
+
function candidates(configFile) {
|
|
174
|
+
const found = [];
|
|
175
|
+
const env = process.env.DSH_OFFICE_PYTHON;
|
|
176
|
+
if (env != null && env.length > 0) found.push(env);
|
|
177
|
+
const saved = savedPython(configFile);
|
|
178
|
+
if (saved != null) found.push(saved);
|
|
179
|
+
const marker = join(fileURLToPath(new URL("..", import.meta.url)), ".python-path");
|
|
180
|
+
if (isFile(marker)) {
|
|
181
|
+
const text = readFileSync(marker, "utf8").trim();
|
|
182
|
+
if (text.length > 0) found.push(text);
|
|
183
|
+
}
|
|
184
|
+
for (const name of ["python3", "python"]) found.push(name);
|
|
185
|
+
if (process.platform === "win32") {
|
|
186
|
+
for (const version of [
|
|
187
|
+
"3.13",
|
|
188
|
+
"3.12",
|
|
189
|
+
"3.11",
|
|
190
|
+
"3.10"
|
|
191
|
+
]) found.push(`py -${version}`);
|
|
192
|
+
found.push("py -3");
|
|
193
|
+
}
|
|
194
|
+
return [...new Set(found)];
|
|
195
|
+
}
|
|
196
|
+
/** Resolve the launcher (`py -3.12`) into the absolute interpreter it runs. */
|
|
197
|
+
async function expandLauncher(candidate) {
|
|
198
|
+
if (!candidate.startsWith("py ")) return [candidate];
|
|
199
|
+
const args = candidate.split(" ").slice(1);
|
|
200
|
+
try {
|
|
201
|
+
const raw = await run("py", [
|
|
202
|
+
...args,
|
|
203
|
+
"-c",
|
|
204
|
+
"import sys;print(sys.executable)"
|
|
205
|
+
]);
|
|
206
|
+
return raw.length > 0 ? [raw] : [];
|
|
207
|
+
} catch {
|
|
208
|
+
return [];
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/** Interpreters the Windows `py` launcher reports, including tagged (non-numeric) installs. */
|
|
212
|
+
async function launcherInterpreters() {
|
|
213
|
+
if (process.platform !== "win32") return [];
|
|
214
|
+
try {
|
|
215
|
+
return (await run("py", ["-0p"])).split(/\r?\n/u).flatMap((line) => {
|
|
216
|
+
const match = /^\s*-V:\S+\s+([A-Z]:\\[^\r\n]*python\.exe)\s*$/iu.exec(line);
|
|
217
|
+
return match?.[1] != null ? [match[1]] : [];
|
|
218
|
+
});
|
|
219
|
+
} catch {
|
|
220
|
+
return [];
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/** Find the first runnable, compatible interpreter; return the best attempt otherwise. */
|
|
224
|
+
async function resolvePython(configFile = officePaths().configFile) {
|
|
225
|
+
let last;
|
|
226
|
+
for (const candidate of [...candidates(configFile), ...await launcherInterpreters()]) for (const expanded of await expandLauncher(candidate)) {
|
|
227
|
+
if (expanded !== candidate && !isFile(expanded)) continue;
|
|
228
|
+
const inspection = await inspectPython(expanded);
|
|
229
|
+
if (inspection.compatible) return inspection;
|
|
230
|
+
last = inspection;
|
|
231
|
+
}
|
|
232
|
+
return last;
|
|
233
|
+
}
|
|
234
|
+
/** Whether the helper CLI file shipped with this package. */
|
|
235
|
+
function cliExists() {
|
|
236
|
+
return isFile(officePaths().cli);
|
|
237
|
+
}
|
|
238
|
+
//#endregion
|
|
239
|
+
//#region src/index.ts
|
|
240
|
+
const execFileAsync = promisify(execFile);
|
|
241
|
+
/** Services required by this host half. */
|
|
242
|
+
const inject = ["skills", "tools"];
|
|
243
|
+
/** Cordis plugin identity used in loader diagnostics. */
|
|
244
|
+
const name = "dsh-office-kit";
|
|
245
|
+
const PROVIDER_NAME = "dsh-office-kit";
|
|
246
|
+
function parseSkill(raw, path) {
|
|
247
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/u.exec(raw);
|
|
248
|
+
if (match?.[1] == null) throw new Error(`dsh-office-kit: ${path} has no YAML frontmatter`);
|
|
249
|
+
const description = /^description:(.*)$/mu.exec(match[1])?.[1]?.trim();
|
|
250
|
+
if (description == null || description.length === 0) throw new Error(`dsh-office-kit: ${path} has no description`);
|
|
251
|
+
return {
|
|
252
|
+
description: description.replace(/^["']|["']$/gu, ""),
|
|
253
|
+
content: raw.slice(match[0].length).trim()
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function findFile(candidates) {
|
|
257
|
+
for (const path of candidates) if (existsSync(path)) return path;
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
function rendererFacts() {
|
|
261
|
+
const libreoffice = findFile([
|
|
262
|
+
process.env.SOFFICE ?? "",
|
|
263
|
+
"C:\\Program Files\\LibreOffice\\program\\soffice.exe",
|
|
264
|
+
"C:\\Program Files (x86)\\LibreOffice\\program\\soffice.exe",
|
|
265
|
+
"/Applications/LibreOffice.app/Contents/MacOS/soffice",
|
|
266
|
+
"/usr/bin/soffice",
|
|
267
|
+
"/usr/local/bin/soffice"
|
|
268
|
+
].filter(Boolean));
|
|
269
|
+
const officeRoots = ["C:\\Program Files\\Microsoft Office\\root\\Office16", "C:\\Program Files (x86)\\Microsoft Office\\root\\Office16"];
|
|
270
|
+
return {
|
|
271
|
+
libreoffice,
|
|
272
|
+
microsoftOffice: {
|
|
273
|
+
word: officeRoots.some((root) => existsSync(join(root, "WINWORD.EXE"))),
|
|
274
|
+
powerpoint: officeRoots.some((root) => existsSync(join(root, "POWERPNT.EXE"))),
|
|
275
|
+
excel: officeRoots.some((root) => existsSync(join(root, "EXCEL.EXE")))
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const PACKAGE_PROBE = `
|
|
280
|
+
import importlib, json, sys
|
|
281
|
+
targets = ${JSON.stringify(PYTHON_PACKAGES)}
|
|
282
|
+
out = {}
|
|
283
|
+
for item in targets:
|
|
284
|
+
try:
|
|
285
|
+
module = importlib.import_module(item["importName"])
|
|
286
|
+
out[item["package"]] = {"installed": True, "version": str(getattr(module, "__version__", ""))}
|
|
287
|
+
except Exception as exc:
|
|
288
|
+
out[item["package"]] = {"installed": False, "error": f"{type(exc).__name__}: {exc}"}
|
|
289
|
+
print(json.dumps({"python": sys.executable, "version": sys.version.split()[0], "packages": out}))
|
|
290
|
+
`.trim();
|
|
291
|
+
async function probePackages(python) {
|
|
292
|
+
try {
|
|
293
|
+
const { stdout } = await execFileAsync(python, ["-c", PACKAGE_PROBE], {
|
|
294
|
+
timeout: 3e4,
|
|
295
|
+
windowsHide: true,
|
|
296
|
+
maxBuffer: 2 * 1024 * 1024,
|
|
297
|
+
env: {
|
|
298
|
+
...process.env,
|
|
299
|
+
PYTHONIOENCODING: "utf-8"
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
return JSON.parse(String(stdout).trim());
|
|
303
|
+
} catch (error) {
|
|
304
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/** Register the four skills and a status tool, and expose the runtime paths in skill bodies. */
|
|
308
|
+
function apply(ctx) {
|
|
309
|
+
const paths = officePaths();
|
|
310
|
+
const candidates = [];
|
|
311
|
+
for (const feature of OFFICE_FEATURES) {
|
|
312
|
+
const directory = join(paths.skillsDir, feature.skill);
|
|
313
|
+
const path = join(directory, "SKILL.md");
|
|
314
|
+
if (!existsSync(path)) {
|
|
315
|
+
console.warn(`[dsh-office-kit] missing skill file: ${path}`);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
const candidate = {
|
|
319
|
+
name: feature.skill,
|
|
320
|
+
description: feature.description,
|
|
321
|
+
invocation: {
|
|
322
|
+
modelInvocable: true,
|
|
323
|
+
userInvocable: true
|
|
324
|
+
},
|
|
325
|
+
provider: PROVIDER_NAME,
|
|
326
|
+
source: "bundled",
|
|
327
|
+
rank: BUNDLED_SKILL_RANK,
|
|
328
|
+
resourceBase: {
|
|
329
|
+
kind: "directory",
|
|
330
|
+
path: directory.split("\\").join("/")
|
|
331
|
+
},
|
|
332
|
+
locator: path,
|
|
333
|
+
path
|
|
334
|
+
};
|
|
335
|
+
candidates.push(candidate);
|
|
336
|
+
}
|
|
337
|
+
const provider = {
|
|
338
|
+
name: PROVIDER_NAME,
|
|
339
|
+
list: () => Promise.resolve(candidates),
|
|
340
|
+
async get(candidate, options) {
|
|
341
|
+
if (!candidates.includes(candidate)) return void 0;
|
|
342
|
+
const path = String(candidate.locator);
|
|
343
|
+
let raw;
|
|
344
|
+
try {
|
|
345
|
+
raw = await readFile(path, {
|
|
346
|
+
encoding: "utf8",
|
|
347
|
+
signal: options.signal
|
|
348
|
+
});
|
|
349
|
+
} catch {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const parsed = parseSkill(raw, path);
|
|
353
|
+
const python = await resolvePython(paths.configFile);
|
|
354
|
+
const pythonLine = python?.compatible === true ? `\n\n## Office runtime\n\nUse these verified absolute paths for every helper command. Quote paths that contain spaces.\n\n\`\`\`json\n${JSON.stringify({
|
|
355
|
+
python: python.path,
|
|
356
|
+
cli: paths.cli,
|
|
357
|
+
version: python.version
|
|
358
|
+
}, null, 2)}\n\`\`\`` : "\n\n## Office runtime\n\nNo compatible Python was found. Ask the user to run `pnpm rebuild dsh-office-kit` (or `npm rebuild dsh-office-kit`) and check the install output before attempting file work.";
|
|
359
|
+
const { rank: _rank, locator: _locator, ...summary } = candidate;
|
|
360
|
+
return {
|
|
361
|
+
...summary,
|
|
362
|
+
description: parsed.description,
|
|
363
|
+
content: parsed.content + pythonLine
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
ctx.effect(() => ctx.skills.registerProvider(() => provider), "office-suite: skills");
|
|
368
|
+
ctx.effect(() => ctx.tools.register(defineTool({
|
|
369
|
+
name: "office_status",
|
|
370
|
+
description: "Report the Office runtime state: compatible Python, installed Python packages, helper CLI path, and document renderers (LibreOffice or Microsoft Office). Call this before Office file work.",
|
|
371
|
+
parameters: {},
|
|
372
|
+
output: {
|
|
373
|
+
schema: { type: "string" },
|
|
374
|
+
render: (_args, value) => [{
|
|
375
|
+
type: "text",
|
|
376
|
+
text: value
|
|
377
|
+
}]
|
|
378
|
+
},
|
|
379
|
+
timeoutMs: 45e3,
|
|
380
|
+
async execute() {
|
|
381
|
+
const python = await resolvePython(paths.configFile);
|
|
382
|
+
const seen = await (python?.compatible === true ? probePackages(python.path) : Promise.resolve(null));
|
|
383
|
+
const report = {
|
|
384
|
+
plugin: {
|
|
385
|
+
name,
|
|
386
|
+
version: "0.1.0"
|
|
387
|
+
},
|
|
388
|
+
python: python == null ? { found: false } : {
|
|
389
|
+
found: true,
|
|
390
|
+
path: python.path,
|
|
391
|
+
version: python.version,
|
|
392
|
+
compatible: python.compatible,
|
|
393
|
+
...python.error == null ? {} : { error: python.error }
|
|
394
|
+
},
|
|
395
|
+
cli: {
|
|
396
|
+
path: paths.cli,
|
|
397
|
+
exists: cliExists()
|
|
398
|
+
},
|
|
399
|
+
packages: seen,
|
|
400
|
+
renderers: rendererFacts(),
|
|
401
|
+
skills: candidates.map((candidate) => candidate.name)
|
|
402
|
+
};
|
|
403
|
+
return JSON.stringify(report, null, 2);
|
|
404
|
+
}
|
|
405
|
+
})), "office-suite: status tool");
|
|
406
|
+
}
|
|
407
|
+
//#endregion
|
|
408
|
+
export { apply, inject, name };
|
package/package.json
CHANGED
|
@@ -1,6 +1,146 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-office-kit",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"description": "Office documents, PDF, presentations, and spreadsheets for DeepSeek Harness",
|
|
6
|
+
"author": "Hairy",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://github.com/hairyf/dsh-office-kit#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/hairyf/dsh-office-kit.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": "https://github.com/hairyf/dsh-office-kit/issues",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"dsh-plugin",
|
|
16
|
+
"deepseek-harness",
|
|
17
|
+
"office",
|
|
18
|
+
"docx",
|
|
19
|
+
"pdf",
|
|
20
|
+
"pptx",
|
|
21
|
+
"xlsx"
|
|
22
|
+
],
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./dist/index.js",
|
|
26
|
+
"./client": "./dist/client.js",
|
|
27
|
+
"./package.json": "./package.json"
|
|
28
|
+
},
|
|
29
|
+
"main": "./dist/index.js",
|
|
30
|
+
"module": "./dist/index.js",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"files": [
|
|
33
|
+
"CAPABILITY.md",
|
|
34
|
+
"README.md",
|
|
35
|
+
"assets",
|
|
36
|
+
"cordis.patch.yml",
|
|
37
|
+
"dist",
|
|
38
|
+
"postinstall.mjs",
|
|
39
|
+
"python"
|
|
40
|
+
],
|
|
41
|
+
"dsh": {
|
|
42
|
+
"client": {
|
|
43
|
+
"inject": [
|
|
44
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
45
|
+
"@deepseek-ai/dsh-client-locale",
|
|
46
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
47
|
+
"@deepseek-ai/dsh-client-ui-conversation",
|
|
48
|
+
"@deepseek-ai/dsh-client-ui-input-trigger",
|
|
49
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right",
|
|
50
|
+
"@deepseek-ai/dsh-api-remotes"
|
|
51
|
+
],
|
|
52
|
+
"platform": "web"
|
|
53
|
+
},
|
|
54
|
+
"bundle": {
|
|
55
|
+
"patch": "./cordis.patch.yml"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"scripts-info": {
|
|
59
|
+
"build": "Build the library for publishing",
|
|
60
|
+
"dev": "Rebuild on change during development",
|
|
61
|
+
"lint": "Check for code style issues",
|
|
62
|
+
"prepack": "Build before publishing",
|
|
63
|
+
"release": "Bump version and publish a release",
|
|
64
|
+
"start": "Run the entry file",
|
|
65
|
+
"test": "Run the test suite",
|
|
66
|
+
"typecheck": "Check types",
|
|
67
|
+
"prepare": "Set up git hooks and skills"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@antfu/eslint-config": "^9.1.0",
|
|
71
|
+
"@antfu/ni": "^30.2.0",
|
|
72
|
+
"@antfu/utils": "^9.3.0",
|
|
73
|
+
"@deepseek-ai/cordis": "4.0.5",
|
|
74
|
+
"@deepseek-ai/cordis-plugin-group": "1.0.5",
|
|
75
|
+
"@deepseek-ai/cordis-plugin-include": "1.0.10",
|
|
76
|
+
"@deepseek-ai/cordis-plugin-loader": "1.0.6",
|
|
77
|
+
"@deepseek-ai/dsh-agent": "0.2.1-rc.2",
|
|
78
|
+
"@deepseek-ai/dsh-agent-default-model": "0.2.1-rc.2",
|
|
79
|
+
"@deepseek-ai/dsh-agent-loop": "0.2.1-rc.2",
|
|
80
|
+
"@deepseek-ai/dsh-agent-preset": "0.2.1-rc.2",
|
|
81
|
+
"@deepseek-ai/dsh-agent-preset-registry": "0.2.1-rc.2",
|
|
82
|
+
"@deepseek-ai/dsh-api-remotes": "0.2.1-rc.2",
|
|
83
|
+
"@deepseek-ai/dsh-api-session-controller": "0.2.1-rc.2",
|
|
84
|
+
"@deepseek-ai/dsh-api-workspace-controller": "0.2.1-rc.2",
|
|
85
|
+
"@deepseek-ai/dsh-client-connection": "0.2.1-rc.2",
|
|
86
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-rc.2",
|
|
87
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-rc.2",
|
|
88
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.2.1-rc.2",
|
|
89
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "0.2.1-rc.2",
|
|
90
|
+
"@deepseek-ai/dsh-client-ui-layout": "0.2.1-rc.2",
|
|
91
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.2",
|
|
92
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.2",
|
|
93
|
+
"@deepseek-ai/dsh-client-ui-session": "0.2.1-rc.2",
|
|
94
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-rc.2",
|
|
95
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": "0.2.1-rc.2",
|
|
96
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.2",
|
|
97
|
+
"@deepseek-ai/dsh-client-ui-theme": "0.2.1-rc.2",
|
|
98
|
+
"@deepseek-ai/dsh-client-ui-workspace": "0.2.1-rc.2",
|
|
99
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.1-rc.2",
|
|
100
|
+
"@deepseek-ai/dsh-llm": "0.2.1-rc.2",
|
|
101
|
+
"@deepseek-ai/dsh-permission-presets": "0.2.1-rc.2",
|
|
102
|
+
"@deepseek-ai/dsh-session": "0.2.1-rc.2",
|
|
103
|
+
"@deepseek-ai/dsh-session-persistence": "0.2.1-rc.2",
|
|
104
|
+
"@deepseek-ai/dsh-session-projection": "0.2.1-rc.2",
|
|
105
|
+
"@deepseek-ai/dsh-skill": "0.2.1-rc.2",
|
|
106
|
+
"@deepseek-ai/dsh-skill-filesystem": "0.2.1-rc.2",
|
|
107
|
+
"@deepseek-ai/dsh-tools": "0.2.1-rc.2",
|
|
108
|
+
"@deepseek-ai/dsh-user-approval": "0.2.1-rc.2",
|
|
109
|
+
"@deepseek-ai/dsh-user-questions": "0.2.1-rc.2",
|
|
110
|
+
"@deepseek-ai/dsh-util-code-language": "0.2.1-rc.2",
|
|
111
|
+
"@deepseek-ai/dsh-util-values": "0.2.1-rc.2",
|
|
112
|
+
"@deepseek-ai/dsh-workspace": "0.2.1-rc.2",
|
|
113
|
+
"@types/node": "^26.1.1",
|
|
114
|
+
"@types/react": "^18.2.0",
|
|
115
|
+
"@types/react-dom": "^18.2.0",
|
|
116
|
+
"bumpp": "^12.0.0",
|
|
117
|
+
"eslint": "^10.7.0",
|
|
118
|
+
"nano-staged": "^1.0.2",
|
|
119
|
+
"publint": "^0.3.21",
|
|
120
|
+
"react": "^18.2.0",
|
|
121
|
+
"simple-git-hooks": "^2.13.1",
|
|
122
|
+
"skills-npm": "^1.2.0",
|
|
123
|
+
"tsdown": "^0.22.12",
|
|
124
|
+
"tsnapi": "^1.0.0",
|
|
125
|
+
"tsx": "^4.23.1",
|
|
126
|
+
"typescript": "^6.0.3",
|
|
127
|
+
"vite": "^8.1.5",
|
|
128
|
+
"vitest": "^4.1.10"
|
|
129
|
+
},
|
|
130
|
+
"simple-git-hooks": {
|
|
131
|
+
"pre-commit": "pnpm i --frozen-lockfile --ignore-scripts --offline && pnpm run build && npx nano-staged"
|
|
132
|
+
},
|
|
133
|
+
"nano-staged": {
|
|
134
|
+
"*": "eslint --fix"
|
|
135
|
+
},
|
|
136
|
+
"scripts": {
|
|
137
|
+
"build": "tsdown",
|
|
138
|
+
"dev": "tsdown --watch",
|
|
139
|
+
"lint": "eslint",
|
|
140
|
+
"release": "bumpp",
|
|
141
|
+
"start": "tsx src/index.ts",
|
|
142
|
+
"test": "pnpm run build && vitest",
|
|
143
|
+
"typecheck": "tsc",
|
|
144
|
+
"postinstall": "node postinstall.mjs"
|
|
145
|
+
}
|
|
6
146
|
}
|