diff --git a/agent/npc.ts b/agent/npc.ts index 22d8bdf..f598230 100644 --- a/agent/npc.ts +++ b/agent/npc.ts @@ -1,6 +1,6 @@ import { app } from './index.ts'; -import { useIssueEnv, useCommentEnv, useRepoInfoEnv } from '../src/index.ts' +import { useIssueEnv, useCommentEnv, useRepoInfoEnv, IssueLabel } from '../src/index.ts' import { pick } from 'es-toolkit'; const writeToProcess = (message: string) => { @@ -10,6 +10,32 @@ const writeToProcess = (message: string) => { console.log(message); } } +const getIssuesLabels = async () => { + const issueEnv = useIssueEnv(); + const repoInfoEnv = useRepoInfoEnv(); + const issueId = issueEnv.issueId; + const repoSlug = repoInfoEnv.repoSlug; + if (!issueId || !repoSlug) { + return []; + } + const res = await app.run({ + path: 'cnb', + key: 'getIssue', + payload: { + repo: repoSlug, + issueNumber: issueId + } + }); + if (res.code === 200) { + const issueData = res.data as any; + const labels = issueData.labels || []; + return labels as IssueLabel[]; + } + console.error('获取 Issue 详情失败', res); + return [] + +} + const main = async () => { const repoInfoEnv = useRepoInfoEnv(); const commentEnv = useCommentEnv(); @@ -17,7 +43,7 @@ const main = async () => { const pickCommentEnv = pick(commentEnv, ['commentId', 'commentIdLabel']); const pickIssueEnv = pick(issueEnv, ['issueId', 'issueIdLabel', 'issueIid', 'issueIidLabel', 'issueTitle', 'issueTitleLabel', 'issueDescription', 'issueDescriptionLabel']); const pickRepoInfoEnv = pick(repoInfoEnv, ['repoId', 'repoIdLabel', 'repoName', 'repoNameLabel', 'repoSlug', 'repoSlugLabel']); - const issueLabels = issueEnv.issueLabels || []; + // const issueLabels = issueEnv.issueLabels || []; const isComment = !!commentEnv.commentId; const envList = [ ...Object.entries(pickRepoInfoEnv).map(([key, value]) => `${key}: ${value}`), @@ -25,8 +51,10 @@ const main = async () => { ...Object.entries(pickCommentEnv).map(([key, value]) => `${key}: ${value}`), ] writeToProcess('当前环境变量:'); + const issueLabels = await getIssuesLabels(); + const issueLabelsNames = issueLabels.map(label => label.name) || []; envList.forEach(item => writeToProcess(item)); - if (!isComment && !issueLabels.includes('Run')) { + if (!isComment && !issueLabelsNames.includes('Run')) { writeToProcess('当前 Issue 不包含 Run 标签,跳过执行'); process.exit(0); } diff --git a/agent/routes/issues/list.ts b/agent/routes/issues/list.ts index 1e3cc64..3e170d4 100644 --- a/agent/routes/issues/list.ts +++ b/agent/routes/issues/list.ts @@ -49,4 +49,37 @@ app.route({ const res = await cnb.issue.getList(repo, params); ctx.forward(res); +}).addTo(app); + +app.route({ + path: 'cnb', + key: 'getIssue', + description: '获取 单个 Issue', + middleware: ['auth'], + metadata: { + tags: ['opencode'], + ...createSkill({ + skill: 'getIssue', + title: '获取 单个 Issue', + args: { + repo: tool.schema.string().optional().describe('代码仓库名称, 如 my-user/my-repo'), + issueNumber: tool.schema.union([tool.schema.string(), tool.schema.number()]).describe('Issue 编号'), + }, + summary: '获取 单个 Issue', + }) + } +}).define(async (ctx) => { + const cnb = await cnbManager.getContext(ctx); + let repo = ctx.query?.repo || useKey('CNB_REPO_SLUG_LOWERCASE'); + const issueNumber = ctx.query?.issueNumber; + + if (!repo) { + ctx.throw(400, '缺少参数 repo'); + } + if (!issueNumber) { + ctx.throw(400, '缺少参数 issueNumber'); + } + + const res = await cnb.issue.getItem(repo, issueNumber); + ctx.forward(res); }).addTo(app); \ No newline at end of file diff --git a/bun.lock b/bun.lock index e59e9a5..fe51e78 100644 --- a/bun.lock +++ b/bun.lock @@ -16,7 +16,7 @@ }, "devDependencies": { "@ai-sdk/openai-compatible": "^2.0.35", - "@kevisual/ai": "^0.0.27", + "@kevisual/ai": "^0.0.28", "@kevisual/api": "^0.0.62", "@kevisual/code-builder": "^0.0.6", "@kevisual/context": "^0.0.8", @@ -56,7 +56,7 @@ "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], - "@kevisual/ai": ["@kevisual/ai@0.0.27", "https://registry.npmmirror.com/@kevisual/ai/-/ai-0.0.27.tgz", { "dependencies": { "@ai-sdk/anthropic": "^3.0.58", "@ai-sdk/openai": "^3.0.41", "@ai-sdk/openai-compatible": "^2.0.35", "@kevisual/js-filter": "^0.0.6", "@kevisual/logger": "^0.0.4", "@kevisual/permission": "^0.0.4", "@kevisual/query": "^0.0.53", "ai": "^6.0.116", "zod": "^4.3.6" } }, "sha512-1FlDg3Tj4171XY5NpTq+do69CyACgDE5oTA1RJYxQlGgaPeAjx2V2ahBgIDHRRhMSX/ztB1pBF1rx4zDoXq99A=="], + "@kevisual/ai": ["@kevisual/ai@0.0.28", "https://registry.npmmirror.com/@kevisual/ai/-/ai-0.0.28.tgz", { "dependencies": { "@ai-sdk/anthropic": "^3.0.58", "@ai-sdk/openai": "^3.0.41", "@ai-sdk/openai-compatible": "^2.0.35", "@kevisual/js-filter": "^0.0.6", "@kevisual/logger": "^0.0.4", "@kevisual/permission": "^0.0.4", "@kevisual/query": "^0.0.53", "ai": "^6.0.116", "zod": "^4.3.6" } }, "sha512-GLwCNXfopDvOj+hEZwEIwOV2/3VGd+TCPgBClaYuAv30KzhgehlCW05HPjBducSg+uPcdKacEzZsecHjo5fMUQ=="], "@kevisual/api": ["@kevisual/api@0.0.62", "https://registry.npmmirror.com/@kevisual/api/-/api-0.0.62.tgz", { "dependencies": { "@kevisual/context": "^0.0.8", "@kevisual/js-filter": "^0.0.5", "@kevisual/load": "^0.0.6", "@paralleldrive/cuid2": "^3.3.0", "es-toolkit": "^1.45.1", "eventemitter3": "^5.0.4", "fuse.js": "^7.1.0", "nanoid": "^5.1.6", "path-browserify-esm": "^1.0.6", "sonner": "^2.0.7", "spark-md5": "^3.0.2", "zustand": "^5.0.11" } }, "sha512-GB8Ho2absXoXoZP2GKyuoRqRqjdwtV0JR512DXBaKJR2sIPn1KvuglbBiX+zPjDBBskv/ApvZKOoSwj1OmkrKQ=="], diff --git a/src/issue/index.ts b/src/issue/index.ts index 6fc3ad1..bb34878 100644 --- a/src/issue/index.ts +++ b/src/issue/index.ts @@ -5,12 +5,23 @@ export type IssueAssignee = { nickname: string; username: string; }; - export type IssueLabel = { color: string; description: string; id: string; name: string; + creator?: { + username: string; + nickname: string; + email: string; + is_npc: boolean; + }; + applied_by?: { + username: string; + nickname: string; + email: string; + is_npc: boolean; + } }; export type IssueState = 'open' | 'closed'; diff --git a/src/issue/npc/env.ts b/src/issue/npc/env.ts index 15cbf23..4b06d41 100644 --- a/src/issue/npc/env.ts +++ b/src/issue/npc/env.ts @@ -128,7 +128,6 @@ export const useIssueEnv = () => { const issueState = useKey("CNB_ISSUE_STATE"); const issueIsResolved = useKey("CNB_ISSUE_IS_RESOLVED"); const issueAssignees = useKey("CNB_ISSUE_ASSIGNEES"); - const issueLabels = useKey("CNB_ISSUE_LABELS"); const issuePriority = useKey("CNB_ISSUE_PRIORITY"); return { @@ -180,12 +179,6 @@ export const useIssueEnv = () => { */ issueAssignees, issueAssigneesLabel: "Issue 处理人列表", - /** - * @key CNB_ISSUE_LABELS - * @description:Issue 标签列表, 多个以 , 分隔。 - */ - issueLabels, - issueLabelsLabel: "Issue 标签列表, 多个以 , 分隔。", /** * @key CNB_ISSUE_PRIORITY * @description:Issue 优先级