@dungsil/dsh-plugin-ui-vcs 0.0.0-stage → 0.0.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.
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: dungsil-ui-vcs
3
+ name: '@dungsil/dsh-plugin-ui-vcs'
package/dist/client.js ADDED
@@ -0,0 +1,249 @@
1
+ window.__ModuleLoader__.load({ id: "@dungsil/dsh-plugin-ui-vcs", factory(require) { const module = { exports: {} }; const exports = module.exports;
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ let react = require("react");
4
+ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
5
+ let react_jsx_runtime = require("react/jsx-runtime");
6
+ // src/client.tsx
7
+ const name = "dungsil-ui-vcs";
8
+ const inject = [
9
+ "slots",
10
+ "locale",
11
+ "sessions",
12
+ "conversation",
13
+ "connection"
14
+ ];
15
+ const instructions = {
16
+ commit: "Commit only the work completed in this session. Do not push, create or update a PR, or switch branches.",
17
+ push: "Commit the work completed in this session if needed, then push the current default branch. Do not create or update a PR or switch branches. If branch protection prevents the push, report the blocker without bypassing it.",
18
+ pr: "Commit and push the work completed in this session if needed, then create or update a pull request. If on the default branch or detached HEAD, create a suitable feature branch rather than pushing directly to the default branch."
19
+ };
20
+ const request = `Write any required commit message, PR title, and PR body yourself based on the actual diff and session context. Follow the repository's AGENTS.md, commit conventions, PR template, and language rules; do not ask the user to draft these messages.
21
+ Inspect the working directory, current branch, Git status, staged and unstaged diffs, recent commits, remotes, and any existing PR before making changes. Include only changes belonging to this task; preserve unrelated edits and staged changes, and never commit secrets.
22
+ Run the relevant checks before committing. If this task is already committed, do not create an empty or duplicate commit. Do not force-push, rewrite published history, merge the PR, or trigger a deployment.
23
+ Only perform the selected operation. When a PR is requested, create one if none exists for this branch; otherwise read its current title and body, then update it while preserving other contributors' edits. Inspect remote state before retrying an uncertain push or PR creation to avoid duplicates.
24
+ Use the existing tools and approval flow without weakening permissions. If Git, remote access, authentication, or required tools are unavailable, report the specific blocker rather than claiming success. Report the commit, pushed branch, PR URL, and checks actually run.`;
25
+ const copy = {
26
+ en: {
27
+ pr: "Create PR",
28
+ push: "Push",
29
+ commit: "Commit only",
30
+ menu: "More Git actions",
31
+ loading: "Checking branch…",
32
+ lookupError: "Could not determine the default branch. Refocus this window to retry. Commit only is still available.",
33
+ hint: "Ask the agent to commit and push, and create or update a PR on a feature branch or worktree.",
34
+ sending: "Sending request…",
35
+ sent: "Requested. Follow the agent’s progress in the conversation.",
36
+ error: "Could not confirm the request. Check the conversation before trying again."
37
+ },
38
+ ko: {
39
+ pr: "PR 생성",
40
+ push: "푸시",
41
+ commit: "커밋만",
42
+ menu: "다른 Git 작업",
43
+ loading: "브랜치 확인 중…",
44
+ lookupError: "기본 브랜치를 확인하지 못했습니다. 창으로 돌아오면 다시 확인합니다. 커밋만 요청할 수 있습니다.",
45
+ hint: "에이전트가 커밋·푸시하고, 기능 브랜치나 worktree에서는 PR을 생성하거나 업데이트합니다.",
46
+ sending: "요청 전송 중…",
47
+ sent: "요청했습니다. 대화에서 에이전트의 진행 상황을 확인하세요.",
48
+ error: "요청 결과를 확인하지 못했습니다. 다시 시도하기 전에 대화를 확인하세요."
49
+ },
50
+ zh: {
51
+ pr: "创建 PR",
52
+ push: "推送",
53
+ commit: "仅提交",
54
+ menu: "更多 Git 操作",
55
+ loading: "正在检查分支…",
56
+ lookupError: "无法确定默认分支。重新聚焦窗口以重试。仍可选择仅提交。",
57
+ hint: "让智能体提交并推送更改,在功能分支或 worktree 中创建或更新 PR。",
58
+ sending: "正在发送请求…",
59
+ sent: "已请求。请在对话中查看智能体的进度。",
60
+ error: "无法确认请求结果。请先检查对话,再决定是否重试。"
61
+ }
62
+ };
63
+ function apply(ctx) {
64
+ const connection = ctx.get("connection");
65
+ const sessions = ctx.get("sessions");
66
+ function Action({ sessionId, useSession, useAccess, useProjection }) {
67
+ const language = (0, react.useSyncExternalStore)((listener) => ctx.locale.subscribe(listener), () => ctx.locale.getSnapshot().active);
68
+ const text = copy[language.startsWith("ko") ? "ko" : language.startsWith("zh") ? "zh" : "en"];
69
+ const canPrompt = useAccess("session.prompt");
70
+ const hidden = useSession((s) => s.blank || s.awaitingFirstTurn || s.removed || s.openState !== "open");
71
+ const unavailable = useSession((s) => s.running || s.removed || s.openState !== "open" || s.pendingSubmissions.length > 0);
72
+ const pending = (0, react.useRef)(false);
73
+ const anchor = (0, react.useRef)(null);
74
+ const cwd = useProjection("workingDirectory");
75
+ const [operation, setOperation] = (0, react.useState)();
76
+ const [lookup, setLookup] = (0, react.useState)("loading");
77
+ const [open, setOpen] = (0, react.useState)(false);
78
+ const [hasChanges, setHasChanges] = (0, react.useState)(false);
79
+ const [status, setStatus] = (0, react.useState)("idle");
80
+ const statusId = (0, react.useId)();
81
+ const disabled = !canPrompt || unavailable || status === "sending";
82
+ (0, react.useEffect)(() => {
83
+ if (!hasChanges || hidden || unavailable) return;
84
+ let controller;
85
+ const refresh = async () => {
86
+ controller?.abort();
87
+ controller = new AbortController();
88
+ const signal = controller.signal;
89
+ setLookup("loading");
90
+ setOperation(void 0);
91
+ try {
92
+ const result = await connection.rpc.call("/api", "dungsil-vcs/describe", { sessionId }, signal);
93
+ if (signal.aborted) return;
94
+ if (!result.ok || result.value !== "push" && result.value !== "pr") throw new Error("Git context unavailable");
95
+ setOperation(result.value);
96
+ setLookup("ready");
97
+ } catch {
98
+ if (!signal.aborted) setLookup("error");
99
+ }
100
+ };
101
+ refresh();
102
+ window.addEventListener("focus", refresh);
103
+ return () => {
104
+ controller?.abort();
105
+ window.removeEventListener("focus", refresh);
106
+ };
107
+ }, [
108
+ sessionId,
109
+ cwd,
110
+ hasChanges,
111
+ hidden,
112
+ unavailable
113
+ ]);
114
+ (0, react.useEffect)(() => {
115
+ if (disabled) setOpen(false);
116
+ }, [disabled]);
117
+ (0, react.useEffect)(() => {
118
+ const conversation = anchor.current?.closest("[data-conversation-session]");
119
+ if (conversation?.getAttribute("data-conversation-session") !== sessionId) return;
120
+ const observer = new MutationObserver(() => {
121
+ if (!conversation.querySelector("[data-changed-files]")) return;
122
+ setHasChanges(true);
123
+ observer.disconnect();
124
+ });
125
+ observer.observe(conversation, {
126
+ childList: true,
127
+ subtree: true
128
+ });
129
+ if (conversation.querySelector("[data-changed-files]")) {
130
+ setHasChanges(true);
131
+ observer.disconnect();
132
+ }
133
+ return () => observer.disconnect();
134
+ }, [sessionId]);
135
+ const send = async (selected) => {
136
+ if (disabled || pending.current) return;
137
+ pending.current = true;
138
+ setOpen(false);
139
+ setStatus("sending");
140
+ try {
141
+ if (selected !== "commit") {
142
+ const result = await connection.rpc.call("/api", "dungsil-vcs/describe", { sessionId });
143
+ if (!result.ok || result.value !== selected) {
144
+ setOperation(result.ok && (result.value === "push" || result.value === "pr") ? result.value : void 0);
145
+ setLookup(result.ok ? "ready" : "error");
146
+ setStatus("idle");
147
+ return;
148
+ }
149
+ }
150
+ const conversation = sessions.scope(sessionId)?.get("conversation");
151
+ if (!conversation) throw new Error("Session conversation unavailable");
152
+ await conversation.send(`${instructions[selected]}\n${request}`);
153
+ setStatus("sent");
154
+ } catch {
155
+ setStatus("error");
156
+ } finally {
157
+ pending.current = false;
158
+ }
159
+ };
160
+ if (hidden || !hasChanges) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
161
+ ref: anchor,
162
+ hidden: true
163
+ });
164
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
165
+ className: "dsh-vcs",
166
+ children: [
167
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
168
+ className: "dsh-vcs-actions",
169
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_deepseek_ai_dsh_client_ui_primitives.Pill, {
170
+ className: "dsh-vcs-trigger",
171
+ disabled: disabled || !operation || lookup !== "ready",
172
+ title: text.hint,
173
+ "aria-describedby": statusId,
174
+ "aria-busy": status === "sending",
175
+ onClick: () => operation && void send(operation),
176
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconBranchOutlineRegular, { "aria-hidden": "true" }), status === "sending" ? text.sending : operation === "push" ? text.push : text.pr]
177
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
178
+ open,
179
+ side: "top",
180
+ portal: true,
181
+ compact: true,
182
+ items: [{
183
+ id: "commit",
184
+ label: text.commit
185
+ }],
186
+ onClose: () => setOpen(false),
187
+ onSelect: () => void send("commit"),
188
+ anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Pill, {
189
+ className: "dsh-vcs-trigger dsh-vcs-menu",
190
+ disabled,
191
+ "aria-label": text.menu,
192
+ "aria-haspopup": "menu",
193
+ "aria-expanded": open,
194
+ onClick: () => setOpen((value) => !value),
195
+ onKeyDown: (event) => {
196
+ if (!open && (event.key === "ArrowDown" || event.key === "ArrowUp")) {
197
+ event.preventDefault();
198
+ setOpen(true);
199
+ }
200
+ },
201
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { "aria-hidden": "true" })
202
+ })
203
+ })]
204
+ }),
205
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
206
+ id: statusId,
207
+ role: status === "error" ? "alert" : "status",
208
+ className: "dsh-vcs-status",
209
+ children: status === "error" ? text.error : status === "sent" ? text.sent : ""
210
+ }),
211
+ lookup !== "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
212
+ className: "dsh-vcs-notice",
213
+ role: "status",
214
+ children: lookup === "loading" ? text.loading : text.lookupError
215
+ })
216
+ ]
217
+ });
218
+ }
219
+ ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
220
+ name: "conversation.input.dock",
221
+ id: name,
222
+ order: 100
223
+ }, (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Action, { ...props }, props.sessionId)));
224
+ ctx.effect(() => {
225
+ const style = document.createElement("style");
226
+ style.textContent = `
227
+ .dsh-vcs { box-sizing: border-box; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; width: calc(100% - 2 * var(--dsh-composer-side-clearance)); max-width: var(--dsh-composer-card-max-width); margin: 0 auto; padding-bottom: 8px; }
228
+ .dsh-vcs-actions { display: inline-flex; align-items: center; }
229
+ .dsh-vcs-actions > .dsh-vcs-trigger { border-radius: 14px 0 0 14px; }
230
+ .dsh-vcs-actions .dsh-vcs-menu { border-radius: 0 14px 14px 0; border-left: 0; padding: 0 7px; }
231
+ .dsh-vcs-notice { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-secondary); }
232
+ .dsh-vcs-trigger { height: 28px; max-width: 100%; padding: 0 10px; border: 1px solid var(--dsw-alias-border-l2); font: inherit; font-size: 12px; line-height: 18px; }
233
+ .dsh-vcs-trigger svg { flex: none; width: 14px; height: 14px; }
234
+ .dsh-vcs-trigger:disabled { background: var(--dsw-alias-bg-layer-2); color: var(--dsw-alias-label-dimmed); cursor: default; }
235
+ .dsh-vcs-trigger:focus-visible { outline: 2px solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary)); outline-offset: 0; }
236
+ .dsh-vcs-status { flex-basis: 100%; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-secondary); }
237
+ .dsh-vcs-status:empty { display: none; }
238
+ .dsh-vcs-status[role=status] { position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
239
+ .dsh-vcs-status[role=alert] { color: var(--dsw-alias-state-error-primary); }
240
+ `;
241
+ document.head.append(style);
242
+ return () => style.remove();
243
+ }, "ui-vcs: composer styles");
244
+ }
245
+ exports.apply = apply;
246
+ exports.inject = inject;
247
+ exports.name = name;
248
+
249
+ return module.exports; } });
package/dist/index.js ADDED
@@ -0,0 +1,130 @@
1
+ import { clientRequestSchema } from "@deepseek-ai/dsh-client-connection";
2
+ import { SessionId } from "@deepseek-ai/dsh-session";
3
+ // src/index.ts
4
+ const name = "dungsil-ui-vcs";
5
+ const inject = [
6
+ "connection",
7
+ "sessionController",
8
+ "subprocess",
9
+ "sandbox",
10
+ "sandboxPolicy",
11
+ "workingDirectory"
12
+ ];
13
+ function apply(ctx) {
14
+ ctx.effect(() => ctx.connection.fetch.register({
15
+ path: "/api/dungsil-vcs/describe",
16
+ methods: ["POST"],
17
+ requestBody: "buffered",
18
+ async fetch(request) {
19
+ const failure = {
20
+ ok: false,
21
+ error: {
22
+ code: "git_unavailable",
23
+ message: "Git context unavailable",
24
+ details: {}
25
+ }
26
+ };
27
+ let result = failure;
28
+ let rpcId = "";
29
+ try {
30
+ const body = clientRequestSchema.parse(await request.json());
31
+ rpcId = body.rpcId;
32
+ if (body.method !== "dungsil-vcs/describe") throw new Error("Invalid method");
33
+ const sessionId = body.payload?.sessionId;
34
+ if (typeof sessionId !== "string" || !sessionId) throw new Error("Invalid session");
35
+ const resolved = await ctx.sessionController.resolveAgent(SessionId(sessionId));
36
+ if ("error" in resolved) throw new Error("Session unavailable");
37
+ const { agent } = resolved;
38
+ const signal = AbortSignal.any([request.signal, AbortSignal.timeout(1e4)]);
39
+ const cwd = await ctx.workingDirectory.ensure(agent, signal);
40
+ const git = async (args) => {
41
+ const argv = [
42
+ await ctx.subprocess.resolveExecutable("git", void 0, signal),
43
+ "-c",
44
+ "core.fsmonitor=false",
45
+ "-c",
46
+ "core.hooksPath=/dev/null",
47
+ ...args
48
+ ];
49
+ const policy = ctx.sandboxPolicy.resolve({ session: agent.session });
50
+ const command = policy.mode === "danger-full-access" ? argv : (await ctx.sandbox.confine(argv, {
51
+ ...policy,
52
+ mode: policy.mode
53
+ }, signal)).argv;
54
+ const child = ctx.subprocess.spawn({
55
+ argv: command,
56
+ cwd,
57
+ signal,
58
+ graceMs: 1e3,
59
+ env: {
60
+ ...Object.fromEntries(Object.keys(process.env).filter((key) => key.startsWith("GIT_")).map((key) => [key, void 0])),
61
+ GIT_TERMINAL_PROMPT: "0",
62
+ GIT_OPTIONAL_LOCKS: "0",
63
+ GIT_NO_LAZY_FETCH: "1"
64
+ },
65
+ stdio: {
66
+ stdin: "ignore",
67
+ stdout: { maxBytes: 65536 },
68
+ stderr: { maxBytes: 4096 }
69
+ }
70
+ });
71
+ try {
72
+ const outcome = await child.done;
73
+ signal.throwIfAborted();
74
+ const output = child.collected.stdout.readFrom(0);
75
+ if (outcome.exitCode !== 0 || output.lossy) throw new Error("Git read failed");
76
+ return output.text.replace(/\r?\n$/, "");
77
+ } finally {
78
+ child.terminate();
79
+ await child.waitForExit();
80
+ }
81
+ };
82
+ if (await git([
83
+ "rev-parse",
84
+ "--path-format=absolute",
85
+ "--git-dir"
86
+ ]) !== await git([
87
+ "rev-parse",
88
+ "--path-format=absolute",
89
+ "--git-common-dir"
90
+ ])) result = {
91
+ ok: true,
92
+ value: "pr"
93
+ };
94
+ else {
95
+ const branch = await git([
96
+ "symbolic-ref",
97
+ "--quiet",
98
+ "--short",
99
+ "HEAD"
100
+ ]);
101
+ const upstream = await git([
102
+ "for-each-ref",
103
+ "--format=%(upstream:remotename)",
104
+ `refs/heads/${branch}`
105
+ ]);
106
+ const remotes = (await git(["remote"])).split("\n").filter(Boolean);
107
+ const remote = upstream && upstream !== "." ? upstream : remotes.includes("origin") ? "origin" : remotes.length === 1 ? remotes[0] : void 0;
108
+ if (!remote) throw new Error("Default remote unknown");
109
+ result = {
110
+ ok: true,
111
+ value: await git([
112
+ "symbolic-ref",
113
+ "--quiet",
114
+ `refs/remotes/${remote}/HEAD`
115
+ ]) === `refs/remotes/${remote}/${branch}` ? "push" : "pr"
116
+ };
117
+ }
118
+ if (ctx.workingDirectory.get(agent.session) !== cwd) throw new Error("Working directory changed");
119
+ } catch {
120
+ result = failure;
121
+ }
122
+ return Response.json({
123
+ type: "server-response",
124
+ rpcId,
125
+ result
126
+ }, { headers: { "Cache-Control": "no-store" } });
127
+ }
128
+ }), "ui-vcs: owner-only Git context");
129
+ }
130
+ export { apply, inject, name };
package/locale/en.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Version Control",
4
+ "description": "Git actions above the composer: push on the default branch, create or update a PR on other branches or worktrees, or commit only."
5
+ }
6
+ }
package/locale/ko.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "버전 관리",
4
+ "description": "입력창 위에서 Git 작업을 요청합니다. 기본 브랜치에서는 푸시하고 다른 브랜치나 worktree에서는 PR을 생성·업데이트하며, 커밋만 선택할 수도 있습니다."
5
+ }
6
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "版本控制",
4
+ "description": "在输入框上方请求 Git 操作:默认分支推送,其他分支或 worktree 创建或更新 PR,也可选择仅提交。"
5
+ }
6
+ }
package/package.json CHANGED
@@ -1,6 +1,103 @@
1
1
  {
2
2
  "name": "@dungsil/dsh-plugin-ui-vcs",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.0.0",
4
+ "description": "Version control actions for the session agent, with Git commit, push, and pull request support.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/dungsil/dsh-plugins.git",
9
+ "directory": "packages/ui-vcs"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "locale",
14
+ "cordis.patch.yml"
15
+ ],
16
+ "type": "module",
17
+ "exports": {
18
+ ".": "./dist/index.js",
19
+ "./client": "./dist/client.js",
20
+ "./package.json": "./package.json",
21
+ "./locale/*.json": "./locale/*.json"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "devDependencies": {
27
+ "@deepseek-ai/cordis": "4.0.5",
28
+ "@deepseek-ai/dsh-agent-loop-testkit": "0.2.1-rc.5",
29
+ "@deepseek-ai/dsh-api-session-controller": "0.2.1-rc.5",
30
+ "@deepseek-ai/dsh-client-connection": "0.2.1-rc.5",
31
+ "@deepseek-ai/dsh-client-locale": "0.2.1-rc.5",
32
+ "@deepseek-ai/dsh-client-store": "0.2.1-rc.5",
33
+ "@deepseek-ai/dsh-client-ui-conversation": "0.2.1-rc.5",
34
+ "@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.5",
35
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.5",
36
+ "@deepseek-ai/dsh-client-ui-session": "0.2.1-rc.5",
37
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.5",
38
+ "@deepseek-ai/dsh-credentials-local": "0.2.1-rc.5",
39
+ "@deepseek-ai/dsh-llm": "0.2.1-rc.5",
40
+ "@deepseek-ai/dsh-sandbox": "0.2.1-rc.5",
41
+ "@deepseek-ai/dsh-sandbox-local": "0.2.1-rc.5",
42
+ "@deepseek-ai/dsh-sandbox-policy": "0.2.1-rc.5",
43
+ "@deepseek-ai/dsh-session": "0.2.1-rc.5",
44
+ "@deepseek-ai/dsh-subprocess": "0.2.1-rc.5",
45
+ "@deepseek-ai/dsh-subprocess-local": "0.2.1-rc.5",
46
+ "@deepseek-ai/dsh-working-directory": "0.2.1-rc.5",
47
+ "@dungsil/dsh-tsconfig": "0.0.0",
48
+ "@types/react": "18.3.31",
49
+ "react": "18.3.1",
50
+ "tsdown": "0.23.4"
51
+ },
52
+ "peerDependencies": {
53
+ "@deepseek-ai/dsh-client-connection": "^0.2.1-rc.5",
54
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.2.1-rc.5",
55
+ "@deepseek-ai/dsh-session": "^0.2.1-rc.5"
56
+ },
57
+ "engines": {
58
+ "dsh": "^0.2.1-rc.5",
59
+ "node": ">=24.9.0"
60
+ },
61
+ "dsh": {
62
+ "bundle": {
63
+ "patch": "./cordis.patch.yml"
64
+ },
65
+ "client": {
66
+ "platform": "web",
67
+ "immediately": true,
68
+ "inject": [
69
+ "@deepseek-ai/dsh-client-connection",
70
+ "@deepseek-ai/dsh-client-locale",
71
+ "@deepseek-ai/dsh-client-ui-conversation",
72
+ "@deepseek-ai/dsh-client-ui-session"
73
+ ]
74
+ }
75
+ },
76
+ "market": {
77
+ "order": 11,
78
+ "title": {
79
+ "en": "Version Control",
80
+ "ko": "버전 관리",
81
+ "zh": "版本控制"
82
+ },
83
+ "description": {
84
+ "en": "Git actions above the composer: push on the default branch, create or update a PR on other branches or worktrees, or commit only.",
85
+ "ko": "입력창 위에서 Git 작업을 요청합니다. 기본 브랜치에서는 푸시하고 다른 브랜치나 worktree에서는 PR을 생성·업데이트하며, 커밋만 선택할 수도 있습니다.",
86
+ "zh": "在输入框上方请求 Git 操作:默认分支推送,其他分支或 worktree 创建或更新 PR,也可选择仅提交。"
87
+ },
88
+ "category": "ui",
89
+ "labels": [],
90
+ "keywords": [
91
+ "git",
92
+ "commit",
93
+ "push",
94
+ "pull-request",
95
+ "composer"
96
+ ]
97
+ },
98
+ "scripts": {
99
+ "build": "tsdown",
100
+ "typecheck": "tsc --noEmit",
101
+ "test": "node --test test/*.test.mjs"
102
+ }
6
103
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.