dsh-prompt-star 0.1.0 → 0.1.3
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/lib/client.js +92 -35
- package/lib/index.js +85 -269
- package/lib/types/client/StarButton.d.ts +31 -0
- package/lib/types/client/StarButton.js +95 -0
- package/lib/types/client/index.d.ts +21 -0
- package/lib/types/client/index.js +37 -0
- package/lib/types/index.d.ts +23 -0
- package/lib/types/index.js +81 -0
- package/lib/types/types.d.ts +45 -0
- package/lib/types/types.js +17 -0
- package/package.json +8 -13
package/lib/client.js
CHANGED
|
@@ -4,20 +4,26 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
-
let react = require("react");
|
|
8
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
-
|
|
8
|
+
let react = require("react");
|
|
9
|
+
//#region lib/types/client/StarButton.js
|
|
10
10
|
/**
|
|
11
|
-
* The ⭐ button rendered beside the conversation input.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* The ⭐ button rendered beside the conversation input.
|
|
12
|
+
*
|
|
13
|
+
* On click it reads the current draft (session input snapshot), asks the host
|
|
14
|
+
* (over the `/dsh-prompt-star` Connection RPC channel) to read a few project
|
|
15
|
+
* doc files as context, assembles a fuller, more efficient prompt on the client,
|
|
16
|
+
* then writes it back with `inputActions.setDraft`. Press Ctrl/Cmd+Z to restore
|
|
17
|
+
* the original draft.
|
|
15
18
|
*
|
|
16
19
|
* The slot framework composes this component's props: the session standard seat
|
|
17
|
-
* (`useInput`, `inputActions
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
+
* (`useInput`, `inputActions`) plus the register-time `context` face this client
|
|
21
|
+
* plugin injects. The interfaces below are the minimal structural shapes this
|
|
22
|
+
* component needs; they match the composed slot props without importing the
|
|
23
|
+
* harness client types.
|
|
20
24
|
*/
|
|
25
|
+
/** Common project-doc filenames are probed on the HOST; the client never
|
|
26
|
+
* enumerates them (it just asks the host for the read context). */
|
|
21
27
|
const buttonStyle = {
|
|
22
28
|
all: "unset",
|
|
23
29
|
display: "inline-flex",
|
|
@@ -32,7 +38,25 @@ window.__ModuleLoader__.load({
|
|
|
32
38
|
opacity: .9,
|
|
33
39
|
userSelect: "none"
|
|
34
40
|
};
|
|
35
|
-
|
|
41
|
+
/** Build a fuller, structured prompt from the draft + any project context. */
|
|
42
|
+
function assemblePrompt(draft, context) {
|
|
43
|
+
return [
|
|
44
|
+
"请把下面的【我的草稿】整理成一段完整、清晰、高效的提示词,直接输出整理后的提示词本身。",
|
|
45
|
+
"",
|
|
46
|
+
"整理要求:",
|
|
47
|
+
"1. 明确任务目标、所需上下文、约束条件与期望输出形式。",
|
|
48
|
+
"2. 若【项目文档】提供了相关规范、术语或背景,请吸收进去,使提示词更贴合项目。",
|
|
49
|
+
"3. 语气中立专业,结构清晰(可用编号、小节或列表),忠于草稿原意,不虚构。",
|
|
50
|
+
"4. 长度以覆盖草稿要点为准,不要过度扩写。",
|
|
51
|
+
"",
|
|
52
|
+
"# 项目文档",
|
|
53
|
+
context.docs.length === 0 ? "(未读取到项目文档)" : context.docs.map((doc) => `## ${doc.name}\n${doc.text}`).join("\n\n"),
|
|
54
|
+
"",
|
|
55
|
+
"# 我的草稿",
|
|
56
|
+
draft
|
|
57
|
+
].join("\n");
|
|
58
|
+
}
|
|
59
|
+
function StarButton({ context, useInput, inputActions }) {
|
|
36
60
|
const input = useInput();
|
|
37
61
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
38
62
|
const [error, setError] = (0, react.useState)(void 0);
|
|
@@ -45,49 +69,82 @@ window.__ModuleLoader__.load({
|
|
|
45
69
|
setBusy(true);
|
|
46
70
|
setError(void 0);
|
|
47
71
|
try {
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
72
|
+
const res = await context();
|
|
73
|
+
if (!res.ok) {
|
|
74
|
+
setError(`读取项目文档失败: ${res.error?.message ?? "未知错误"}`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const value = res.value;
|
|
78
|
+
const full = assemblePrompt(draft, value);
|
|
79
|
+
if (full && full !== draft) {
|
|
80
|
+
inputActions.setDraft(full);
|
|
81
|
+
setError(value.docs.length === 0 ? "已按草稿整理(未读取到项目文档)" : `已整理并读取 ${value.docs.length} 个项目文档`);
|
|
82
|
+
} else setError("未生成新内容");
|
|
57
83
|
} catch (cause) {
|
|
58
|
-
|
|
59
|
-
setError(`生成失败: ${message}`);
|
|
84
|
+
setError(`生成失败: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
60
85
|
} finally {
|
|
61
86
|
setBusy(false);
|
|
62
87
|
}
|
|
63
88
|
}
|
|
64
|
-
return
|
|
89
|
+
return (0, react_jsx_runtime.jsx)("button", {
|
|
65
90
|
type: "button",
|
|
66
91
|
style: buttonStyle,
|
|
67
|
-
title: error ?? "prompt-star:
|
|
92
|
+
title: error ?? "prompt-star: 整理成更完整的提示词",
|
|
68
93
|
disabled: busy,
|
|
69
94
|
onClick,
|
|
70
95
|
children: busy ? "…" : "⭐"
|
|
71
96
|
});
|
|
72
97
|
}
|
|
73
98
|
//#endregion
|
|
74
|
-
//#region
|
|
75
|
-
/**
|
|
76
|
-
|
|
99
|
+
//#region lib/types/types.js
|
|
100
|
+
/**
|
|
101
|
+
* dsh-prompt-star — host↔client RPC protocol (shared vocabulary).
|
|
102
|
+
*
|
|
103
|
+
* Transport: the generic Connection RPC channel `/dsh-prompt-star`
|
|
104
|
+
* (the host registers it with `ctx.connection.rpc.handle`, the browser calls
|
|
105
|
+
* `ctx.connection.rpc.call('/dsh-prompt-star', endpoint, payload)`).
|
|
106
|
+
*
|
|
107
|
+
* The host sells exactly one capability: reading a few project documentation
|
|
108
|
+
* files for the current workspace (it CAN read file contents natively; the
|
|
109
|
+
* browser client cannot). Everything else — assembling the fuller prompt from
|
|
110
|
+
* the draft + that context — stays on the client.
|
|
111
|
+
*/
|
|
112
|
+
/** Absolute logical Connection RPC channel owned by this plugin. */
|
|
113
|
+
const RPC_CHANNEL = "/dsh-prompt-star";
|
|
114
|
+
/** Channel-relative endpoint that reads project doc files on the host. */
|
|
115
|
+
const EP_CONTEXT = "context";
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region lib/types/client/index.js
|
|
118
|
+
/**
|
|
119
|
+
* Client plugin: mounts the ⭐ button into the composer input tool row
|
|
120
|
+
* (`conversation.input.right`, a session-scoped list slot) and wires it to the
|
|
121
|
+
* host's `/dsh-prompt-star` Connection RPC channel.
|
|
122
|
+
*
|
|
123
|
+
* This client half only needs the slot registry and the `connection` service.
|
|
124
|
+
* On click the button asks the host for project doc context (the browser cannot
|
|
125
|
+
* read file contents itself), then assembles the fuller prompt on the client and
|
|
126
|
+
* writes it back with `inputActions.setDraft`.
|
|
127
|
+
*/
|
|
128
|
+
/** Cordis services this client plugin needs: the slot registry and the
|
|
129
|
+
* Connection service (both provided by the stock web-app composition). */
|
|
130
|
+
const inject = ["slots", "connection"];
|
|
77
131
|
/**
|
|
78
132
|
* Client plugin body: register the ⭐ button once the slot registry and the
|
|
79
|
-
*
|
|
133
|
+
* Connection service are up.
|
|
80
134
|
* @param ctx - client root context.
|
|
81
135
|
*/
|
|
82
136
|
function apply(ctx) {
|
|
83
|
-
ctx.inject(["slots", "
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
137
|
+
ctx.inject(["slots", "connection"], (scope) => {
|
|
138
|
+
const root = scope;
|
|
139
|
+
const rpc = root.connection.rpc;
|
|
140
|
+
root.slots.inject("conversation.input.right", () => {
|
|
141
|
+
root.slots.register({
|
|
142
|
+
name: "conversation.input.right",
|
|
143
|
+
id: "prompt-star",
|
|
144
|
+
order: 0,
|
|
145
|
+
inject: () => ({ context: () => rpc.call(RPC_CHANNEL, EP_CONTEXT, {}) })
|
|
146
|
+
}, StarButton);
|
|
147
|
+
});
|
|
91
148
|
});
|
|
92
149
|
}
|
|
93
150
|
//#endregion
|
package/lib/index.js
CHANGED
|
@@ -1,283 +1,99 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
17
|
-
if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
|
|
18
|
-
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
19
|
-
t && (o = function o() {
|
|
20
|
-
try {
|
|
21
|
-
t.call(e);
|
|
22
|
-
} catch (r) {
|
|
23
|
-
return Promise.reject(r);
|
|
24
|
-
}
|
|
25
|
-
}), n.push({
|
|
26
|
-
v: e,
|
|
27
|
-
d: o,
|
|
28
|
-
a: r
|
|
29
|
-
});
|
|
30
|
-
} else r && n.push({
|
|
31
|
-
d: e,
|
|
32
|
-
a: r
|
|
33
|
-
});
|
|
34
|
-
return e;
|
|
35
|
-
}
|
|
36
|
-
return {
|
|
37
|
-
e,
|
|
38
|
-
u: using.bind(null, !1),
|
|
39
|
-
a: using.bind(null, !0),
|
|
40
|
-
d: function d() {
|
|
41
|
-
var o, t = this.e, s = 0;
|
|
42
|
-
function next() {
|
|
43
|
-
for (; o = n.pop();) try {
|
|
44
|
-
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
45
|
-
if (o.d) {
|
|
46
|
-
var r = o.d.call(o.v);
|
|
47
|
-
if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
|
|
48
|
-
} else s |= 1;
|
|
49
|
-
} catch (r) {
|
|
50
|
-
return err(r);
|
|
51
|
-
}
|
|
52
|
-
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
53
|
-
if (t !== e) throw t;
|
|
54
|
-
}
|
|
55
|
-
function err(n) {
|
|
56
|
-
return t = t !== e ? new r(n, t) : n, next();
|
|
57
|
-
}
|
|
58
|
-
return next();
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
}
|
|
1
|
+
//#region lib/types/types.js
|
|
2
|
+
/**
|
|
3
|
+
* dsh-prompt-star — host↔client RPC protocol (shared vocabulary).
|
|
4
|
+
*
|
|
5
|
+
* Transport: the generic Connection RPC channel `/dsh-prompt-star`
|
|
6
|
+
* (the host registers it with `ctx.connection.rpc.handle`, the browser calls
|
|
7
|
+
* `ctx.connection.rpc.call('/dsh-prompt-star', endpoint, payload)`).
|
|
8
|
+
*
|
|
9
|
+
* The host sells exactly one capability: reading a few project documentation
|
|
10
|
+
* files for the current workspace (it CAN read file contents natively; the
|
|
11
|
+
* browser client cannot). Everything else — assembling the fuller prompt from
|
|
12
|
+
* the draft + that context — stays on the client.
|
|
13
|
+
*/
|
|
14
|
+
/** Absolute logical Connection RPC channel owned by this plugin. */
|
|
15
|
+
const RPC_CHANNEL = "/dsh-prompt-star";
|
|
62
16
|
//#endregion
|
|
63
|
-
//#region
|
|
17
|
+
//#region lib/types/index.js
|
|
64
18
|
/**
|
|
65
|
-
* Host
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
19
|
+
* Host entry for dsh-prompt-star.
|
|
20
|
+
*
|
|
21
|
+
* The ⭐ button lives in the client half; this host half registers ONE generic
|
|
22
|
+
* Connection RPC channel (`/dsh-prompt-star`) that reads a few project
|
|
23
|
+
* documentation files for the current workspace. The browser client CANNOT read
|
|
24
|
+
* file contents (the stock web app exposes no content-reading remote), so the
|
|
25
|
+
* read happens here and is shipped to the browser over the Connection channel.
|
|
26
|
+
*
|
|
27
|
+
* This entry follows the standard DSH plugin export contract `apply(ctx)`.
|
|
28
|
+
*
|
|
29
|
+
* The host-side services (`ctx.connection.rpc`, `ctx.fs`) are consumed through
|
|
30
|
+
* small local structural types instead of importing the harness packages, so the
|
|
31
|
+
* plugin's `tsc` stays inside its own `rootDir` and never drags harness source
|
|
32
|
+
* files into its program.
|
|
69
33
|
*/
|
|
70
|
-
/**
|
|
71
|
-
const
|
|
72
|
-
"
|
|
34
|
+
/** Project doc files probed, in priority order. Reads are best-effort. */
|
|
35
|
+
const DOC_CANDIDATES = [
|
|
36
|
+
"README.md",
|
|
37
|
+
"README",
|
|
73
38
|
"AGENTS.md",
|
|
74
|
-
".
|
|
75
|
-
"
|
|
39
|
+
"CLAUDE.md",
|
|
40
|
+
"CONTRIBUTING.md",
|
|
41
|
+
"docs/README.md",
|
|
42
|
+
"docs/index.md",
|
|
43
|
+
".cursorrules"
|
|
76
44
|
];
|
|
77
|
-
/** Per-
|
|
78
|
-
const
|
|
79
|
-
/** Output-token cap for the generated prompt. */
|
|
80
|
-
const MAX_OUTPUT_TOKENS = 1200;
|
|
81
|
-
/** End-to-end generate deadline. */
|
|
82
|
-
const TIMEOUT_MS = 2e4;
|
|
83
|
-
/** Timeout code registered for the capability. */
|
|
84
|
-
const PROMPT_STAR_TIMEOUT_CODE = "PROMPT_STAR_TIMEOUT";
|
|
45
|
+
/** Per-doc content cap so a huge README cannot flood the input. */
|
|
46
|
+
const MAX_DOC_CHARS = 4e3;
|
|
85
47
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* one-line addition to that union (see README "Patch dsh-llm"). The cast keeps
|
|
89
|
-
* this package compiling before the patch lands.
|
|
48
|
+
* Minimal host plugin body: mount the `/dsh-prompt-star` RPC channel.
|
|
49
|
+
* @param ctx - host root context.
|
|
90
50
|
*/
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
hint: "现象 / 复现步骤 / 期望 vs 实际 / 触发条件 / 环境"
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
id: "letter",
|
|
106
|
-
title: "写信",
|
|
107
|
-
hint: "称呼 / 目的 / 语气 / 落款"
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
id: "generic",
|
|
111
|
-
title: "通用",
|
|
112
|
-
hint: "目标 / 输入 / 期望输出 / 约束"
|
|
113
|
-
}
|
|
114
|
-
];
|
|
115
|
-
/** Default workspace root used when the caller cannot supply one. */
|
|
116
|
-
function defaultRoot(ctx) {
|
|
117
|
-
return process.cwd();
|
|
118
|
-
}
|
|
119
|
-
/** Cap a path at the workspace root (defence-in-depth: refuses abs paths outside root). */
|
|
120
|
-
function keepInside(root, path) {
|
|
121
|
-
if (isAbsolute(path)) return path.startsWith(root) ? path : void 0;
|
|
122
|
-
return join(root, path);
|
|
123
|
-
}
|
|
124
|
-
/** Probe the doc files, reading the first `MAX_DOC_BYTES` bytes of each hit. */
|
|
125
|
-
async function readDocFiles(root) {
|
|
126
|
-
const sources = [];
|
|
127
|
-
for (const name of DOC_FILE_NAMES) {
|
|
128
|
-
const path = keepInside(root, name);
|
|
129
|
-
if (path === void 0) continue;
|
|
130
|
-
try {
|
|
131
|
-
const buf = await readFile(path);
|
|
132
|
-
sources.push({
|
|
133
|
-
path,
|
|
134
|
-
name,
|
|
135
|
-
read: true,
|
|
136
|
-
bytes: Math.min(buf.byteLength, MAX_DOC_BYTES)
|
|
137
|
-
});
|
|
138
|
-
} catch {
|
|
139
|
-
sources.push({
|
|
140
|
-
path,
|
|
141
|
-
name,
|
|
142
|
-
read: false,
|
|
143
|
-
bytes: 0
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return sources;
|
|
148
|
-
}
|
|
149
|
-
/** Frame the doc context into the system prompt (references, not whole files). */
|
|
150
|
-
function frameContext(sources) {
|
|
151
|
-
const hits = sources.filter((source) => source.read);
|
|
152
|
-
if (hits.length === 0) return "当前项目没有可读的说明文件(未找到 CLAUDE.md / AGENTS.md / .cursorrules / README.md)。";
|
|
153
|
-
return hits.map((source) => `--- ${source.name} (${source.bytes} 字节) ---\n<probe-only: use this file as project context>`).join("\n");
|
|
154
|
-
}
|
|
155
|
-
/** Compose the system instruction that turns a draft into a fuller prompt. */
|
|
156
|
-
function buildSystem(sources) {
|
|
157
|
-
return [
|
|
158
|
-
"你是提示词优化器。用户会给一段随手写的草稿,你把它扩写成一版更完整、更省 token、意图清晰的提示词。",
|
|
159
|
-
"阅读下面用到的项目说明文件(若有)作为上下文,不要照抄,只借用其术语、技术栈与约定。",
|
|
160
|
-
"可参考的模板骨架(选择与该草稿最贴切的一个作为形状,按需补充):",
|
|
161
|
-
SKELETONS.map((skeleton) => `- ${skeleton.title}(${skeleton.id}):${skeleton.hint}`).join("\n"),
|
|
162
|
-
"输出要求:",
|
|
163
|
-
"- 只输出优化后的提示词正文,不要解释、不要 Markdown 包裹、不要前缀。",
|
|
164
|
-
"- 保留用户草稿的原意,补全缺失的上下文与验收标准。",
|
|
165
|
-
"- 用草稿同语言输出。",
|
|
166
|
-
"",
|
|
167
|
-
frameContext(sources)
|
|
168
|
-
].join("\n");
|
|
169
|
-
}
|
|
170
|
-
/** Map the LLM finish reason to an error, mirroring session-title-llm. */
|
|
171
|
-
function finishError(finish) {
|
|
172
|
-
switch (finish.kind) {
|
|
173
|
-
case "stop": return;
|
|
174
|
-
case "error":
|
|
175
|
-
case "aborted": {
|
|
176
|
-
const error = new Error(finish.failure.message);
|
|
177
|
-
error.code = finish.failure.code;
|
|
178
|
-
return error;
|
|
179
|
-
}
|
|
180
|
-
case "max-tokens": return /* @__PURE__ */ new Error("prompt-star: output reached maxTokens");
|
|
181
|
-
case "tool-calls": return /* @__PURE__ */ new Error("prompt-star: model unexpectedly requested a tool");
|
|
182
|
-
default: return /* @__PURE__ */ new Error(`prompt-star: unsupported finish reason "${String(finish.kind)}"`);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
/** Read the plain text of one assembled LLM reply. */
|
|
186
|
-
function blocksToText(blocks) {
|
|
187
|
-
return blocks.filter((block) => block.type === "text").map((block) => block.text).join(" ");
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Generate the optimized prompt.
|
|
191
|
-
* @param ctx - Host context carrying the `llm` service.
|
|
192
|
-
* @param request - draft + optional workspace root / intent.
|
|
193
|
-
* @returns a settled result; degraded=true when the model call failed.
|
|
194
|
-
*/
|
|
195
|
-
async function generatePrompt(ctx, request) {
|
|
196
|
-
const sources = await readDocFiles(request.workspaceRoot ?? defaultRoot(ctx));
|
|
197
|
-
const system = buildSystem(sources);
|
|
198
|
-
const userText = request.intent?.trim() ? `草稿:\n${request.draft}\n\n请侧重「${request.intent}」模板。` : `草稿:\n${request.draft}`;
|
|
199
|
-
try {
|
|
51
|
+
function apply(ctx) {
|
|
52
|
+
const host = ctx;
|
|
53
|
+
host.connection.rpc.handle(RPC_CHANNEL, async (endpoint, payload) => {
|
|
54
|
+
if (endpoint !== "context") return {
|
|
55
|
+
ok: false,
|
|
56
|
+
error: {
|
|
57
|
+
code: "unknown_endpoint",
|
|
58
|
+
message: `unknown endpoint '${endpoint}'`,
|
|
59
|
+
details: {}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
200
62
|
try {
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
63
|
+
const root = (payload ?? {}).cwd?.trim() || process.cwd();
|
|
64
|
+
const docs = [];
|
|
65
|
+
const seen = /* @__PURE__ */ new Set();
|
|
66
|
+
let filesRead = 0;
|
|
67
|
+
for (const name of DOC_CANDIDATES) try {
|
|
68
|
+
const target = host.fs.resolve(name, { cwd: root });
|
|
69
|
+
const trimmed = (await host.fs.readText(target))?.trim();
|
|
70
|
+
if (trimmed && !seen.has(name)) {
|
|
71
|
+
seen.add(name);
|
|
72
|
+
docs.push({
|
|
73
|
+
name,
|
|
74
|
+
text: trimmed.slice(0, MAX_DOC_CHARS)
|
|
75
|
+
});
|
|
76
|
+
filesRead += 1;
|
|
210
77
|
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
signal: callDeadline.signal
|
|
221
|
-
});
|
|
222
|
-
callDeadline.signal.throwIfAborted();
|
|
223
|
-
const assembler = new BlockAssembler();
|
|
224
|
-
for await (const chunk of ctx.llm.stream(options)) {
|
|
225
|
-
callDeadline.signal.throwIfAborted();
|
|
226
|
-
assembler.push(chunk);
|
|
227
|
-
}
|
|
228
|
-
callDeadline.signal.throwIfAborted();
|
|
229
|
-
const terminalError = finishError(assembler.finish);
|
|
230
|
-
if (terminalError !== void 0) throw terminalError;
|
|
231
|
-
const blocks = assembler.blocks();
|
|
232
|
-
if (blocks.some((block) => block.type === "tool-call")) throw new Error("prompt-star: output must contain text only");
|
|
233
|
-
const prompt = blocksToText(blocks).trim();
|
|
234
|
-
if (prompt.length === 0) throw new Error("prompt-star: model produced no text");
|
|
78
|
+
} catch {}
|
|
79
|
+
return {
|
|
80
|
+
ok: true,
|
|
81
|
+
value: {
|
|
82
|
+
docs,
|
|
83
|
+
filesRead
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
} catch (err) {
|
|
235
87
|
return {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
88
|
+
ok: false,
|
|
89
|
+
error: {
|
|
90
|
+
code: "internal",
|
|
91
|
+
message: err instanceof Error ? err.message : String(err),
|
|
92
|
+
details: {}
|
|
93
|
+
}
|
|
241
94
|
};
|
|
242
|
-
} catch (_) {
|
|
243
|
-
_usingCtx$1.e = _;
|
|
244
|
-
} finally {
|
|
245
|
-
_usingCtx$1.d();
|
|
246
95
|
}
|
|
247
|
-
}
|
|
248
|
-
return {
|
|
249
|
-
prompt: request.draft,
|
|
250
|
-
intent: request.intent ?? "generic",
|
|
251
|
-
sources,
|
|
252
|
-
model: void 0,
|
|
253
|
-
degraded: true
|
|
254
|
-
};
|
|
255
|
-
}
|
|
96
|
+
});
|
|
256
97
|
}
|
|
257
|
-
/** Cheap intent label: prefer the supplied one, else the first skeleton hit. */
|
|
258
|
-
function inferIntent(prompt, _system) {
|
|
259
|
-
prompt.toLowerCase();
|
|
260
|
-
return SKELETONS.find((skeleton) => skeleton.id === "request" || skeleton.id === "bug" || skeleton.id === "letter")?.id ?? "generic";
|
|
261
|
-
}
|
|
262
|
-
//#endregion
|
|
263
|
-
//#region src/index.ts
|
|
264
|
-
/** Host service backing the generated `ctx.remote.promptStar` namespace. */
|
|
265
|
-
var PromptStarService = class extends TypertRemoteService {
|
|
266
|
-
static inject = ["typert"];
|
|
267
|
-
ctx;
|
|
268
|
-
/** @param ctx - Host context exposing the LLM and workspace services. */
|
|
269
|
-
constructor(ctx) {
|
|
270
|
-
super(ctx, "promptStar", { namespace: "promptStar" });
|
|
271
|
-
this.ctx = ctx;
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Turn a draft + project context into a fuller prompt.
|
|
275
|
-
* @param request - draft and optional workspace root / intent / signal.
|
|
276
|
-
* @returns generated prompt and the doc files probed for context.
|
|
277
|
-
*/
|
|
278
|
-
@Remote("generate") async generate(request) {
|
|
279
|
-
return generatePrompt(this.ctx, request);
|
|
280
|
-
}
|
|
281
|
-
};
|
|
282
98
|
//#endregion
|
|
283
|
-
export {
|
|
99
|
+
export { apply };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ⭐ button rendered beside the conversation input.
|
|
3
|
+
*
|
|
4
|
+
* On click it reads the current draft (session input snapshot), asks the host
|
|
5
|
+
* (over the `/dsh-prompt-star` Connection RPC channel) to read a few project
|
|
6
|
+
* doc files as context, assembles a fuller, more efficient prompt on the client,
|
|
7
|
+
* then writes it back with `inputActions.setDraft`. Press Ctrl/Cmd+Z to restore
|
|
8
|
+
* the original draft.
|
|
9
|
+
*
|
|
10
|
+
* The slot framework composes this component's props: the session standard seat
|
|
11
|
+
* (`useInput`, `inputActions`) plus the register-time `context` face this client
|
|
12
|
+
* plugin injects. The interfaces below are the minimal structural shapes this
|
|
13
|
+
* component needs; they match the composed slot props without importing the
|
|
14
|
+
* harness client types.
|
|
15
|
+
*/
|
|
16
|
+
import { type ReactElement } from 'react';
|
|
17
|
+
import type { ContextRpcResult } from '../types';
|
|
18
|
+
export interface StarButtonProps {
|
|
19
|
+
/** Host RPC caller that returns the project doc context. */
|
|
20
|
+
context(): Promise<ContextRpcResult>;
|
|
21
|
+
/** Session input snapshot hook (returns the current draft). */
|
|
22
|
+
useInput(): {
|
|
23
|
+
draft: string;
|
|
24
|
+
};
|
|
25
|
+
/** Session public input actions (write the whole draft). */
|
|
26
|
+
inputActions: {
|
|
27
|
+
setDraft(text: string): void;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export declare function StarButton({ context, useInput, inputActions }: StarButtonProps): ReactElement;
|
|
31
|
+
//# sourceMappingURL=StarButton.d.ts.map
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* The ⭐ button rendered beside the conversation input.
|
|
4
|
+
*
|
|
5
|
+
* On click it reads the current draft (session input snapshot), asks the host
|
|
6
|
+
* (over the `/dsh-prompt-star` Connection RPC channel) to read a few project
|
|
7
|
+
* doc files as context, assembles a fuller, more efficient prompt on the client,
|
|
8
|
+
* then writes it back with `inputActions.setDraft`. Press Ctrl/Cmd+Z to restore
|
|
9
|
+
* the original draft.
|
|
10
|
+
*
|
|
11
|
+
* The slot framework composes this component's props: the session standard seat
|
|
12
|
+
* (`useInput`, `inputActions`) plus the register-time `context` face this client
|
|
13
|
+
* plugin injects. The interfaces below are the minimal structural shapes this
|
|
14
|
+
* component needs; they match the composed slot props without importing the
|
|
15
|
+
* harness client types.
|
|
16
|
+
*/
|
|
17
|
+
import { useState } from 'react';
|
|
18
|
+
/** Common project-doc filenames are probed on the HOST; the client never
|
|
19
|
+
* enumerates them (it just asks the host for the read context). */
|
|
20
|
+
const buttonStyle = {
|
|
21
|
+
all: 'unset',
|
|
22
|
+
display: 'inline-flex',
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
justifyContent: 'center',
|
|
25
|
+
width: '30px',
|
|
26
|
+
height: '30px',
|
|
27
|
+
cursor: 'pointer',
|
|
28
|
+
borderRadius: '6px',
|
|
29
|
+
fontSize: '16px',
|
|
30
|
+
lineHeight: 1,
|
|
31
|
+
opacity: 0.9,
|
|
32
|
+
userSelect: 'none',
|
|
33
|
+
};
|
|
34
|
+
/** Build a fuller, structured prompt from the draft + any project context. */
|
|
35
|
+
function assemblePrompt(draft, context) {
|
|
36
|
+
const projectContext = context.docs.length === 0
|
|
37
|
+
? '(未读取到项目文档)'
|
|
38
|
+
: context.docs.map((doc) => `## ${doc.name}\n${doc.text}`).join('\n\n');
|
|
39
|
+
return [
|
|
40
|
+
'请把下面的【我的草稿】整理成一段完整、清晰、高效的提示词,直接输出整理后的提示词本身。',
|
|
41
|
+
'',
|
|
42
|
+
'整理要求:',
|
|
43
|
+
'1. 明确任务目标、所需上下文、约束条件与期望输出形式。',
|
|
44
|
+
'2. 若【项目文档】提供了相关规范、术语或背景,请吸收进去,使提示词更贴合项目。',
|
|
45
|
+
'3. 语气中立专业,结构清晰(可用编号、小节或列表),忠于草稿原意,不虚构。',
|
|
46
|
+
'4. 长度以覆盖草稿要点为准,不要过度扩写。',
|
|
47
|
+
'',
|
|
48
|
+
'# 项目文档',
|
|
49
|
+
projectContext,
|
|
50
|
+
'',
|
|
51
|
+
'# 我的草稿',
|
|
52
|
+
draft,
|
|
53
|
+
].join('\n');
|
|
54
|
+
}
|
|
55
|
+
export function StarButton({ context, useInput, inputActions }) {
|
|
56
|
+
const input = useInput();
|
|
57
|
+
const [busy, setBusy] = useState(false);
|
|
58
|
+
const [error, setError] = useState(undefined);
|
|
59
|
+
async function onClick() {
|
|
60
|
+
const draft = input.draft.trim();
|
|
61
|
+
if (draft.length === 0) {
|
|
62
|
+
setError('草稿为空,先写点什么再点 ⭐');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
setBusy(true);
|
|
66
|
+
setError(undefined);
|
|
67
|
+
try {
|
|
68
|
+
const res = await context();
|
|
69
|
+
if (!res.ok) {
|
|
70
|
+
setError(`读取项目文档失败: ${res.error?.message ?? '未知错误'}`);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const value = res.value;
|
|
74
|
+
const full = assemblePrompt(draft, value);
|
|
75
|
+
if (full && full !== draft) {
|
|
76
|
+
inputActions.setDraft(full);
|
|
77
|
+
setError(value.docs.length === 0
|
|
78
|
+
? '已按草稿整理(未读取到项目文档)'
|
|
79
|
+
: `已整理并读取 ${value.docs.length} 个项目文档`);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
setError('未生成新内容');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (cause) {
|
|
86
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
87
|
+
setError(`生成失败: ${message}`);
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
setBusy(false);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return (_jsx("button", { type: "button", style: buttonStyle, title: error ?? 'prompt-star: 整理成更完整的提示词', disabled: busy, onClick: onClick, children: busy ? '…' : '⭐' }));
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=StarButton.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client plugin: mounts the ⭐ button into the composer input tool row
|
|
3
|
+
* (`conversation.input.right`, a session-scoped list slot) and wires it to the
|
|
4
|
+
* host's `/dsh-prompt-star` Connection RPC channel.
|
|
5
|
+
*
|
|
6
|
+
* This client half only needs the slot registry and the `connection` service.
|
|
7
|
+
* On click the button asks the host for project doc context (the browser cannot
|
|
8
|
+
* read file contents itself), then assembles the fuller prompt on the client and
|
|
9
|
+
* writes it back with `inputActions.setDraft`.
|
|
10
|
+
*/
|
|
11
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
12
|
+
/** Cordis services this client plugin needs: the slot registry and the
|
|
13
|
+
* Connection service (both provided by the stock web-app composition). */
|
|
14
|
+
export declare const inject: string[];
|
|
15
|
+
/**
|
|
16
|
+
* Client plugin body: register the ⭐ button once the slot registry and the
|
|
17
|
+
* Connection service are up.
|
|
18
|
+
* @param ctx - client root context.
|
|
19
|
+
*/
|
|
20
|
+
export declare function apply(ctx: Context): void;
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client plugin: mounts the ⭐ button into the composer input tool row
|
|
3
|
+
* (`conversation.input.right`, a session-scoped list slot) and wires it to the
|
|
4
|
+
* host's `/dsh-prompt-star` Connection RPC channel.
|
|
5
|
+
*
|
|
6
|
+
* This client half only needs the slot registry and the `connection` service.
|
|
7
|
+
* On click the button asks the host for project doc context (the browser cannot
|
|
8
|
+
* read file contents itself), then assembles the fuller prompt on the client and
|
|
9
|
+
* writes it back with `inputActions.setDraft`.
|
|
10
|
+
*/
|
|
11
|
+
import { StarButton } from "./StarButton.js";
|
|
12
|
+
import { RPC_CHANNEL, EP_CONTEXT } from '../types';
|
|
13
|
+
/** Cordis services this client plugin needs: the slot registry and the
|
|
14
|
+
* Connection service (both provided by the stock web-app composition). */
|
|
15
|
+
export const inject = ['slots', 'connection'];
|
|
16
|
+
/**
|
|
17
|
+
* Client plugin body: register the ⭐ button once the slot registry and the
|
|
18
|
+
* Connection service are up.
|
|
19
|
+
* @param ctx - client root context.
|
|
20
|
+
*/
|
|
21
|
+
export function apply(ctx) {
|
|
22
|
+
ctx.inject(['slots', 'connection'], (scope) => {
|
|
23
|
+
const root = scope;
|
|
24
|
+
const rpc = root.connection.rpc;
|
|
25
|
+
root.slots.inject('conversation.input.right', () => {
|
|
26
|
+
root.slots.register({
|
|
27
|
+
name: 'conversation.input.right',
|
|
28
|
+
id: 'prompt-star',
|
|
29
|
+
order: 0,
|
|
30
|
+
inject: () => ({
|
|
31
|
+
context: () => rpc.call(RPC_CHANNEL, EP_CONTEXT, {}),
|
|
32
|
+
}),
|
|
33
|
+
}, StarButton);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host entry for dsh-prompt-star.
|
|
3
|
+
*
|
|
4
|
+
* The ⭐ button lives in the client half; this host half registers ONE generic
|
|
5
|
+
* Connection RPC channel (`/dsh-prompt-star`) that reads a few project
|
|
6
|
+
* documentation files for the current workspace. The browser client CANNOT read
|
|
7
|
+
* file contents (the stock web app exposes no content-reading remote), so the
|
|
8
|
+
* read happens here and is shipped to the browser over the Connection channel.
|
|
9
|
+
*
|
|
10
|
+
* This entry follows the standard DSH plugin export contract `apply(ctx)`.
|
|
11
|
+
*
|
|
12
|
+
* The host-side services (`ctx.connection.rpc`, `ctx.fs`) are consumed through
|
|
13
|
+
* small local structural types instead of importing the harness packages, so the
|
|
14
|
+
* plugin's `tsc` stays inside its own `rootDir` and never drags harness source
|
|
15
|
+
* files into its program.
|
|
16
|
+
*/
|
|
17
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
18
|
+
/**
|
|
19
|
+
* Minimal host plugin body: mount the `/dsh-prompt-star` RPC channel.
|
|
20
|
+
* @param ctx - host root context.
|
|
21
|
+
*/
|
|
22
|
+
export declare function apply(ctx: Context): void;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host entry for dsh-prompt-star.
|
|
3
|
+
*
|
|
4
|
+
* The ⭐ button lives in the client half; this host half registers ONE generic
|
|
5
|
+
* Connection RPC channel (`/dsh-prompt-star`) that reads a few project
|
|
6
|
+
* documentation files for the current workspace. The browser client CANNOT read
|
|
7
|
+
* file contents (the stock web app exposes no content-reading remote), so the
|
|
8
|
+
* read happens here and is shipped to the browser over the Connection channel.
|
|
9
|
+
*
|
|
10
|
+
* This entry follows the standard DSH plugin export contract `apply(ctx)`.
|
|
11
|
+
*
|
|
12
|
+
* The host-side services (`ctx.connection.rpc`, `ctx.fs`) are consumed through
|
|
13
|
+
* small local structural types instead of importing the harness packages, so the
|
|
14
|
+
* plugin's `tsc` stays inside its own `rootDir` and never drags harness source
|
|
15
|
+
* files into its program.
|
|
16
|
+
*/
|
|
17
|
+
import { RPC_CHANNEL, EP_CONTEXT } from './types';
|
|
18
|
+
/** Project doc files probed, in priority order. Reads are best-effort. */
|
|
19
|
+
const DOC_CANDIDATES = [
|
|
20
|
+
'README.md',
|
|
21
|
+
'README',
|
|
22
|
+
'AGENTS.md',
|
|
23
|
+
'CLAUDE.md',
|
|
24
|
+
'CONTRIBUTING.md',
|
|
25
|
+
'docs/README.md',
|
|
26
|
+
'docs/index.md',
|
|
27
|
+
'.cursorrules',
|
|
28
|
+
];
|
|
29
|
+
/** Per-doc content cap so a huge README cannot flood the input. */
|
|
30
|
+
const MAX_DOC_CHARS = 4000;
|
|
31
|
+
/**
|
|
32
|
+
* Minimal host plugin body: mount the `/dsh-prompt-star` RPC channel.
|
|
33
|
+
* @param ctx - host root context.
|
|
34
|
+
*/
|
|
35
|
+
export function apply(ctx) {
|
|
36
|
+
const host = ctx;
|
|
37
|
+
// Registrations on `ctx.connection.rpc` belong to this plugin's Cordis fiber,
|
|
38
|
+
// so they are removed automatically when the plugin is torn down.
|
|
39
|
+
host.connection.rpc.handle(RPC_CHANNEL, async (endpoint, payload) => {
|
|
40
|
+
if (endpoint !== EP_CONTEXT) {
|
|
41
|
+
return {
|
|
42
|
+
ok: false,
|
|
43
|
+
error: { code: 'unknown_endpoint', message: `unknown endpoint '${endpoint}'`, details: {} },
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const req = (payload ?? {});
|
|
48
|
+
const root = req.cwd?.trim() || process.cwd();
|
|
49
|
+
const docs = [];
|
|
50
|
+
const seen = new Set();
|
|
51
|
+
let filesRead = 0;
|
|
52
|
+
for (const name of DOC_CANDIDATES) {
|
|
53
|
+
try {
|
|
54
|
+
const target = host.fs.resolve(name, { cwd: root });
|
|
55
|
+
const text = await host.fs.readText(target);
|
|
56
|
+
const trimmed = text?.trim();
|
|
57
|
+
if (trimmed && !seen.has(name)) {
|
|
58
|
+
seen.add(name);
|
|
59
|
+
docs.push({ name, text: trimmed.slice(0, MAX_DOC_CHARS) });
|
|
60
|
+
filesRead += 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Absent / unreadable / outside the workspace: leave it out.
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { ok: true, value: { docs, filesRead } };
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
return {
|
|
71
|
+
ok: false,
|
|
72
|
+
error: {
|
|
73
|
+
code: 'internal',
|
|
74
|
+
message: err instanceof Error ? err.message : String(err),
|
|
75
|
+
details: {},
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-prompt-star — host↔client RPC protocol (shared vocabulary).
|
|
3
|
+
*
|
|
4
|
+
* Transport: the generic Connection RPC channel `/dsh-prompt-star`
|
|
5
|
+
* (the host registers it with `ctx.connection.rpc.handle`, the browser calls
|
|
6
|
+
* `ctx.connection.rpc.call('/dsh-prompt-star', endpoint, payload)`).
|
|
7
|
+
*
|
|
8
|
+
* The host sells exactly one capability: reading a few project documentation
|
|
9
|
+
* files for the current workspace (it CAN read file contents natively; the
|
|
10
|
+
* browser client cannot). Everything else — assembling the fuller prompt from
|
|
11
|
+
* the draft + that context — stays on the client.
|
|
12
|
+
*/
|
|
13
|
+
/** Absolute logical Connection RPC channel owned by this plugin. */
|
|
14
|
+
export declare const RPC_CHANNEL = "/dsh-prompt-star";
|
|
15
|
+
/** Channel-relative endpoint that reads project doc files on the host. */
|
|
16
|
+
export declare const EP_CONTEXT = "context";
|
|
17
|
+
export interface GenerateContextRequest {
|
|
18
|
+
/**
|
|
19
|
+
* Optional workspace directory to probe for doc files. When absent the host
|
|
20
|
+
* falls back to the DSH process working directory.
|
|
21
|
+
*/
|
|
22
|
+
cwd?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface DocContext {
|
|
25
|
+
/** One entry per successfully read project-doc file. */
|
|
26
|
+
docs: Array<{
|
|
27
|
+
name: string;
|
|
28
|
+
text: string;
|
|
29
|
+
}>;
|
|
30
|
+
/** Number of doc files read. */
|
|
31
|
+
filesRead: number;
|
|
32
|
+
}
|
|
33
|
+
/** The `context` endpoint's success/error envelope (Connection RPC result). */
|
|
34
|
+
export type ContextRpcResult = {
|
|
35
|
+
ok: true;
|
|
36
|
+
value: DocContext;
|
|
37
|
+
} | {
|
|
38
|
+
ok: false;
|
|
39
|
+
error: {
|
|
40
|
+
code: string;
|
|
41
|
+
message: string;
|
|
42
|
+
details: object;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-prompt-star — host↔client RPC protocol (shared vocabulary).
|
|
3
|
+
*
|
|
4
|
+
* Transport: the generic Connection RPC channel `/dsh-prompt-star`
|
|
5
|
+
* (the host registers it with `ctx.connection.rpc.handle`, the browser calls
|
|
6
|
+
* `ctx.connection.rpc.call('/dsh-prompt-star', endpoint, payload)`).
|
|
7
|
+
*
|
|
8
|
+
* The host sells exactly one capability: reading a few project documentation
|
|
9
|
+
* files for the current workspace (it CAN read file contents natively; the
|
|
10
|
+
* browser client cannot). Everything else — assembling the fuller prompt from
|
|
11
|
+
* the draft + that context — stays on the client.
|
|
12
|
+
*/
|
|
13
|
+
/** Absolute logical Connection RPC channel owned by this plugin. */
|
|
14
|
+
export const RPC_CHANNEL = '/dsh-prompt-star';
|
|
15
|
+
/** Channel-relative endpoint that reads project doc files on the host. */
|
|
16
|
+
export const EP_CONTEXT = 'context';
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-prompt-star",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "DSH plugin: a ⭐ button beside the conversation input that reads your draft + the project's doc files and
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "DSH plugin: a ⭐ button beside the conversation input that reads your draft + the project's doc files and turns them into a fuller, more efficient prompt, filling the input directly (Ctrl/Cmd+Z to undo).",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -29,13 +29,8 @@
|
|
|
29
29
|
"patch": "./cordis.patch.yml"
|
|
30
30
|
},
|
|
31
31
|
"client": {
|
|
32
|
-
"external": [
|
|
33
|
-
"@deepseek-ai/dsh-api-gateway/client"
|
|
34
|
-
],
|
|
35
32
|
"inject": [
|
|
36
|
-
"@deepseek-ai/dsh-
|
|
37
|
-
"@deepseek-ai/dsh-client-connection",
|
|
38
|
-
"@deepseek-ai/dsh-client-locale"
|
|
33
|
+
"@deepseek-ai/dsh-client-connection"
|
|
39
34
|
],
|
|
40
35
|
"platform": "web"
|
|
41
36
|
}
|
|
@@ -49,21 +44,21 @@
|
|
|
49
44
|
],
|
|
50
45
|
"peerDependencies": {
|
|
51
46
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
52
|
-
"@deepseek-ai/dsh-
|
|
53
|
-
"@deepseek-ai/dsh-
|
|
54
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.2-rc.1",
|
|
47
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.2-rc.1",
|
|
48
|
+
"@deepseek-ai/dsh-fs": "^0.1.2-rc.1",
|
|
55
49
|
"@deepseek-ai/dsh-client-ui-conversation": "^0.1.2-rc.1",
|
|
56
|
-
"@deepseek-ai/dsh-client-store": "^0.1.2-rc.1",
|
|
57
50
|
"react": "^18.3.1"
|
|
58
51
|
},
|
|
59
52
|
"devDependencies": {
|
|
60
53
|
"@types/react": "~18.3.1",
|
|
61
54
|
"react": "^18.3.1",
|
|
62
|
-
"tsdown": "^0.
|
|
55
|
+
"tsdown": "^0.22.2",
|
|
63
56
|
"typescript": "^5.5.0"
|
|
64
57
|
},
|
|
65
58
|
"scripts": {
|
|
66
59
|
"bundle": "tsdown",
|
|
60
|
+
"bundle:host": "tsdown --env.DSH_BUILD_FACE host",
|
|
61
|
+
"bundle:client": "tsdown --env.DSH_BUILD_FACE client",
|
|
67
62
|
"watch": "tsdown --watch"
|
|
68
63
|
},
|
|
69
64
|
"license": "MIT"
|