@kevisual/cnb 0.0.37 → 0.0.40

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.
@@ -1,4 +1,4 @@
1
- import { app, cnb } from '../../app.ts';
1
+ import { app, cnbManager } from '../../app.ts';
2
2
  import { createSkill, Skill, tool } from '@kevisual/router'
3
3
 
4
4
  // 创建一个仓库 kevisual/test-repo
@@ -6,7 +6,7 @@ app.route({
6
6
  path: 'cnb',
7
7
  key: 'create-repo',
8
8
  description: '创建代码仓库, 参数name, visibility, description',
9
- middleware: ['auth-admin'],
9
+ middleware: ['auth'],
10
10
  metadata: {
11
11
  tags: ['opencode'],
12
12
  ...createSkill({
@@ -21,6 +21,7 @@ app.route({
21
21
  })
22
22
  }
23
23
  }).define(async (ctx) => {
24
+ const cnb = await cnbManager.getContext(ctx);
24
25
  const name = ctx.query?.name;
25
26
  const visibility = ctx.query?.visibility ?? 'public';
26
27
  const description = ctx.query?.description ?? '';
@@ -42,11 +43,32 @@ app.route({
42
43
  }
43
44
  }).addTo(app);
44
45
 
46
+ app.route({
47
+ path: 'cnb',
48
+ key: 'get-repo',
49
+ description: '获取代码仓库详情, 参数name',
50
+ middleware: ['auth'],
51
+ metadata: {
52
+ args: {
53
+ name: tool.schema.string().describe('代码仓库名称, 如 my-user/my-repo'),
54
+ }
55
+ }
56
+ }).define(async (ctx) => {
57
+ const cnb = await cnbManager.getContext(ctx);
58
+ const name = ctx.query?.name;
59
+
60
+ if (!name) {
61
+ ctx.throw(400, '缺少参数 name');
62
+ }
63
+ const res = await cnb.repo.getRepo(name);
64
+ ctx.forward(res);
65
+ }).addTo(app);
66
+
45
67
  app.route({
46
68
  path: 'cnb',
47
69
  key: 'create-repo-file',
48
70
  description: '在代码仓库中创建文件, repoName, filePath, content, encoding。使用CNB_COOKIE进行鉴权',
49
- middleware: ['auth-admin'],
71
+ middleware: ['auth'],
50
72
  metadata: {
51
73
  tags: ['opencode'],
52
74
  ...createSkill({
@@ -62,6 +84,7 @@ app.route({
62
84
  })
63
85
  }
64
86
  }).define(async (ctx) => {
87
+ const cnb = await cnbManager.getContext(ctx);
65
88
  const repoName = ctx.query?.repoName;
66
89
  const filePath = ctx.query?.filePath;
67
90
  const content = ctx.query?.content;
@@ -85,7 +108,7 @@ app.route({
85
108
  path: 'cnb',
86
109
  key: 'delete-repo',
87
110
  description: '删除代码仓库, 参数name',
88
- middleware: ['auth-admin'],
111
+ middleware: ['auth'],
89
112
  metadata: {
90
113
  tags: ['opencode'],
91
114
  ...createSkill({
@@ -98,12 +121,62 @@ app.route({
98
121
  })
99
122
  }
100
123
  }).define(async (ctx) => {
124
+ const cnb = await cnbManager.getContext(ctx);
101
125
  const name = ctx.query?.name;
102
126
 
103
127
  if (!name) {
104
128
  ctx.throw(400, '缺少参数 name');
105
129
  }
130
+ try {
131
+ const resCookie = await cnb.user.checkCookieValid()
132
+ if (resCookie.code !== 200) {
133
+ ctx.throw(401, 'Cookie 无效或已过期');
134
+ }
135
+ const res = await cnb.repo.deleteRepoCookie(name);
136
+ ctx.forward(res);
137
+ } catch (error) {
138
+ ctx.code = 200
139
+ ctx.body = { content: '已经删除' }
140
+ }
141
+ }).addTo(app);
106
142
 
107
- const res = await cnb.repo.deleteRepo(name);
143
+
144
+ app.route({
145
+ path: 'cnb',
146
+ key: 'update-repo-info',
147
+ description: '更新代码仓库信息, 参数name, description',
148
+ middleware: ['auth'],
149
+ metadata: {
150
+ tags: ['opencode'],
151
+ ...createSkill({
152
+ skill: 'update-repo-info',
153
+ title: '更新代码仓库信息',
154
+ args: {
155
+ name: tool.schema.string().describe('代码仓库名称'),
156
+ description: tool.schema.string().describe('代码仓库描述'),
157
+ license: tool.schema.string().describe('代码仓库许可证类型,如 MIT').optional(),
158
+ site: tool.schema.string().describe('代码仓库主页链接').optional(),
159
+ topics: tool.schema.array(tool.schema.string()).describe('代码仓库话题标签列表').optional(),
160
+ },
161
+ summary: '更新代码仓库的信息',
162
+ })
163
+ }
164
+ }).define(async (ctx) => {
165
+ const cnb = await cnbManager.getContext(ctx);
166
+ const name = ctx.query?.name;
167
+ const description = ctx.query?.description;
168
+ const license = ctx.query?.license;
169
+ const site = ctx.query?.site;
170
+ const topics = ctx.query?.topics;
171
+
172
+ if (!name) {
173
+ ctx.throw(400, '缺少参数 name');
174
+ }
175
+ if (!description) {
176
+ ctx.throw(400, '缺少参数 description');
177
+ }
178
+
179
+ const res = await cnb.repo.updateRepoInfo(name, { description, license, site, topics });
108
180
  ctx.forward(res);
109
- }).addTo(app);
181
+ }).addTo(app);
182
+
@@ -1,5 +1,5 @@
1
1
  import { useKey } from '@kevisual/context';
2
- import { app, cnb } from '../../app.ts';
2
+ import { app } from '../../app.ts';
3
3
  import z from 'zod';
4
4
 
5
5
  app.route({
@@ -0,0 +1,43 @@
1
+ import { createSkill, tool } from '@kevisual/router';
2
+
3
+ import { app, cnbManager, notCNBCheck } from '../../app.ts';
4
+
5
+ // 启动工作空间
6
+ app.route({
7
+ path: 'cnb',
8
+ key: 'cloud-build',
9
+ description: '云端构建,参数 event, repo, branch, ref, config, env',
10
+ middleware: ['auth'],
11
+ metadata: {
12
+ tags: ['opencode'],
13
+ ...createSkill({
14
+ skill: 'cloud-build',
15
+ title: '云端构建',
16
+ summary: '在云端构建代码仓库,参数包括 event, repo, branch, ref, config, env',
17
+ args: {
18
+ env: tool.schema.any().optional().describe('构建环境变量,格式为 { "KEY": "VALUE" }'),
19
+ event: tool.schema.string().optional().describe('触发事件类型,例如 api_trigger_event'),
20
+ branch: tool.schema.string().optional().describe('分支名称,默认主分支'),
21
+ config: tool.schema.string().describe('构建config文件内容,例如 cloudbuild.yaml对应的yml的内容'),
22
+ repo: tool.schema.string().describe('代码仓库路径,例如 user/repo'),
23
+ },
24
+ })
25
+ }
26
+ }).define(async (ctx) => {
27
+ const cnb = await cnbManager.getContext(ctx);
28
+ const repo = ctx.query?.repo;
29
+ const branch = ctx.query?.branch || 'main';
30
+ const config = ctx.query?.config;
31
+ const event = ctx.query?.event || 'api_trigger_event';
32
+ const env = ctx.query?.env ?? {};
33
+ if (!repo) {
34
+ ctx.throw(400, '缺少参数 repo');
35
+ }
36
+ const res = await cnb.build.startBuild(repo, {
37
+ branch,
38
+ config,
39
+ event,
40
+ env,
41
+ });
42
+ ctx.forward(res);
43
+ }).addTo(app);
@@ -1,15 +1,16 @@
1
1
  import { createSkill, tool } from '@kevisual/router';
2
- import { app, cnb } from '../../app.ts';
2
+ import { app, cnbManager, notCNBCheck } from '../../app.ts';
3
3
  import z from 'zod';
4
4
  import './skills.ts';
5
5
  import './keep.ts';
6
+ import './build.ts';
6
7
 
7
8
  // 启动工作空间
8
9
  app.route({
9
10
  path: 'cnb',
10
11
  key: 'start-workspace',
11
12
  description: '启动开发工作空间, 参数 repo',
12
- middleware: ['auth-admin'],
13
+ middleware: ['auth'],
13
14
  metadata: {
14
15
  tags: ['opencode'],
15
16
  ...createSkill({
@@ -24,6 +25,7 @@ app.route({
24
25
  })
25
26
  }
26
27
  }).define(async (ctx) => {
28
+ const cnb = await cnbManager.getContext(ctx);
27
29
  const repo = ctx.query?.repo;
28
30
  const branch = ctx.query?.branch;
29
31
  const ref = ctx.query?.ref;
@@ -42,7 +44,7 @@ app.route({
42
44
  path: 'cnb',
43
45
  key: 'list-workspace',
44
46
  description: '获取cnb开发工作空间列表,可选参数 status=running 获取运行中的环境',
45
- middleware: ['auth-admin'],
47
+ middleware: ['auth'],
46
48
  metadata: {
47
49
  tags: ['opencode'],
48
50
  ...createSkill({
@@ -59,13 +61,14 @@ app.route({
59
61
  })
60
62
  }
61
63
  }).define(async (ctx) => {
64
+ const cnb = await cnbManager.getContext(ctx);
62
65
  const { status = 'running', page, pageSize, slug, branch } = ctx.query || {};
63
66
  const res = await cnb.workspace.list({
64
67
  status: status as 'running' | 'closed' | undefined,
65
68
  page: page ?? 1,
66
69
  pageSize: pageSize ?? 100,
67
70
  });
68
- ctx.forward({ code: 200, message: 'success', data: res });
71
+ ctx.forward(res);
69
72
  }).addTo(app);
70
73
 
71
74
  // 获取工作空间详情
@@ -73,7 +76,7 @@ app.route({
73
76
  path: 'cnb',
74
77
  key: 'get-workspace',
75
78
  description: '获取工作空间详情,通过 repo 和 sn 获取',
76
- middleware: ['auth-admin'],
79
+ middleware: ['auth'],
77
80
  metadata: {
78
81
  tags: ['opencode'],
79
82
  ...createSkill({
@@ -87,6 +90,7 @@ app.route({
87
90
  })
88
91
  }
89
92
  }).define(async (ctx) => {
93
+ const cnb = await cnbManager.getContext(ctx);
90
94
  const repo = ctx.query?.repo;
91
95
  const sn = ctx.query?.sn;
92
96
  if (!repo) {
@@ -96,7 +100,7 @@ app.route({
96
100
  ctx.throw(400, '缺少参数 sn');
97
101
  }
98
102
  const res = await cnb.workspace.getDetail(repo, sn);
99
- ctx.forward({ code: 200, message: 'success', data: res });
103
+ ctx.forward(res);
100
104
  }).addTo(app);
101
105
 
102
106
  // 删除工作空间
@@ -104,7 +108,7 @@ app.route({
104
108
  path: 'cnb',
105
109
  key: 'delete-workspace',
106
110
  description: '删除工作空间,通过 pipelineId 或 sn',
107
- middleware: ['auth-admin'],
111
+ middleware: ['auth'],
108
112
  metadata: {
109
113
  tags: ['opencode'],
110
114
  ...createSkill({
@@ -119,6 +123,7 @@ app.route({
119
123
  })
120
124
  }
121
125
  }).define(async (ctx) => {
126
+ const cnb = await cnbManager.getContext(ctx);
122
127
  const pipelineId = ctx.query?.pipelineId;
123
128
  const sn = ctx.query?.sn;
124
129
  const sns = ctx.query?.sns;
@@ -143,7 +148,7 @@ app.route({
143
148
  path: 'cnb',
144
149
  key: 'stop-workspace',
145
150
  description: '停止工作空间,通过 pipelineId 或 sn',
146
- middleware: ['auth-admin'],
151
+ middleware: ['auth'],
147
152
  metadata: {
148
153
  tags: ['opencode'],
149
154
  ...createSkill({
@@ -157,12 +162,14 @@ app.route({
157
162
  })
158
163
  }
159
164
  }).define(async (ctx) => {
165
+ const cnb = await cnbManager.getContext(ctx);
160
166
  const pipelineId = ctx.query?.pipelineId;
161
167
  const sn = ctx.query?.sn;
162
168
  if (!pipelineId && !sn) {
163
169
  ctx.throw(400, 'pipelineId 和 sn 必须提供其中一个');
164
170
  }
165
171
  const res = await cnb.workspace.stopWorkspace({ pipelineId, sn });
166
- ctx.forward({ code: 200, message: 'success', data: res });
172
+ ctx.forward(res);
167
173
  }).addTo(app);
168
174
 
175
+
@@ -1,5 +1,5 @@
1
1
  import { tool } from '@kevisual/router';
2
- import { app, cnb } from '../../app.ts';
2
+ import { app, cnbManager, notCNBCheck } from '../../app.ts';
3
3
  import { addKeepAliveData, KeepAliveData, removeKeepAliveData, createLiveData } from '../../../src/workspace/keep-file-live.ts';
4
4
  import { useKey } from '@kevisual/context';
5
5
 
@@ -8,7 +8,7 @@ app.route({
8
8
  path: 'cnb',
9
9
  key: 'keep-workspace-alive',
10
10
  description: '保持工作空间存活技能,参数repo:代码仓库路径,例如 user/repo,pipelineId:流水线ID,例如 cnb-708-1ji9sog7o-001',
11
- middleware: ['auth-admin'],
11
+ middleware: ['auth'],
12
12
  metadata: {
13
13
  tags: [],
14
14
  ...({
@@ -19,9 +19,11 @@ app.route({
19
19
  })
20
20
  }
21
21
  }).define(async (ctx) => {
22
+
23
+ const cnb = await cnbManager.getContext(ctx);
22
24
  const repo = ctx.query?.repo as string;
23
25
  const pipelineId = ctx.query?.pipelineId as string;
24
-
26
+ if (notCNBCheck(ctx)) return;
25
27
  if (!repo || !pipelineId) {
26
28
  ctx.throw(400, '缺少参数 repo 或 pipelineId');
27
29
  }
@@ -51,7 +53,7 @@ app.route({
51
53
  path: 'cnb',
52
54
  key: 'stop-keep-workspace-alive',
53
55
  description: '停止保持工作空间存活技能, 参数repo:代码仓库路径,例如 user/repo,pipelineId:流水线ID,例如 cnb-708-1ji9sog7o-001',
54
- middleware: ['auth-admin'],
56
+ middleware: ['auth'],
55
57
  metadata: {
56
58
  tags: [],
57
59
  ...({
@@ -62,6 +64,7 @@ app.route({
62
64
  })
63
65
  }
64
66
  }).define(async (ctx) => {
67
+ if (notCNBCheck(ctx)) return;
65
68
  const repo = ctx.query?.repo as string;
66
69
  const pipelineId = ctx.query?.pipelineId as string;
67
70
 
@@ -79,7 +82,7 @@ app.route({
79
82
  path: 'cnb',
80
83
  key: 'keep-alive-current-workspace',
81
84
  description: '保持当前工作空间存活技能',
82
- middleware: ['auth-admin'],
85
+ middleware: ['auth'],
83
86
  metadata: {
84
87
  tags: ['opencode'],
85
88
  skill: 'keep-alive-current-workspace',
@@ -87,6 +90,7 @@ app.route({
87
90
  summary: '保持当前工作空间存活,防止被关闭或释放资源',
88
91
  }
89
92
  }).define(async (ctx) => {
93
+ if (notCNBCheck(ctx)) return;
90
94
  const pipelineId = useKey('CNB_PIPELINE_ID');
91
95
  const repo = useKey('CNB_REPO_SLUG_LOWERCASE');
92
96
  if (!pipelineId || !repo) {
@@ -1,5 +1,5 @@
1
1
  import { createSkill, tool } from '@kevisual/router';
2
- import { app, cnb } from '../../app.ts';
2
+ import { app, cnbManager } from '../../app.ts';
3
3
 
4
4
  // 批量删除已停止的cnb工作空间
5
5
  // app.route({
@@ -35,7 +35,7 @@ app.route({
35
35
  path: 'cnb',
36
36
  key: 'clean-closed-workspace',
37
37
  description: '批量删除已停止的cnb工作空间',
38
- middleware: ['auth-admin'],
38
+ middleware: ['auth'],
39
39
  metadata: {
40
40
  tags: ['opencode'],
41
41
  ...createSkill({
@@ -45,6 +45,7 @@ app.route({
45
45
  })
46
46
  }
47
47
  }).define(async (ctx) => {
48
+ const cnb = await cnbManager.getContext(ctx);
48
49
  const closedWorkspaces = await cnb.workspace.list({ status: 'closed', pageSize: 100 });
49
50
  if (closedWorkspaces.code !== 200) {
50
51
  ctx.throw(500, '获取已关闭工作空间列表失败');