dsh-github-flow 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/README.md +130 -0
- package/cordis.patch.yml +7 -0
- package/icon.svg +17 -0
- package/lib/api/routes.d.ts +3 -0
- package/lib/api/routes.js +230 -0
- package/lib/client/icons.d.ts +13 -0
- package/lib/client/icons.js +41 -0
- package/lib/client/index.d.ts +3 -0
- package/lib/client/index.js +36 -0
- package/lib/client/panel.d.ts +1 -0
- package/lib/client/panel.js +75 -0
- package/lib/client/style.d.ts +1 -0
- package/lib/client/style.js +190 -0
- package/lib/client.d.ts +11 -0
- package/lib/client.js +615 -0
- package/lib/commands/gh.d.ts +2 -0
- package/lib/commands/gh.js +63 -0
- package/lib/executor.d.ts +22 -0
- package/lib/executor.js +207 -0
- package/lib/index.d.ts +17 -0
- package/lib/index.js +57 -0
- package/lib/service.d.ts +28 -0
- package/lib/service.js +34 -0
- package/lib/tools/api.d.ts +2 -0
- package/lib/tools/api.js +55 -0
- package/lib/tools/define.d.ts +6 -0
- package/lib/tools/define.js +15 -0
- package/lib/tools/issue.d.ts +2 -0
- package/lib/tools/issue.js +109 -0
- package/lib/tools/pr.d.ts +2 -0
- package/lib/tools/pr.js +130 -0
- package/lib/tools/repo.d.ts +2 -0
- package/lib/tools/repo.js +68 -0
- package/lib/tools/run.d.ts +2 -0
- package/lib/tools/run.js +87 -0
- package/lib/types.d.ts +167 -0
- package/lib/types.js +4 -0
- package/package.json +56 -0
package/lib/tools/pr.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { defineSafeTool } from './define.js';
|
|
2
|
+
export function createPrTool(executor) {
|
|
3
|
+
return defineSafeTool({
|
|
4
|
+
name: 'github_pr',
|
|
5
|
+
description: '管理与审查 GitHub Pull Request (PR)。支持查看列表、详情、差异比对、CI 检查状态、代码审查与合并操作。默认针对当前工作区关联的仓库。',
|
|
6
|
+
parameters: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
action: {
|
|
10
|
+
type: 'string',
|
|
11
|
+
enum: ['list', 'view', 'create', 'diff', 'checks', 'review', 'merge'],
|
|
12
|
+
description: 'PR 操作类型。',
|
|
13
|
+
},
|
|
14
|
+
pr_number: {
|
|
15
|
+
type: 'number',
|
|
16
|
+
description: 'PR 编号(view, diff, checks, review, merge 时使用;若在 PR 对应分支可不填,自动识别当前分支 PR)。',
|
|
17
|
+
},
|
|
18
|
+
repo: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: '目标仓库 [owner/repo],留空则自动识别当前本地 Git 仓库。',
|
|
21
|
+
},
|
|
22
|
+
title: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: '创建 PR 时的标题。',
|
|
25
|
+
},
|
|
26
|
+
body: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
description: '创建 PR 或提交 Review 时的内容描述。',
|
|
29
|
+
},
|
|
30
|
+
base: {
|
|
31
|
+
type: 'string',
|
|
32
|
+
description: '目标基准分支(默认主分支,如 main)。',
|
|
33
|
+
},
|
|
34
|
+
draft: {
|
|
35
|
+
type: 'boolean',
|
|
36
|
+
description: '是否创建为草稿 PR。',
|
|
37
|
+
},
|
|
38
|
+
review_decision: {
|
|
39
|
+
type: 'string',
|
|
40
|
+
enum: ['APPROVE', 'REQUEST_CHANGES', 'COMMENT'],
|
|
41
|
+
description: '代码审查意见判定(review 操作时使用)。',
|
|
42
|
+
},
|
|
43
|
+
merge_method: {
|
|
44
|
+
type: 'string',
|
|
45
|
+
enum: ['merge', 'squash', 'rebase'],
|
|
46
|
+
description: '合并策略(merge 操作时使用,默认 squash)。',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
required: ['action'],
|
|
50
|
+
},
|
|
51
|
+
output: {
|
|
52
|
+
schema: { type: 'object' },
|
|
53
|
+
render(args, value) {
|
|
54
|
+
return [{ type: 'text', text: typeof value === 'string' ? value : JSON.stringify(value, null, 2) }];
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
async execute(args, execContext) {
|
|
58
|
+
const cwd = execContext?.cwd || process.cwd();
|
|
59
|
+
const repoArgs = args.repo ? ['-R', args.repo] : [];
|
|
60
|
+
switch (args.action) {
|
|
61
|
+
case 'list': {
|
|
62
|
+
const res = await executor.run(['pr', 'list', ...repoArgs, '--json', 'number,title,author,headRefName,isDraft,state,updatedAt', '-L', '20'], { cwd });
|
|
63
|
+
if (!res.ok)
|
|
64
|
+
throw new Error(res.error);
|
|
65
|
+
return res.data || res.rawOutput;
|
|
66
|
+
}
|
|
67
|
+
case 'view': {
|
|
68
|
+
const target = args.pr_number ? [String(args.pr_number)] : [];
|
|
69
|
+
const res = await executor.run(['pr', 'view', ...target, ...repoArgs, '--json', 'number,title,body,state,author,labels,assignees,reviewDecision,mergeable,statusCheckRollup,url'], { cwd });
|
|
70
|
+
if (!res.ok)
|
|
71
|
+
throw new Error(res.error);
|
|
72
|
+
return res.data || res.rawOutput;
|
|
73
|
+
}
|
|
74
|
+
case 'checks': {
|
|
75
|
+
const target = args.pr_number ? [String(args.pr_number)] : [];
|
|
76
|
+
const res = await executor.run(['pr', 'checks', ...target, ...repoArgs, '--json', 'name,state,conclusion,detailsUrl'], { cwd });
|
|
77
|
+
if (!res.ok)
|
|
78
|
+
throw new Error(res.error);
|
|
79
|
+
return res.data || res.rawOutput;
|
|
80
|
+
}
|
|
81
|
+
case 'diff': {
|
|
82
|
+
const target = args.pr_number ? [String(args.pr_number)] : [];
|
|
83
|
+
const res = await executor.run(['pr', 'diff', ...target, ...repoArgs], { cwd });
|
|
84
|
+
if (!res.ok)
|
|
85
|
+
throw new Error(res.error);
|
|
86
|
+
return res.rawOutput || '无差异内容';
|
|
87
|
+
}
|
|
88
|
+
case 'create': {
|
|
89
|
+
const createCmd = ['pr', 'create', ...repoArgs, '--title', args.title || '', '--body', args.body || ''];
|
|
90
|
+
if (args.base)
|
|
91
|
+
createCmd.push('--base', args.base);
|
|
92
|
+
if (args.draft)
|
|
93
|
+
createCmd.push('--draft');
|
|
94
|
+
const res = await executor.run(createCmd, { cwd });
|
|
95
|
+
if (!res.ok)
|
|
96
|
+
throw new Error(res.error);
|
|
97
|
+
return { message: 'PR 创建成功', url: res.rawOutput };
|
|
98
|
+
}
|
|
99
|
+
case 'review': {
|
|
100
|
+
if (!args.pr_number)
|
|
101
|
+
throw new Error('review 操作必须提供 pr_number');
|
|
102
|
+
const reviewCmd = ['pr', 'review', String(args.pr_number), ...repoArgs];
|
|
103
|
+
if (args.review_decision === 'APPROVE')
|
|
104
|
+
reviewCmd.push('--approve');
|
|
105
|
+
else if (args.review_decision === 'REQUEST_CHANGES')
|
|
106
|
+
reviewCmd.push('--request-changes');
|
|
107
|
+
else
|
|
108
|
+
reviewCmd.push('--comment');
|
|
109
|
+
if (args.body)
|
|
110
|
+
reviewCmd.push('--body', args.body);
|
|
111
|
+
const res = await executor.run(reviewCmd, { cwd });
|
|
112
|
+
if (!res.ok)
|
|
113
|
+
throw new Error(res.error);
|
|
114
|
+
return { message: 'Review 提交成功', detail: res.rawOutput };
|
|
115
|
+
}
|
|
116
|
+
case 'merge': {
|
|
117
|
+
if (!args.pr_number)
|
|
118
|
+
throw new Error('merge 操作必须提供 pr_number');
|
|
119
|
+
const method = args.merge_method === 'merge' ? '--merge' : (args.merge_method === 'rebase' ? '--rebase' : '--squash');
|
|
120
|
+
const res = await executor.run(['pr', 'merge', String(args.pr_number), ...repoArgs, method, '--delete-branch'], { cwd });
|
|
121
|
+
if (!res.ok)
|
|
122
|
+
throw new Error(res.error);
|
|
123
|
+
return { message: 'PR 合并完成并已清理分支', output: res.rawOutput };
|
|
124
|
+
}
|
|
125
|
+
default:
|
|
126
|
+
throw new Error(`未知的 PR 操作: ${args.action}`);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { defineSafeTool } from './define.js';
|
|
2
|
+
export function createRepoTool(executor) {
|
|
3
|
+
return defineSafeTool({
|
|
4
|
+
name: 'github_repo',
|
|
5
|
+
description: '查看 GitHub 仓库元数据与跨仓库检索代码、Issue。默认查询当前工作区关联的仓库。',
|
|
6
|
+
parameters: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
action: {
|
|
10
|
+
type: 'string',
|
|
11
|
+
enum: ['view', 'search_code', 'search_repos'],
|
|
12
|
+
description: '仓库操作类型。',
|
|
13
|
+
},
|
|
14
|
+
repo: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: '目标仓库 [owner/repo],留空则识别当前仓库。',
|
|
17
|
+
},
|
|
18
|
+
query: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: '检索关键词(search_code 或 search_repos 时使用)。',
|
|
21
|
+
},
|
|
22
|
+
limit: {
|
|
23
|
+
type: 'number',
|
|
24
|
+
description: '返回条数,默认 10。',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
required: ['action'],
|
|
28
|
+
},
|
|
29
|
+
output: {
|
|
30
|
+
schema: { type: 'object' },
|
|
31
|
+
render(args, value) {
|
|
32
|
+
return [{ type: 'text', text: typeof value === 'string' ? value : JSON.stringify(value, null, 2) }];
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
async execute(args, execContext) {
|
|
36
|
+
const cwd = execContext?.cwd || process.cwd();
|
|
37
|
+
const limitStr = String(args.limit || 10);
|
|
38
|
+
switch (args.action) {
|
|
39
|
+
case 'view': {
|
|
40
|
+
const repoArgs = args.repo ? [args.repo] : [];
|
|
41
|
+
const res = await executor.run(['repo', 'view', ...repoArgs, '--json', 'nameWithOwner,description,defaultBranchRef,isPrivate,stargazerCount,forkCount,url'], { cwd });
|
|
42
|
+
if (!res.ok)
|
|
43
|
+
throw new Error(res.error);
|
|
44
|
+
return res.data || res.rawOutput;
|
|
45
|
+
}
|
|
46
|
+
case 'search_code': {
|
|
47
|
+
if (!args.query)
|
|
48
|
+
throw new Error('search_code 必须提供 query');
|
|
49
|
+
const repoArgs = args.repo ? ['--repo', args.repo] : [];
|
|
50
|
+
const res = await executor.run(['search', 'code', args.query, ...repoArgs, '--json', 'path,repository,textMatches', '-L', limitStr], { cwd });
|
|
51
|
+
if (!res.ok)
|
|
52
|
+
throw new Error(res.error);
|
|
53
|
+
return res.data || res.rawOutput;
|
|
54
|
+
}
|
|
55
|
+
case 'search_repos': {
|
|
56
|
+
if (!args.query)
|
|
57
|
+
throw new Error('search_repos 必须提供 query');
|
|
58
|
+
const res = await executor.run(['search', 'repos', args.query, '--json', 'fullName,description,stargazersCount,updatedAt', '-L', limitStr], { cwd });
|
|
59
|
+
if (!res.ok)
|
|
60
|
+
throw new Error(res.error);
|
|
61
|
+
return res.data || res.rawOutput;
|
|
62
|
+
}
|
|
63
|
+
default:
|
|
64
|
+
throw new Error(`未知的 Repo 操作: ${args.action}`);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
package/lib/tools/run.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { defineSafeTool } from './define.js';
|
|
2
|
+
export function createRunTool(executor) {
|
|
3
|
+
return defineSafeTool({
|
|
4
|
+
name: 'github_run',
|
|
5
|
+
description: '排查和诊断 GitHub Actions 工作流构建状态。特别优化了获取失败步骤日志能力(log_failed),专供 Agent 快速定位 CI 报错。',
|
|
6
|
+
parameters: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
action: {
|
|
10
|
+
type: 'string',
|
|
11
|
+
enum: ['list', 'view', 'log_failed', 'rerun', 'cancel'],
|
|
12
|
+
description: 'Actions 操作类型。',
|
|
13
|
+
},
|
|
14
|
+
run_id: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'Workflow 运行 ID(view, log_failed, rerun, cancel 时使用)。',
|
|
17
|
+
},
|
|
18
|
+
repo: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: '目标仓库 [owner/repo],留空则识别当前仓库。',
|
|
21
|
+
},
|
|
22
|
+
limit: {
|
|
23
|
+
type: 'number',
|
|
24
|
+
description: '列出 runs 的数量,默认 10。',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
required: ['action'],
|
|
28
|
+
},
|
|
29
|
+
output: {
|
|
30
|
+
schema: { type: 'object' },
|
|
31
|
+
render(args, value) {
|
|
32
|
+
return [{ type: 'text', text: typeof value === 'string' ? value : JSON.stringify(value, null, 2) }];
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
async execute(args, execContext) {
|
|
36
|
+
const cwd = execContext?.cwd || process.cwd();
|
|
37
|
+
const repoArgs = args.repo ? ['-R', args.repo] : [];
|
|
38
|
+
switch (args.action) {
|
|
39
|
+
case 'list': {
|
|
40
|
+
const res = await executor.run(['run', 'list', ...repoArgs, '--json', 'databaseId,name,status,conclusion,event,headBranch,createdAt', '-L', String(args.limit || 10)], { cwd });
|
|
41
|
+
if (!res.ok)
|
|
42
|
+
throw new Error(res.error);
|
|
43
|
+
return res.data || res.rawOutput;
|
|
44
|
+
}
|
|
45
|
+
case 'view': {
|
|
46
|
+
if (!args.run_id)
|
|
47
|
+
throw new Error('view 操作必须提供 run_id');
|
|
48
|
+
const res = await executor.run(['run', 'view', String(args.run_id), ...repoArgs, '--json', 'databaseId,name,status,conclusion,jobs,url'], { cwd });
|
|
49
|
+
if (!res.ok)
|
|
50
|
+
throw new Error(res.error);
|
|
51
|
+
return res.data || res.rawOutput;
|
|
52
|
+
}
|
|
53
|
+
case 'log_failed': {
|
|
54
|
+
if (!args.run_id)
|
|
55
|
+
throw new Error('log_failed 操作必须提供 run_id');
|
|
56
|
+
// gh 原生支持仅提取失败的日志!对 Agent 故障诊断价值极高
|
|
57
|
+
const res = await executor.run(['run', 'view', String(args.run_id), ...repoArgs, '--log-failed'], {
|
|
58
|
+
cwd,
|
|
59
|
+
timeoutMs: 60_000,
|
|
60
|
+
rawText: true,
|
|
61
|
+
});
|
|
62
|
+
if (!res.ok)
|
|
63
|
+
throw new Error(res.error);
|
|
64
|
+
return res.rawOutput || '未找到失败步骤的日志';
|
|
65
|
+
}
|
|
66
|
+
case 'rerun': {
|
|
67
|
+
if (!args.run_id)
|
|
68
|
+
throw new Error('rerun 操作必须提供 run_id');
|
|
69
|
+
const res = await executor.run(['run', 'rerun', String(args.run_id), ...repoArgs, '--failed'], { cwd });
|
|
70
|
+
if (!res.ok)
|
|
71
|
+
throw new Error(res.error);
|
|
72
|
+
return { message: '已成功重新触发失败任务', output: res.rawOutput };
|
|
73
|
+
}
|
|
74
|
+
case 'cancel': {
|
|
75
|
+
if (!args.run_id)
|
|
76
|
+
throw new Error('cancel 操作必须提供 run_id');
|
|
77
|
+
const res = await executor.run(['run', 'cancel', String(args.run_id), ...repoArgs], { cwd });
|
|
78
|
+
if (!res.ok)
|
|
79
|
+
throw new Error(res.error);
|
|
80
|
+
return { message: '已取消该工作流任务', output: res.rawOutput };
|
|
81
|
+
}
|
|
82
|
+
default:
|
|
83
|
+
throw new Error(`未知的 Run 操作: ${args.action}`);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DSH GitHub 插件核心数据类型定义
|
|
3
|
+
*/
|
|
4
|
+
export interface PluginConfig {
|
|
5
|
+
/** GitHub CLI (gh) 可执行文件路径,默认 'gh' */
|
|
6
|
+
ghPath?: string;
|
|
7
|
+
/** 进程超时限制(毫秒),默认 30,000ms */
|
|
8
|
+
defaultTimeoutMs?: number;
|
|
9
|
+
/** 单次安全输出字符数上限(防止 Token 溢出),默认 24,000 */
|
|
10
|
+
maxOutputChars?: number;
|
|
11
|
+
/** Web API 概览数据缓存时长(毫秒),默认 15,000ms */
|
|
12
|
+
cacheTtlMs?: number;
|
|
13
|
+
/** 查询列表默认限制条数,默认 20 */
|
|
14
|
+
defaultListLimit?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface GhExecutionOptions {
|
|
17
|
+
/** 命令执行的工作目录,优先使用当前 Agent 会话所在的 Workspace 物理路径 */
|
|
18
|
+
cwd?: string;
|
|
19
|
+
/** 进程超时限制(毫秒),默认 30,000ms */
|
|
20
|
+
timeoutMs?: number;
|
|
21
|
+
/** 附加环境变量 */
|
|
22
|
+
env?: NodeJS.ProcessEnv;
|
|
23
|
+
/** 是否强制以纯文本形式返回,不进行 JSON 尝试解析 */
|
|
24
|
+
rawText?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface GhResult<T = unknown> {
|
|
27
|
+
ok: boolean;
|
|
28
|
+
data?: T;
|
|
29
|
+
rawOutput?: string;
|
|
30
|
+
error?: string;
|
|
31
|
+
/** 是否因超出安全阈值而被截断 */
|
|
32
|
+
truncated?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface AuthStatus {
|
|
35
|
+
installed: boolean;
|
|
36
|
+
loggedIn: boolean;
|
|
37
|
+
platform?: string;
|
|
38
|
+
user?: string;
|
|
39
|
+
host?: string;
|
|
40
|
+
activeAccount?: boolean;
|
|
41
|
+
protocol?: string;
|
|
42
|
+
scopes?: string[];
|
|
43
|
+
raw?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface RepoMetadata {
|
|
46
|
+
nameWithOwner: string;
|
|
47
|
+
name: string;
|
|
48
|
+
owner: string;
|
|
49
|
+
defaultBranch: string;
|
|
50
|
+
currentBranch?: string;
|
|
51
|
+
description?: string;
|
|
52
|
+
isPrivate?: boolean;
|
|
53
|
+
url?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface PrItem {
|
|
56
|
+
number: number;
|
|
57
|
+
title: string;
|
|
58
|
+
state: 'OPEN' | 'CLOSED' | 'MERGED';
|
|
59
|
+
author: {
|
|
60
|
+
login: string;
|
|
61
|
+
avatarUrl?: string;
|
|
62
|
+
};
|
|
63
|
+
headRefName: string;
|
|
64
|
+
baseRefName: string;
|
|
65
|
+
isDraft: boolean;
|
|
66
|
+
mergeable?: 'MERGEABLE' | 'CONFLICTING' | 'UNKNOWN';
|
|
67
|
+
reviewDecision?: 'APPROVED' | 'CHANGES_REQUESTED' | 'REVIEW_REQUIRED';
|
|
68
|
+
statusCheckRollup?: Array<{
|
|
69
|
+
name: string;
|
|
70
|
+
status: string;
|
|
71
|
+
conclusion: string;
|
|
72
|
+
}>;
|
|
73
|
+
url: string;
|
|
74
|
+
updatedAt: string;
|
|
75
|
+
}
|
|
76
|
+
export interface IssueItem {
|
|
77
|
+
number: number;
|
|
78
|
+
title: string;
|
|
79
|
+
state: 'OPEN' | 'CLOSED';
|
|
80
|
+
author: {
|
|
81
|
+
login: string;
|
|
82
|
+
};
|
|
83
|
+
labels: Array<{
|
|
84
|
+
name: string;
|
|
85
|
+
color: string;
|
|
86
|
+
}>;
|
|
87
|
+
assignees: Array<{
|
|
88
|
+
login: string;
|
|
89
|
+
}>;
|
|
90
|
+
url: string;
|
|
91
|
+
updatedAt: string;
|
|
92
|
+
}
|
|
93
|
+
export interface WorkflowRunItem {
|
|
94
|
+
databaseId: number;
|
|
95
|
+
name: string;
|
|
96
|
+
status: 'queued' | 'in_progress' | 'completed';
|
|
97
|
+
conclusion?: 'success' | 'failure' | 'cancelled' | 'skipped';
|
|
98
|
+
event: string;
|
|
99
|
+
headBranch: string;
|
|
100
|
+
url: string;
|
|
101
|
+
createdAt: string;
|
|
102
|
+
}
|
|
103
|
+
export interface GitHubOverviewData {
|
|
104
|
+
auth: AuthStatus;
|
|
105
|
+
repo?: RepoMetadata;
|
|
106
|
+
pullRequests: PrItem[];
|
|
107
|
+
issues: IssueItem[];
|
|
108
|
+
runs: WorkflowRunItem[];
|
|
109
|
+
lastUpdated: string;
|
|
110
|
+
error?: string;
|
|
111
|
+
}
|
|
112
|
+
export interface UserRepoItem {
|
|
113
|
+
name: string;
|
|
114
|
+
nameWithOwner: string;
|
|
115
|
+
description?: string;
|
|
116
|
+
defaultBranch: string;
|
|
117
|
+
isPrivate: boolean;
|
|
118
|
+
stargazerCount?: number;
|
|
119
|
+
updatedAt: string;
|
|
120
|
+
url: string;
|
|
121
|
+
}
|
|
122
|
+
export interface WorkspaceMatrixItem {
|
|
123
|
+
id: string;
|
|
124
|
+
title: string;
|
|
125
|
+
path: string;
|
|
126
|
+
hasGit: boolean;
|
|
127
|
+
repo?: RepoMetadata;
|
|
128
|
+
sessionCount: number;
|
|
129
|
+
}
|
|
130
|
+
export interface GlobalOverviewData {
|
|
131
|
+
auth: AuthStatus;
|
|
132
|
+
userRepos: UserRepoItem[];
|
|
133
|
+
workspaceMatrix: WorkspaceMatrixItem[];
|
|
134
|
+
myPrs: Array<{
|
|
135
|
+
number: number;
|
|
136
|
+
title: string;
|
|
137
|
+
repository: {
|
|
138
|
+
nameWithOwner: string;
|
|
139
|
+
};
|
|
140
|
+
url: string;
|
|
141
|
+
updatedAt: string;
|
|
142
|
+
}>;
|
|
143
|
+
myIssues: Array<{
|
|
144
|
+
number: number;
|
|
145
|
+
title: string;
|
|
146
|
+
repository: {
|
|
147
|
+
nameWithOwner: string;
|
|
148
|
+
};
|
|
149
|
+
url: string;
|
|
150
|
+
updatedAt: string;
|
|
151
|
+
}>;
|
|
152
|
+
lastUpdated: string;
|
|
153
|
+
error?: string;
|
|
154
|
+
}
|
|
155
|
+
declare module '@deepseek-ai/cordis' {
|
|
156
|
+
interface Events {
|
|
157
|
+
'github/pr:create'(repo: string, pr: {
|
|
158
|
+
title: string;
|
|
159
|
+
url: string;
|
|
160
|
+
}): void;
|
|
161
|
+
'github/pr:merge'(repo: string, prNumber: number): void;
|
|
162
|
+
'github/issue:create'(repo: string, issue: {
|
|
163
|
+
title: string;
|
|
164
|
+
url: string;
|
|
165
|
+
}): void;
|
|
166
|
+
}
|
|
167
|
+
}
|
package/lib/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-github-flow",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"icon": "icon.svg",
|
|
5
|
+
"description": "GitHub Flow: Native GitHub CLI (gh) integration for DeepSeek Harness — Agent Tools, Slash Commands, and Web UI Workspace",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./lib/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./lib/index.js",
|
|
10
|
+
"./client": "./lib/client.js",
|
|
11
|
+
"./package.json": "./package.json"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"lib",
|
|
15
|
+
"icon.svg",
|
|
16
|
+
"cordis.patch.yml",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc && node scripts/build.mjs",
|
|
21
|
+
"prepare": "pnpm run build"
|
|
22
|
+
},
|
|
23
|
+
"dsh": {
|
|
24
|
+
"bundle": {
|
|
25
|
+
"patch": "./cordis.patch.yml"
|
|
26
|
+
},
|
|
27
|
+
"client": {
|
|
28
|
+
"platform": "web",
|
|
29
|
+
"entry": "./lib/client.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"dsh-plugin",
|
|
34
|
+
"deepseek-harness",
|
|
35
|
+
"github",
|
|
36
|
+
"gh-cli",
|
|
37
|
+
"cordis"
|
|
38
|
+
],
|
|
39
|
+
"author": "DSH Contributor",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public",
|
|
43
|
+
"registry": "https://registry.npmjs.org/"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@deepseek-ai/cordis": "*",
|
|
47
|
+
"@deepseek-ai/schemastery": "^3.18.4"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@deepseek-ai/schemastery": "^3.18.4"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^26.6.3",
|
|
54
|
+
"typescript": "^7.0.2"
|
|
55
|
+
}
|
|
56
|
+
}
|