dsh-codespace-workspace 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +680 -2
- package/cordis.patch.yml +11 -0
- package/icon.svg +10 -0
- package/lib/client.js +3598 -0
- package/lib/host/codespaces.js +942 -0
- package/lib/host/gh.js +271 -0
- package/lib/host/github.js +619 -0
- package/lib/host/remote-tools.js +565 -0
- package/lib/host/routes.js +555 -0
- package/lib/host/session.js +267 -0
- package/lib/host/transport.js +463 -0
- package/lib/index.js +170 -0
- package/lib/shared.js +181 -0
- package/locale/en.json +122 -0
- package/locale/zh.json +122 -0
- package/package.json +80 -4
package/lib/shared.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared contract between the Host and Client halves of dsh-codespace-workspace.
|
|
3
|
+
*
|
|
4
|
+
* This module is imported by the Host bundle only. The Client bundle is a
|
|
5
|
+
* self-contained lazy-CJS factory and must repeat these literals; keep the two
|
|
6
|
+
* in sync — the values here are the wire contract.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-codespace-workspace/shared
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Package name; also the client module-loader id and the loader row id. */
|
|
12
|
+
export const PLUGIN_ID = 'dsh-codespace-workspace'
|
|
13
|
+
|
|
14
|
+
/** Exact host route the browser posts RPC calls to. */
|
|
15
|
+
export const RPC_ROUTE = '/api/dsh-codespace-workspace/rpc'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Directory under the DSH home that holds placeholder workspace folders.
|
|
19
|
+
* A Codespace workspace is registered in DSH's own workspace registry as a real
|
|
20
|
+
* local directory; `dsh-workspace` requires an existing, fully-qualified path.
|
|
21
|
+
* Relative to the harness home; the host resolves the absolute path.
|
|
22
|
+
*/
|
|
23
|
+
export const PLACEHOLDER_DIRNAME = 'codespaces'
|
|
24
|
+
|
|
25
|
+
/** System-prompt section registered once, at session creation. */
|
|
26
|
+
export const PROMPT_SECTION = 'codespace:workspace-rule'
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Prompt section order. After the deployment persona (0) and the plan/team
|
|
30
|
+
* policies (500/600), before the tool guidance (900+), so the rule is read as
|
|
31
|
+
* workspace context rather than as a tool instruction.
|
|
32
|
+
*/
|
|
33
|
+
export const PROMPT_ORDER = 1500
|
|
34
|
+
|
|
35
|
+
/** The single rule injected for a Codespace session. */
|
|
36
|
+
export const PROMPT_TEXT = [
|
|
37
|
+
'This session runs in a cloud Codespace workspace: file and command tools',
|
|
38
|
+
'operate inside a remote GitHub Codespace, not on the local machine.',
|
|
39
|
+
'When you finish a change, `git push` it back to the repository — the plugin',
|
|
40
|
+
'does not push for you and does not wrap Git in any way.',
|
|
41
|
+
].join(' ')
|
|
42
|
+
|
|
43
|
+
/** Every RPC action name. Frozen: the client repeats these strings. */
|
|
44
|
+
export const ACTIONS = Object.freeze({
|
|
45
|
+
STATUS: 'status',
|
|
46
|
+
GET_SETTINGS: 'get-settings',
|
|
47
|
+
SET_SETTINGS: 'set-settings',
|
|
48
|
+
LIST_REPOS: 'list-repos',
|
|
49
|
+
LIST_CODESPACES: 'list-codespaces',
|
|
50
|
+
MACHINES: 'machines',
|
|
51
|
+
PREBUILD: 'prebuild',
|
|
52
|
+
CREATE: 'create',
|
|
53
|
+
START: 'start',
|
|
54
|
+
STOP: 'stop',
|
|
55
|
+
REMOVE: 'remove',
|
|
56
|
+
PAUSE_CANCEL: 'pause-cancel',
|
|
57
|
+
PAUSE_NOW: 'pause-now',
|
|
58
|
+
WORKSPACES: 'workspaces',
|
|
59
|
+
CREATE_WORKSPACE: 'create-workspace',
|
|
60
|
+
REMOVE_WORKSPACE: 'remove-workspace',
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Codespace lifecycle state, normalized for the UI.
|
|
65
|
+
*
|
|
66
|
+
* The raw vocabulary is the `state` enum of the Codespaces REST API:
|
|
67
|
+
* `Unknown`, `Created`, `Queued`, `Provisioning`, `Available`, `Awaiting`,
|
|
68
|
+
* `Unavailable`, `Deleted`, `Moved`, `Shutdown`, `Archived`, `Starting`,
|
|
69
|
+
* `ShuttingDown`, `Failed`, `Exporting`, `Updating`, `Rebuilding`.
|
|
70
|
+
*
|
|
71
|
+
* @typedef {'running'|'stopped'|'pending'|'error'} CodespacePhase
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
/** States that mean the Codespace is usable. */
|
|
75
|
+
const RUNNING_STATES = new Set(['available'])
|
|
76
|
+
|
|
77
|
+
/** States that mean it is not running and can be started. */
|
|
78
|
+
const STOPPED_STATES = new Set(['shutdown', 'archived'])
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* States that are transitional: show a spinner and disable the control.
|
|
82
|
+
* `awaiting` is included because it is a transient hand-off state, not a
|
|
83
|
+
* settled one — the API documents it as neither available nor stopped.
|
|
84
|
+
*/
|
|
85
|
+
const PENDING_STATES = new Set([
|
|
86
|
+
'created',
|
|
87
|
+
'queued',
|
|
88
|
+
'provisioning',
|
|
89
|
+
'starting',
|
|
90
|
+
'awaiting',
|
|
91
|
+
'shuttingdown',
|
|
92
|
+
'exporting',
|
|
93
|
+
'updating',
|
|
94
|
+
'rebuilding',
|
|
95
|
+
])
|
|
96
|
+
|
|
97
|
+
/** States that are terminal failures. */
|
|
98
|
+
const ERROR_STATES = new Set(['failed', 'unavailable', 'deleted', 'moved', 'unknown'])
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Map a raw GitHub Codespaces state string onto a UI phase.
|
|
102
|
+
*
|
|
103
|
+
* Unknown and missing values are treated as `pending` rather than `error`: a
|
|
104
|
+
* state this build has never seen is far more likely to be a new transitional
|
|
105
|
+
* state than a broken Codespace, and `pending` disables the control instead of
|
|
106
|
+
* offering a start that would be rejected.
|
|
107
|
+
*
|
|
108
|
+
* @param {unknown} state - raw `state` field from the GitHub API.
|
|
109
|
+
* @returns {CodespacePhase} the normalized phase.
|
|
110
|
+
*/
|
|
111
|
+
export function codespacePhase(state) {
|
|
112
|
+
if (typeof state !== 'string') return 'pending'
|
|
113
|
+
// The enum is PascalCase (`ShuttingDown`); compare case-insensitively and
|
|
114
|
+
// tolerate a snake_case or spaced spelling from any other producer.
|
|
115
|
+
const key = state.trim().toLowerCase().replace(/[\s_-]+/g, '')
|
|
116
|
+
if (RUNNING_STATES.has(key)) return 'running'
|
|
117
|
+
if (STOPPED_STATES.has(key)) return 'stopped'
|
|
118
|
+
if (PENDING_STATES.has(key)) return 'pending'
|
|
119
|
+
if (ERROR_STATES.has(key)) return 'error'
|
|
120
|
+
return 'pending'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Whether a phase may be started. */
|
|
124
|
+
export function canStart(phase) {
|
|
125
|
+
return phase === 'stopped' || phase === 'error'
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Whether a phase may be stopped. */
|
|
129
|
+
export function canStop(phase) {
|
|
130
|
+
return phase === 'running'
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Settings namespace = the loader row id. */
|
|
134
|
+
export const SETTINGS_NS = PLUGIN_ID
|
|
135
|
+
|
|
136
|
+
/** Default settings values; also mirrored by the Host `Config` schema. */
|
|
137
|
+
export const SETTINGS_DEFAULTS = Object.freeze({
|
|
138
|
+
githubUsername: '',
|
|
139
|
+
defaultBranch: 'main',
|
|
140
|
+
autoPauseMinutes: 30,
|
|
141
|
+
sshKeyPath: '',
|
|
142
|
+
alwaysShowCloudButton: false,
|
|
143
|
+
autoInitEmptyRepo: true,
|
|
144
|
+
readmeContent: '',
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Reduce an unknown thrown value to a wire-safe `{ code, message }` pair.
|
|
149
|
+
* Never leaks a stack, a token, or a request body.
|
|
150
|
+
*
|
|
151
|
+
* @param {unknown} error - the caught value.
|
|
152
|
+
* @returns {{ code: string, message: string }} the wire error.
|
|
153
|
+
*/
|
|
154
|
+
export function wireError(error) {
|
|
155
|
+
if (error && typeof error === 'object') {
|
|
156
|
+
const code = typeof error.code === 'string' && error.code.length > 0 ? error.code : 'E_UNKNOWN'
|
|
157
|
+
const message = error instanceof Error ? error.message : String(error.message ?? error)
|
|
158
|
+
return { code, message: redact(message) }
|
|
159
|
+
}
|
|
160
|
+
return { code: 'E_UNKNOWN', message: redact(String(error)) }
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Patterns that must never reach the browser. */
|
|
164
|
+
const SECRET_PATTERNS = [
|
|
165
|
+
/\bgh[pousr]_[A-Za-z0-9]{16,}\b/g,
|
|
166
|
+
/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,
|
|
167
|
+
/\bBearer\s+[A-Za-z0-9._-]{20,}/gi,
|
|
168
|
+
/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
|
|
169
|
+
]
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Strip anything credential-shaped out of a string.
|
|
173
|
+
*
|
|
174
|
+
* @param {string} text - candidate text.
|
|
175
|
+
* @returns {string} the same text with credential-shaped runs replaced.
|
|
176
|
+
*/
|
|
177
|
+
export function redact(text) {
|
|
178
|
+
let out = text
|
|
179
|
+
for (const pattern of SECRET_PATTERNS) out = out.replace(pattern, '[redacted]')
|
|
180
|
+
return out
|
|
181
|
+
}
|
package/locale/en.json
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nav": "Codespace",
|
|
3
|
+
"page.title": "Codespace",
|
|
4
|
+
"page.subtitle": "Use a GitHub Codespace as a DSH workspace: file and command tools run inside the cloud Codespace.",
|
|
5
|
+
"status.heading": "Status",
|
|
6
|
+
"status.refresh": "Refresh",
|
|
7
|
+
"status.checking": "Checking…",
|
|
8
|
+
"status.gh": "GitHub CLI (gh)",
|
|
9
|
+
"status.gh.installed": "installed · {version}",
|
|
10
|
+
"status.gh.missing": "not installed",
|
|
11
|
+
"status.gh.missingNote": "The GitHub CLI was not found. That does not block the plugin: it connects to the Codespace through the SSH setting below instead (a host alias from ~/.ssh/config, such as codespace-mybox, is the recommended value). Installing gh enables the fuller capability set.",
|
|
12
|
+
"status.token": "GitHub token",
|
|
13
|
+
"status.token.settings": "from plugin settings",
|
|
14
|
+
"status.token.env": "from the GITHUB_TOKEN environment variable",
|
|
15
|
+
"status.token.gh": "from gh auth token",
|
|
16
|
+
"status.token.none": "not found",
|
|
17
|
+
"status.token.noneNote": "No token found: the repository list and the Codespace lifecycle actions are unavailable.",
|
|
18
|
+
"status.login": "GitHub login",
|
|
19
|
+
"status.loggedOut": "not signed in",
|
|
20
|
+
"status.configured": "Configuration",
|
|
21
|
+
"status.configured.yes": "configured",
|
|
22
|
+
"status.configured.no": "not configured",
|
|
23
|
+
"status.failed": "Could not read the status: {message}",
|
|
24
|
+
"settings.heading": "Settings",
|
|
25
|
+
"field.githubUsername": "GitHub username",
|
|
26
|
+
"field.githubUsername.hint": "Leave empty to use the account the token belongs to.",
|
|
27
|
+
"field.defaultBranch": "Default branch",
|
|
28
|
+
"field.autoPauseMinutes": "Auto-pause delay (minutes)",
|
|
29
|
+
"field.autoPauseMinutes.hint": "Counts down after a turn ends; a new message cancels it. 0 disables auto-pause. Double-click the clock on a workspace row to pause immediately.",
|
|
30
|
+
"field.sshKeyPath": "SSH key (optional)",
|
|
31
|
+
"field.sshKeyPath.hint": "Used to reach the Codespace when gh is unavailable. Put a host alias from ~/.ssh/config here (such as codespace-mybox); name the private key with IdentityFile in that Host entry — a key path alone does not say which host to reach.",
|
|
32
|
+
"field.sshKeyPath.set": "Set",
|
|
33
|
+
"field.sshKeyPath.unset": "Not set",
|
|
34
|
+
"field.sshKeyPath.write": "Enter a new value (never shown again)",
|
|
35
|
+
"field.sshKeyPath.save": "Save",
|
|
36
|
+
"field.sshKeyPath.clear": "Clear",
|
|
37
|
+
"field.alwaysShowCloudButton": "Always show the cloud workspace button",
|
|
38
|
+
"field.alwaysShowCloudButton.hint": "When off, the button appears only while the pointer is over that workspace row. When on, the row’s whole action cluster stays visible (CSS cannot reveal one child of a hidden container).",
|
|
39
|
+
"field.autoInitEmptyRepo": "Initialize empty repositories",
|
|
40
|
+
"field.autoInitEmptyRepo.hint": "Commit a README first when the repository has no commits.",
|
|
41
|
+
"field.readmeContent": "Initial README content",
|
|
42
|
+
"field.readmeContent.hint": "Leave empty to commit an empty README.md.",
|
|
43
|
+
"save": "Save",
|
|
44
|
+
"saving": "Saving…",
|
|
45
|
+
"saved": "Saved",
|
|
46
|
+
"saveFailed": "Save failed: {message}",
|
|
47
|
+
"managed.heading": "Cloud workspaces",
|
|
48
|
+
"managed.empty": "No Codespace workspace is managed by this plugin yet.",
|
|
49
|
+
"managed.loading": "Loading…",
|
|
50
|
+
"managed.new": "New cloud workspace",
|
|
51
|
+
"managed.delete": "Delete Codespace…",
|
|
52
|
+
"managed.deleteFallbackNote": "The workspace row’s “⋯” menu also offers “Delete Codespace…”. If it does not appear there, use the button here.",
|
|
53
|
+
"window.title": "New cloud workspace",
|
|
54
|
+
"step.repo": "Repository",
|
|
55
|
+
"step.codespace": "Codespace",
|
|
56
|
+
"step.machine": "Machine",
|
|
57
|
+
"step.apply": "Create",
|
|
58
|
+
"step.done": "Done",
|
|
59
|
+
"repo.search": "Search repositories",
|
|
60
|
+
"repo.loading": "Loading repositories…",
|
|
61
|
+
"repo.empty": "No repository matches.",
|
|
62
|
+
"repo.failed": "Could not load repositories: {message}",
|
|
63
|
+
"repo.private": "private",
|
|
64
|
+
"repo.isEmpty": "empty",
|
|
65
|
+
"repo.count": "{n} total",
|
|
66
|
+
"cs.heading": "This repository already has Codespaces",
|
|
67
|
+
"cs.pick": "Pick one",
|
|
68
|
+
"cs.none": "This repository has no Codespace yet; one will be created.",
|
|
69
|
+
"cs.loading": "Loading Codespaces…",
|
|
70
|
+
"cs.failed": "Could not load Codespaces: {message}",
|
|
71
|
+
"cs.state": "state: {state}",
|
|
72
|
+
"cs.createNew": "Create a new Codespace",
|
|
73
|
+
"prebuild.checking": "Checking for a prebuild…",
|
|
74
|
+
"prebuild.missing": "No prebuild configured — creating may be slow",
|
|
75
|
+
"prebuild.unknown": "Prebuild status could not be read — creating may take 1–3 minutes",
|
|
76
|
+
"prebuild.cancel": "Cancel",
|
|
77
|
+
"prebuild.proceed": "Create anyway",
|
|
78
|
+
"prebuild.ok": "This repository has a prebuild configured.",
|
|
79
|
+
"machine.heading": "Machine type",
|
|
80
|
+
"machine.loading": "Loading machine types…",
|
|
81
|
+
"machine.failed": "Could not load machine types: {message}",
|
|
82
|
+
"machine.empty": "No machine type is available for this repository.",
|
|
83
|
+
"machine.default": "smallest default",
|
|
84
|
+
"machine.cpus": "{n} CPUs",
|
|
85
|
+
"machine.memory": "{n} GB RAM",
|
|
86
|
+
"machine.storage": "{n} GB storage",
|
|
87
|
+
"machine.gpu": "GPU",
|
|
88
|
+
"seed.note": "The repository is empty: README.md is committed first, then the Codespace is created.",
|
|
89
|
+
"seed.note.off": "The repository is empty and “Initialize empty repositories” is off, so creation may fail.",
|
|
90
|
+
"apply.creating": "Creating the Codespace…",
|
|
91
|
+
"apply.creatingHint": "Creation usually takes 1–3 minutes.",
|
|
92
|
+
"apply.starting": "Starting the Codespace…",
|
|
93
|
+
"apply.registering": "Registering the DSH workspace…",
|
|
94
|
+
"apply.failed": "The operation failed: {message}",
|
|
95
|
+
"retry": "Retry",
|
|
96
|
+
"back": "Back",
|
|
97
|
+
"next": "Next",
|
|
98
|
+
"cancel": "Cancel",
|
|
99
|
+
"close": "Close",
|
|
100
|
+
"success.title": "The Codespace is ready",
|
|
101
|
+
"success.body": "The DSH workspace is registered; the session works inside the cloud Codespace.",
|
|
102
|
+
"success.open": "Open a session here",
|
|
103
|
+
"success.opening": "Opening…",
|
|
104
|
+
"success.openFailed": "That row is not in the sidebar yet. Expand the sidebar and use the “New session” button on the workspace row.",
|
|
105
|
+
"success.done": "Done",
|
|
106
|
+
"row.cloud": "Cloud Codespace workspace",
|
|
107
|
+
"row.hoverRepo": "{repo} · {name}",
|
|
108
|
+
"row.start": "Start Codespace",
|
|
109
|
+
"row.stop": "Pause Codespace",
|
|
110
|
+
"row.countdown": "Auto-pause in {n} min",
|
|
111
|
+
"row.countdownSoon": "Auto-pausing soon",
|
|
112
|
+
"row.pending": "Changing state…",
|
|
113
|
+
"row.error": "Unhealthy state: {state}",
|
|
114
|
+
"row.actionFailed": "The action failed: {message}",
|
|
115
|
+
"menu.delete": "Delete Codespace…",
|
|
116
|
+
"delete.title": "Delete Codespace",
|
|
117
|
+
"delete.body": "The cloud Codespace “{name}” is deleted permanently. Unpushed work inside it is lost and cannot be recovered. The DSH workspace record stays behind as an empty placeholder directory.",
|
|
118
|
+
"delete.confirm": "Delete permanently",
|
|
119
|
+
"delete.working": "Deleting…",
|
|
120
|
+
"delete.failed": "Delete failed: {message}",
|
|
121
|
+
"launcher.label": "New cloud workspace"
|
|
122
|
+
}
|
package/locale/zh.json
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
{
|
|
2
|
+
"nav": "Codespace",
|
|
3
|
+
"page.title": "Codespace",
|
|
4
|
+
"page.subtitle": "把 GitHub Codespace 当作 DSH 工作区:文件与命令工具在云端 Codespace 里运行。",
|
|
5
|
+
"status.heading": "状态",
|
|
6
|
+
"status.refresh": "刷新",
|
|
7
|
+
"status.checking": "检查中…",
|
|
8
|
+
"status.gh": "GitHub CLI (gh)",
|
|
9
|
+
"status.gh.installed": "已安装 · {version}",
|
|
10
|
+
"status.gh.missing": "未安装",
|
|
11
|
+
"status.gh.missingNote": "没有检测到 GitHub CLI。这不影响使用:插件会改用你在下面配置的 SSH 连接方式(推荐填 ~/.ssh/config 里的主机别名,例如 codespace-mybox)。安装 gh 后可以获得更完整的能力。",
|
|
12
|
+
"status.token": "GitHub 令牌",
|
|
13
|
+
"status.token.settings": "来自插件设置",
|
|
14
|
+
"status.token.env": "来自环境变量 GITHUB_TOKEN",
|
|
15
|
+
"status.token.gh": "来自 gh auth token",
|
|
16
|
+
"status.token.none": "未找到",
|
|
17
|
+
"status.token.noneNote": "未找到令牌:仓库列表与 Codespace 生命周期操作不可用。",
|
|
18
|
+
"status.login": "GitHub 登录",
|
|
19
|
+
"status.loggedOut": "未登录",
|
|
20
|
+
"status.configured": "配置",
|
|
21
|
+
"status.configured.yes": "已配置",
|
|
22
|
+
"status.configured.no": "未配置",
|
|
23
|
+
"status.failed": "状态读取失败:{message}",
|
|
24
|
+
"settings.heading": "设置",
|
|
25
|
+
"field.githubUsername": "GitHub 用户名",
|
|
26
|
+
"field.githubUsername.hint": "留空表示使用令牌所属的账号。",
|
|
27
|
+
"field.defaultBranch": "默认分支",
|
|
28
|
+
"field.autoPauseMinutes": "自动暂停等待时间(分钟)",
|
|
29
|
+
"field.autoPauseMinutes.hint": "一个回合结束后开始计时,期间收到新消息会取消。填 0 表示不自动暂停。双击工作区行上的时钟图标可以立即暂停。",
|
|
30
|
+
"field.sshKeyPath": "SSH 密钥(可选)",
|
|
31
|
+
"field.sshKeyPath.hint": "没有 gh 时用它连接 Codespace。填 ~/.ssh/config 里的主机别名,例如 codespace-mybox(私钥请在 Host 条目里用 IdentityFile 指定——只填密钥路径无法确定要连接哪台主机)。",
|
|
32
|
+
"field.sshKeyPath.set": "已设置",
|
|
33
|
+
"field.sshKeyPath.unset": "未设置",
|
|
34
|
+
"field.sshKeyPath.write": "输入新的值(保存后不再显示)",
|
|
35
|
+
"field.sshKeyPath.save": "保存",
|
|
36
|
+
"field.sshKeyPath.clear": "清除",
|
|
37
|
+
"field.alwaysShowCloudButton": "始终显示云端工作区按钮",
|
|
38
|
+
"field.alwaysShowCloudButton.hint": "关闭时,按钮只在鼠标悬停该工作区行时出现。开启后该行的整组操作按钮会常驻显示(CSS 无法只显示其中的一个子元素)。",
|
|
39
|
+
"field.autoInitEmptyRepo": "自动初始化空仓库",
|
|
40
|
+
"field.autoInitEmptyRepo.hint": "仓库没有任何提交时,先提交一个 README 再创建 Codespace。",
|
|
41
|
+
"field.readmeContent": "README 初始内容",
|
|
42
|
+
"field.readmeContent.hint": "留空则提交一个空的 README.md。",
|
|
43
|
+
"save": "保存",
|
|
44
|
+
"saving": "保存中…",
|
|
45
|
+
"saved": "已保存",
|
|
46
|
+
"saveFailed": "保存失败:{message}",
|
|
47
|
+
"managed.heading": "云端工作区",
|
|
48
|
+
"managed.empty": "还没有由本插件管理的 Codespace 工作区。",
|
|
49
|
+
"managed.loading": "正在读取…",
|
|
50
|
+
"managed.new": "新建云端工作区",
|
|
51
|
+
"managed.delete": "删除 Codespace…",
|
|
52
|
+
"managed.deleteFallbackNote": "侧边栏工作区行的「⋯」菜单里也有「删除 Codespace…」。如果那里没有出现,可以用这里的按钮。",
|
|
53
|
+
"window.title": "新建云端工作区",
|
|
54
|
+
"step.repo": "选择仓库",
|
|
55
|
+
"step.codespace": "选择 Codespace",
|
|
56
|
+
"step.machine": "选择机型",
|
|
57
|
+
"step.apply": "创建",
|
|
58
|
+
"step.done": "完成",
|
|
59
|
+
"repo.search": "搜索仓库",
|
|
60
|
+
"repo.loading": "正在读取仓库…",
|
|
61
|
+
"repo.empty": "没有匹配的仓库。",
|
|
62
|
+
"repo.failed": "仓库读取失败:{message}",
|
|
63
|
+
"repo.private": "私有",
|
|
64
|
+
"repo.isEmpty": "空仓库",
|
|
65
|
+
"repo.count": "共 {n} 个",
|
|
66
|
+
"cs.heading": "该仓库已有 Codespace",
|
|
67
|
+
"cs.pick": "选择一个 Codespace",
|
|
68
|
+
"cs.none": "该仓库还没有 Codespace,将新建一个。",
|
|
69
|
+
"cs.loading": "正在读取 Codespace…",
|
|
70
|
+
"cs.failed": "Codespace 读取失败:{message}",
|
|
71
|
+
"cs.state": "状态:{state}",
|
|
72
|
+
"cs.createNew": "新建一个 Codespace",
|
|
73
|
+
"prebuild.checking": "正在检查预构建…",
|
|
74
|
+
"prebuild.missing": "未配置预构建,创建可能较慢",
|
|
75
|
+
"prebuild.unknown": "无法确认预构建状态,创建可能需要 1–3 分钟",
|
|
76
|
+
"prebuild.cancel": "取消",
|
|
77
|
+
"prebuild.proceed": "直接创建",
|
|
78
|
+
"prebuild.ok": "该仓库已配置预构建。",
|
|
79
|
+
"machine.heading": "选择机型",
|
|
80
|
+
"machine.loading": "正在读取机型…",
|
|
81
|
+
"machine.failed": "机型读取失败:{message}",
|
|
82
|
+
"machine.empty": "该仓库没有可用的机型。",
|
|
83
|
+
"machine.default": "默认最小",
|
|
84
|
+
"machine.cpus": "{n} 核",
|
|
85
|
+
"machine.memory": "{n} GB 内存",
|
|
86
|
+
"machine.storage": "{n} GB 存储",
|
|
87
|
+
"machine.gpu": "GPU",
|
|
88
|
+
"seed.note": "仓库为空:将先提交 README.md,再创建 Codespace。",
|
|
89
|
+
"seed.note.off": "仓库为空,但「自动初始化空仓库」已关闭,创建可能失败。",
|
|
90
|
+
"apply.creating": "正在创建 Codespace…",
|
|
91
|
+
"apply.creatingHint": "创建通常需要 1–3 分钟。",
|
|
92
|
+
"apply.starting": "正在启动 Codespace…",
|
|
93
|
+
"apply.registering": "正在登记 DSH 工作区…",
|
|
94
|
+
"apply.failed": "操作失败:{message}",
|
|
95
|
+
"retry": "重试",
|
|
96
|
+
"back": "上一步",
|
|
97
|
+
"next": "下一步",
|
|
98
|
+
"cancel": "取消",
|
|
99
|
+
"close": "关闭",
|
|
100
|
+
"success.title": "Codespace 已就绪",
|
|
101
|
+
"success.body": "DSH 工作区已登记,会话的工作目录是云端 Codespace。",
|
|
102
|
+
"success.open": "在此打开会话",
|
|
103
|
+
"success.opening": "正在打开…",
|
|
104
|
+
"success.openFailed": "侧边栏里还没有这一行,请展开侧边栏后点击该工作区右侧的「新建会话」。",
|
|
105
|
+
"success.done": "完成",
|
|
106
|
+
"row.cloud": "云端 Codespace 工作区",
|
|
107
|
+
"row.hoverRepo": "{repo} · {name}",
|
|
108
|
+
"row.start": "启动 Codespace",
|
|
109
|
+
"row.stop": "暂停 Codespace",
|
|
110
|
+
"row.countdown": "还剩 {n} 分钟自动暂停",
|
|
111
|
+
"row.countdownSoon": "即将自动暂停",
|
|
112
|
+
"row.pending": "正在切换状态…",
|
|
113
|
+
"row.error": "状态异常:{state}",
|
|
114
|
+
"row.actionFailed": "操作失败:{message}",
|
|
115
|
+
"menu.delete": "删除 Codespace…",
|
|
116
|
+
"delete.title": "删除 Codespace",
|
|
117
|
+
"delete.body": "将永久删除云端 Codespace「{name}」。其中未推送的改动会一起丢失,且无法恢复。DSH 里保留的工作区记录只包含一个空的占位目录。",
|
|
118
|
+
"delete.confirm": "永久删除",
|
|
119
|
+
"delete.working": "正在删除…",
|
|
120
|
+
"delete.failed": "删除失败:{message}",
|
|
121
|
+
"launcher.label": "新建云端工作区"
|
|
122
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,82 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-codespace-workspace",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Use a GitHub Codespace directly as a DSH workspace: the agent reads, writes and runs commands inside the cloud Codespace.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Ckarefulon",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/Ckarefulon/dsh-codespace-workspace.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/Ckarefulon/dsh-codespace-workspace#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/Ckarefulon/dsh-codespace-workspace/issues"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public",
|
|
18
|
+
"registry": "https://registry.npmjs.org/"
|
|
19
|
+
},
|
|
20
|
+
"main": "./lib/index.js",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": "./lib/index.js",
|
|
23
|
+
"./client": "./lib/client.js",
|
|
24
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
25
|
+
"./package.json": "./package.json",
|
|
26
|
+
"./locale/en.json": "./locale/en.json",
|
|
27
|
+
"./locale/zh.json": "./locale/zh.json"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"lib",
|
|
31
|
+
"locale",
|
|
32
|
+
"cordis.patch.yml",
|
|
33
|
+
"icon.svg",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"icon": "./icon.svg",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=22.0.0"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"test": "node test/check.mjs && node test/shutdown.mjs && node test/e2e.mjs",
|
|
43
|
+
"test:node": "node test/check.mjs",
|
|
44
|
+
"test:shutdown": "node test/shutdown.mjs",
|
|
45
|
+
"test:e2e": "node test/e2e.mjs",
|
|
46
|
+
"test:live": "node test/live.mjs",
|
|
47
|
+
"test:browser": "node test/serve.mjs"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"dsh",
|
|
51
|
+
"dsh-plugin",
|
|
52
|
+
"deepseek-harness",
|
|
53
|
+
"codespace",
|
|
54
|
+
"codespaces",
|
|
55
|
+
"github",
|
|
56
|
+
"remote-workspace"
|
|
57
|
+
],
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@deepseek-ai/cordis": ">=4.0.0 <5",
|
|
60
|
+
"@deepseek-ai/schemastery": ">=3.18.0 <4"
|
|
61
|
+
},
|
|
62
|
+
"meta": {
|
|
63
|
+
"title": "Codespace 云端工作区",
|
|
64
|
+
"description": "把 GitHub Codespace 当作 DSH 工作区:Agent 在云端 Codespace 里读写文件、执行命令。"
|
|
65
|
+
},
|
|
66
|
+
"dsh": {
|
|
67
|
+
"engines": {
|
|
68
|
+
"dsh": ">=0.2.0-rc.2"
|
|
69
|
+
},
|
|
70
|
+
"bundle": {
|
|
71
|
+
"patch": "./cordis.patch.yml"
|
|
72
|
+
},
|
|
73
|
+
"client": {
|
|
74
|
+
"platform": "web",
|
|
75
|
+
"inject": [
|
|
76
|
+
"@deepseek-ai/dsh-client-connection",
|
|
77
|
+
"@deepseek-ai/dsh-client-ui-settings",
|
|
78
|
+
"@deepseek-ai/dsh-client-ui-workspace"
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|