@goliapkg/sentori-cli 1.7.0 → 1.9.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 +87 -8
- package/lib/artifacts.d.ts +7 -0
- package/lib/artifacts.d.ts.map +1 -1
- package/lib/artifacts.js +1 -1
- package/lib/artifacts.js.map +1 -1
- package/lib/compatibility.js +1 -1
- package/lib/compatibility.js.map +1 -1
- package/lib/index.js +12 -6
- package/lib/index.js.map +1 -1
- package/lib/issue.d.ts +13 -2
- package/lib/issue.d.ts.map +1 -1
- package/lib/issue.js +12 -1
- package/lib/issue.js.map +1 -1
- package/lib/mcp.d.ts +6 -0
- package/lib/mcp.d.ts.map +1 -1
- package/lib/mcp.js +228 -65
- package/lib/mcp.js.map +1 -1
- package/lib/web.d.ts +3 -0
- package/lib/web.d.ts.map +1 -0
- package/lib/web.js +121 -0
- package/lib/web.js.map +1 -0
- package/lib/workflow.d.ts +2 -0
- package/lib/workflow.d.ts.map +1 -1
- package/lib/workflow.js +28 -4
- package/lib/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/issue.test.ts +27 -0
- package/src/__tests__/mcp.test.ts +128 -1
- package/src/__tests__/web.test.ts +48 -0
- package/src/__tests__/workflow.test.ts +77 -2
- package/src/artifacts.ts +3 -1
- package/src/compatibility.ts +1 -1
- package/src/index.ts +11 -6
- package/src/issue.ts +16 -5
- package/src/mcp.ts +205 -67
- package/src/web.ts +88 -0
- package/src/workflow.ts +24 -4
package/lib/workflow.js
CHANGED
|
@@ -3,6 +3,7 @@ import { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from 'n
|
|
|
3
3
|
import { basename, dirname, resolve } from 'node:path';
|
|
4
4
|
import { gunzipSync } from 'node:zlib';
|
|
5
5
|
import { parseArgs } from 'node:util';
|
|
6
|
+
import { showProject } from './apps.js';
|
|
6
7
|
import { fetchArtifacts } from './artifacts.js';
|
|
7
8
|
import { checkCompatibility } from './compatibility.js';
|
|
8
9
|
import { dwarfBinariesIn } from './native-artifacts.js';
|
|
@@ -44,7 +45,7 @@ export function loadUploadConfig(path) {
|
|
|
44
45
|
throw new Error('config requires version: 1, apiUrl, and artifacts; run sentori init');
|
|
45
46
|
if (Object.hasOwn(value, 'token'))
|
|
46
47
|
throw new Error('store the API token in the environment and set tokenEnv, not token in the config');
|
|
47
|
-
const allowed = new Set(['version', 'apiUrl', 'tokenEnv', 'release', 'artifacts', 'sources', 'sourceArchive']);
|
|
48
|
+
const allowed = new Set(['version', 'apiUrl', 'tokenEnv', 'projectId', 'release', 'artifacts', 'sources', 'sourceArchive']);
|
|
48
49
|
for (const key of Object.keys(value))
|
|
49
50
|
if (!allowed.has(key))
|
|
50
51
|
throw new Error(`unknown config field: ${key}`);
|
|
@@ -53,6 +54,8 @@ export function loadUploadConfig(path) {
|
|
|
53
54
|
throw new Error(`unknown artifact kind ${kind}; use sourcemap, dsym, or mapping`);
|
|
54
55
|
strings(paths, `artifacts.${kind}`);
|
|
55
56
|
}
|
|
57
|
+
if (value.projectId !== undefined && (typeof value.projectId !== 'string' || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value.projectId)))
|
|
58
|
+
throw new Error('projectId must be the expected Project UUID');
|
|
56
59
|
if (value.release !== undefined && (typeof value.release !== 'string' || !value.release.trim()))
|
|
57
60
|
throw new Error('release must be a non-empty string');
|
|
58
61
|
if (value.sourceArchive !== undefined && typeof value.sourceArchive !== 'string')
|
|
@@ -102,7 +105,7 @@ export function prepareUploadPlan(configPath, overrides = {}) {
|
|
|
102
105
|
const release = overrides.release ?? process.env.SENTORI_RELEASE ?? config.release;
|
|
103
106
|
if (!release?.trim())
|
|
104
107
|
throw new Error('set --release, SENTORI_RELEASE, or config.release to the exact SDK release');
|
|
105
|
-
const plan = { release, apiUrl: apiUrl(overrides.apiUrl ?? process.env.SENTORI_API_URL ?? config.apiUrl), tokenEnv: config.tokenEnv, files: [] };
|
|
108
|
+
const plan = { release, apiUrl: apiUrl(overrides.apiUrl ?? process.env.SENTORI_API_URL ?? config.apiUrl), tokenEnv: config.tokenEnv, ...(config.projectId ? { projectId: config.projectId } : {}), files: [] };
|
|
106
109
|
const add = (kind, path, name = basename(path)) => {
|
|
107
110
|
let bytes = readFileSync(path);
|
|
108
111
|
if (bytes[0] === 0x1f && bytes[1] === 0x8b) {
|
|
@@ -161,7 +164,7 @@ export function prepareUploadPlan(configPath, overrides = {}) {
|
|
|
161
164
|
return plan;
|
|
162
165
|
}
|
|
163
166
|
export async function verifyUploadPlan(plan, token) {
|
|
164
|
-
const result = await fetchArtifacts({ ...plan, token });
|
|
167
|
+
const result = await fetchArtifacts({ ...plan, token, verify: true });
|
|
165
168
|
if (!result.known || result.release !== plan.release)
|
|
166
169
|
return [`release not found: ${plan.release}`];
|
|
167
170
|
const problems = [];
|
|
@@ -170,6 +173,11 @@ export async function verifyUploadPlan(plan, token) {
|
|
|
170
173
|
&& (file.kind === 'dsym' || row.name === file.name));
|
|
171
174
|
if (!matches.length)
|
|
172
175
|
problems.push(`missing exact bytes: ${file.kind} ${file.name}`);
|
|
176
|
+
else if (!matches.some(row => row.storageVerification?.integrity === 'verified'
|
|
177
|
+
&& row.storageVerification.actualContentHash === file.hash
|
|
178
|
+
&& row.storageVerification.actualSizeBytes === file.bytes
|
|
179
|
+
&& row.storageVerification.usable === true))
|
|
180
|
+
problems.push(`stored bytes not verified: ${file.kind} ${file.name}; upgrade the server if storageVerification is absent`);
|
|
173
181
|
else if (!matches.some(row => row.usable === true))
|
|
174
182
|
problems.push(`${matches.some(row => row.usable === false) ? 'unreadable' : 'not verified by server'}: ${file.kind} ${file.name}`);
|
|
175
183
|
}
|
|
@@ -210,6 +218,7 @@ export async function runWorkflow(command, argv) {
|
|
|
210
218
|
const token = process.env[config.tokenEnv];
|
|
211
219
|
if (!token)
|
|
212
220
|
throw new Error(`set ${config.tokenEnv} to an API-scope token`);
|
|
221
|
+
await verifyProject({ apiUrl: apiUrl(parsed.values['api-url'] ?? process.env.SENTORI_API_URL ?? config.apiUrl), projectId: config.projectId }, token);
|
|
213
222
|
const result = await fetchArtifacts({
|
|
214
223
|
apiUrl: apiUrl(parsed.values['api-url'] ?? process.env.SENTORI_API_URL ?? config.apiUrl), token,
|
|
215
224
|
release: parsed.values.release ?? process.env.SENTORI_RELEASE ?? config.release ?? '__sentori_compatibility_check__',
|
|
@@ -227,6 +236,7 @@ export async function runWorkflow(command, argv) {
|
|
|
227
236
|
const token = process.env[plan.tokenEnv];
|
|
228
237
|
if (!token)
|
|
229
238
|
throw new Error(`set ${plan.tokenEnv} to an API-scope token`);
|
|
239
|
+
await verifyProject(plan, token);
|
|
230
240
|
// Check credentials before the first write. An unknown release is allowed.
|
|
231
241
|
console.log(checkCompatibility(await fetchArtifacts({ ...plan, token }), plan.files.some(file => file.kind === 'srcbundle')));
|
|
232
242
|
const failures = [];
|
|
@@ -248,7 +258,12 @@ export async function runWorkflow(command, argv) {
|
|
|
248
258
|
}
|
|
249
259
|
}
|
|
250
260
|
}
|
|
251
|
-
|
|
261
|
+
try {
|
|
262
|
+
failures.push(...await verifyUploadPlan(plan, token));
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
failures.push(`verification request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
266
|
+
}
|
|
252
267
|
if (failures.length)
|
|
253
268
|
throw new Error(failures.join('\n'));
|
|
254
269
|
console.log(`Verified ${plan.files.length} exact file(s) for ${plan.release}: stored bytes match and format checks passed. Event/build matching is not asserted.`);
|
|
@@ -286,4 +301,13 @@ export async function runSourcesPack(argv) {
|
|
|
286
301
|
return 1;
|
|
287
302
|
}
|
|
288
303
|
}
|
|
304
|
+
async function verifyProject(config, token) {
|
|
305
|
+
if (!config.projectId)
|
|
306
|
+
return;
|
|
307
|
+
const { project } = await showProject({ apiUrl: config.apiUrl, token });
|
|
308
|
+
if (project.id.toLowerCase() !== config.projectId.toLowerCase()) {
|
|
309
|
+
throw new Error(`Project mismatch: expected ${config.projectId}, token belongs to ${project.id}. No files uploaded.`);
|
|
310
|
+
}
|
|
311
|
+
console.log(`Project verified: ${project.name} (${project.id})`);
|
|
312
|
+
}
|
|
289
313
|
//# sourceMappingURL=workflow.js.map
|
package/lib/workflow.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goliapkg/sentori-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Sentori CLI \u2014 configure, upload and verify release debug files and source archives.",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"author": "GOLIA K.K. <takagi@golia.jp> (https://golia.jp)",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { expect, test } from 'bun:test'
|
|
2
|
+
import { listIssues } from '../issue.js'
|
|
3
|
+
|
|
4
|
+
test('CLI forwards pagination and filters and preserves page metadata', async () => {
|
|
5
|
+
const page = { issues: [{ id: 'second' }], total: 3, limit: 1, offset: 1, nextOffset: 2 }
|
|
6
|
+
const server = Bun.serve({ port: 0, fetch(request) {
|
|
7
|
+
const url = new URL(request.url)
|
|
8
|
+
expect(url.pathname).toBe('/api/issues')
|
|
9
|
+
expect(Object.fromEntries(url.searchParams)).toEqual({ status: 'open', app_id: 'app', environment: 'development', limit: '1', offset: '1' })
|
|
10
|
+
return Response.json(page)
|
|
11
|
+
} })
|
|
12
|
+
try {
|
|
13
|
+
const child = Bun.spawn([process.execPath, new URL('../index.ts', import.meta.url).pathname,
|
|
14
|
+
'issue', 'list', '--json', '--limit', '1', '--offset', '1', '--app', 'app', '--environment', 'development', '--api-url', server.url.toString()], {
|
|
15
|
+
env: { ...process.env, SENTORI_API_TOKEN: 'test-token' }, stdout: 'pipe', stderr: 'pipe',
|
|
16
|
+
})
|
|
17
|
+
const output = await new Response(child.stdout).text()
|
|
18
|
+
expect(await child.exited).toBe(0)
|
|
19
|
+
expect(JSON.parse(output)).toEqual(page)
|
|
20
|
+
} finally { await server.stop(true) }
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('invalid pagination is rejected before making a request', async () => {
|
|
24
|
+
const config = { apiUrl: 'http://127.0.0.1:1', token: 'test' }
|
|
25
|
+
for (const limit of [0, -1, 201, 1.5, NaN]) await expect(listIssues(config, { limit })).rejects.toThrow('--limit')
|
|
26
|
+
for (const offset of [-1, 1.5, NaN, Infinity, Number.MAX_SAFE_INTEGER + 1]) await expect(listIssues(config, { offset })).rejects.toThrow('--offset')
|
|
27
|
+
})
|
|
@@ -3,16 +3,20 @@
|
|
|
3
3
|
import { describe, expect, test } from 'bun:test'
|
|
4
4
|
|
|
5
5
|
import { buildTools } from '../mcp.js'
|
|
6
|
+
import { fileURLToPath } from 'node:url'
|
|
6
7
|
|
|
7
8
|
describe('mcp tools', () => {
|
|
8
9
|
const tools = buildTools()
|
|
9
10
|
|
|
10
|
-
test('
|
|
11
|
+
test('the closed loop includes durable watch', () => {
|
|
11
12
|
expect(tools.map((t) => t.name).sort()).toEqual([
|
|
13
|
+
'sentori_issue_attachment',
|
|
12
14
|
'sentori_issue_bundle',
|
|
13
15
|
'sentori_issue_list',
|
|
14
16
|
'sentori_issue_note',
|
|
17
|
+
'sentori_issue_read',
|
|
15
18
|
'sentori_issue_resolve',
|
|
19
|
+
'sentori_issue_watch',
|
|
16
20
|
])
|
|
17
21
|
})
|
|
18
22
|
|
|
@@ -30,3 +34,126 @@ describe('mcp tools', () => {
|
|
|
30
34
|
}
|
|
31
35
|
})
|
|
32
36
|
})
|
|
37
|
+
|
|
38
|
+
test('watch and evidence use the project API with credentials and lossless cursors', async () => {
|
|
39
|
+
const requests: { url: URL; auth: string | null }[] = []
|
|
40
|
+
const server = Bun.serve({
|
|
41
|
+
port: 0,
|
|
42
|
+
fetch(req) {
|
|
43
|
+
const url = new URL(req.url)
|
|
44
|
+
requests.push({ url, auth: req.headers.get('authorization') })
|
|
45
|
+
if (url.searchParams.get('format') === 'json') return Response.json({ schemaVersion: 1, evidence: { missing: ['stack'] } })
|
|
46
|
+
if (url.pathname.endsWith('/bundle')) return new Response('# Evidence')
|
|
47
|
+
return Response.json({ changes: [], nextCursor: 'v1:test:9223372036854775807', hasMore: false })
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
try {
|
|
51
|
+
const tools = buildTools()
|
|
52
|
+
const ctx = { apiUrl: server.url.toString(), token: 'test-only' }
|
|
53
|
+
const watch = tools.find((t) => t.name === 'sentori_issue_watch')!
|
|
54
|
+
const bundle = tools.find((t) => t.name === 'sentori_issue_bundle')!
|
|
55
|
+
const cursor = 'v1:test:9223372036854775807'
|
|
56
|
+
const result = await watch.handler({ cursor, limit: 17, waitSeconds: 25 }, ctx)
|
|
57
|
+
expect(result).toEqual({ changes: [], nextCursor: cursor, hasMore: false })
|
|
58
|
+
expect(requests[0].url.pathname).toBe('/api/issues/watch')
|
|
59
|
+
expect(requests[0].url.searchParams.get('cursor')).toBe(cursor)
|
|
60
|
+
expect(requests[0].url.searchParams.get('waitSeconds')).toBe('25')
|
|
61
|
+
expect(requests[0].auth).toBe('Bearer test-only')
|
|
62
|
+
await bundle.handler({ issueId: 'a/b', format: 'json' }, ctx)
|
|
63
|
+
expect(requests[1].url.pathname).toBe('/api/issues/a%2Fb/bundle')
|
|
64
|
+
expect(requests[1].url.searchParams.get('format')).toBe('json')
|
|
65
|
+
expect(await bundle.handler({ issueId: 'test' }, ctx)).toBe('# Evidence')
|
|
66
|
+
for (const args of [{ waitSeconds: 26 }, { limit: 0 }, { limit: 1.5 }]) {
|
|
67
|
+
await expect(watch.handler(args, ctx)).rejects.toThrow()
|
|
68
|
+
}
|
|
69
|
+
expect(requests).toHaveLength(3)
|
|
70
|
+
} finally { server.stop(true) }
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('stdio negotiates, stays responsive during watch, and separates protocol and tool errors', async () => {
|
|
74
|
+
const server = Bun.serve({
|
|
75
|
+
port: 0,
|
|
76
|
+
async fetch(req) {
|
|
77
|
+
if (new URL(req.url).pathname.endsWith('/attachments/test')) {
|
|
78
|
+
return new Response(Buffer.from('R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==', 'base64'), { headers: { 'Content-Type': 'image/gif' } })
|
|
79
|
+
}
|
|
80
|
+
if (new URL(req.url).pathname.endsWith('/watch')) {
|
|
81
|
+
await Bun.sleep(200)
|
|
82
|
+
return Response.json({ schemaVersion: 1, changes: [], nextCursor: 'v1:test:0', hasMore: false })
|
|
83
|
+
}
|
|
84
|
+
return Response.json({ error: 'database_unavailable' }, { status: 503 })
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
const source = fileURLToPath(new URL('../mcp.ts', import.meta.url))
|
|
88
|
+
const requests = [
|
|
89
|
+
{ id: 0, method: 'initialize', params: { protocolVersion: '2025-11-25' } },
|
|
90
|
+
{ id: 1, method: 'tools/call', params: { name: 'sentori_issue_watch', arguments: { waitSeconds: 1 } } },
|
|
91
|
+
{ id: 2, method: 'ping' },
|
|
92
|
+
{ id: 3, method: 'tools/call', params: { name: 'sentori_issue_list' } },
|
|
93
|
+
{ id: 4, method: 'tools/call', params: { name: 'sentori_issue_watch', arguments: { waitSeconds: 26 } } },
|
|
94
|
+
{ id: 5, method: 'unknown' },
|
|
95
|
+
{ id: 6, method: 'tools/call', params: { name: 'missing' } },
|
|
96
|
+
{ id: 7, method: 'tools/list' },
|
|
97
|
+
{ id: 8, method: 'tools/call', params: { name: 'sentori_issue_attachment', arguments: { issueId: 'issue', attachmentRef: 'test' } } },
|
|
98
|
+
].map((r) => JSON.stringify({ jsonrpc: '2.0', ...r })).join('\n') + '\nnull\n{broken\n'
|
|
99
|
+
try {
|
|
100
|
+
const child = Bun.spawn([process.execPath, '-e', `import {runMcpServer} from ${JSON.stringify(source)}; await runMcpServer({apiUrl: ${JSON.stringify(server.url.toString())}, token: 'test-only'})`], {
|
|
101
|
+
stdin: new Blob([requests]), stdout: 'pipe', stderr: 'pipe',
|
|
102
|
+
})
|
|
103
|
+
const output = await new Response(child.stdout).text()
|
|
104
|
+
expect(await child.exited).toBe(0)
|
|
105
|
+
const responses = output.trim().split('\n').map((line) => JSON.parse(line))
|
|
106
|
+
const byId = (id: number) => responses.find((r) => r.id === id)
|
|
107
|
+
expect(byId(0).result.protocolVersion).toBe('2025-11-25')
|
|
108
|
+
expect(byId(1).result.structuredContent.nextCursor).toBe('v1:test:0')
|
|
109
|
+
expect(responses.indexOf(byId(2))).toBeLessThan(responses.indexOf(byId(1)))
|
|
110
|
+
expect(byId(3).result.isError).toBe(true)
|
|
111
|
+
expect(byId(3).result.structuredContent.error).toEqual({ code: 'database_unavailable', status: 503, retryable: true })
|
|
112
|
+
expect(byId(4).result.isError).toBe(true)
|
|
113
|
+
expect(byId(5).error.code).toBe(-32601)
|
|
114
|
+
expect(byId(6).error.code).toBe(-32602)
|
|
115
|
+
expect(byId(7).result.tools.find((t: { name: string }) => t.name === 'sentori_issue_watch').annotations.readOnlyHint).toBe(true)
|
|
116
|
+
expect(byId(8).result.content[0]).toEqual({ type: 'image', mimeType: 'image/gif', data: 'R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==' })
|
|
117
|
+
expect(responses.filter((r) => r.id === null).map((r) => r.error.code)).toEqual([-32600, -32700])
|
|
118
|
+
} finally { server.stop(true) }
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test('attachment reads are bounded even without Content-Length', async () => {
|
|
122
|
+
const server = Bun.serve({
|
|
123
|
+
port: 0,
|
|
124
|
+
fetch() {
|
|
125
|
+
return new Response(new ReadableStream({
|
|
126
|
+
start(controller) {
|
|
127
|
+
controller.enqueue(new Uint8Array(1024 * 1024))
|
|
128
|
+
controller.enqueue(new Uint8Array(1))
|
|
129
|
+
controller.close()
|
|
130
|
+
},
|
|
131
|
+
}), { headers: { 'Content-Type': 'text/plain' } })
|
|
132
|
+
},
|
|
133
|
+
})
|
|
134
|
+
try {
|
|
135
|
+
const tool = buildTools().find((t) => t.name === 'sentori_issue_attachment')!
|
|
136
|
+
await expect(tool.handler({ issueId: 'i', attachmentRef: 'r' }, { apiUrl: server.url.toString(), token: 'test-only' })).rejects.toThrow('1 MiB')
|
|
137
|
+
} finally { server.stop(true) }
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
test('a cancelled watch releases the request without blocking subsequent calls', async () => {
|
|
141
|
+
const server = Bun.serve({ port: 0, fetch: () => new Promise<Response>(() => {}) })
|
|
142
|
+
const source = fileURLToPath(new URL('../mcp.ts', import.meta.url))
|
|
143
|
+
const input = [
|
|
144
|
+
{ id: 1, method: 'tools/call', params: { name: 'sentori_issue_watch', arguments: { waitSeconds: 25 } } },
|
|
145
|
+
{ method: 'notifications/cancelled', params: { requestId: 1, reason: 'test cancellation' } },
|
|
146
|
+
{ id: 2, method: 'ping' },
|
|
147
|
+
].map((r) => JSON.stringify({ jsonrpc: '2.0', ...r })).join('\n') + '\n'
|
|
148
|
+
try {
|
|
149
|
+
const child = Bun.spawn([process.execPath, '-e', `import {runMcpServer} from ${JSON.stringify(source)}; await runMcpServer({apiUrl: ${JSON.stringify(server.url.toString())}, token: 'test-only'})`], {
|
|
150
|
+
stdin: new Blob([input]), stdout: 'pipe', stderr: 'pipe',
|
|
151
|
+
})
|
|
152
|
+
const output = await new Response(child.stdout).text()
|
|
153
|
+
expect(await child.exited).toBe(0)
|
|
154
|
+
const responses = output.trim().split('\n').map((line) => JSON.parse(line))
|
|
155
|
+
expect(responses).toHaveLength(2)
|
|
156
|
+
expect(responses.find((r) => r.id === 1).result.isError).toBe(true)
|
|
157
|
+
expect(responses.find((r) => r.id === 2).result).toEqual({})
|
|
158
|
+
} finally { server.stop(true) }
|
|
159
|
+
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { afterEach, expect, test } from 'bun:test'
|
|
2
|
+
import { runWeb } from '../web.js'
|
|
3
|
+
const original = globalThis.fetch
|
|
4
|
+
const args = ['--token','fixture','--api-url','https://monitor.test']
|
|
5
|
+
const reply = (body: unknown, status=200) => new Response(JSON.stringify(body), {status,headers:{'Content-Type':'application/json'}})
|
|
6
|
+
afterEach(()=>{globalThis.fetch=original})
|
|
7
|
+
test('performance filters are encoded and token is scoped', async()=>{
|
|
8
|
+
globalThis.fetch=(async(url,init)=>{
|
|
9
|
+
const u=new URL(String(url)); expect(u.pathname).toBe('/api/web/performance')
|
|
10
|
+
expect(u.searchParams.get('route')).toBe('/orders/:id');expect(u.searchParams.get('device')).toBe('mobile')
|
|
11
|
+
expect((init?.headers as Record<string,string>).Authorization).toBe('Bearer fixture')
|
|
12
|
+
return reply({visits:0})
|
|
13
|
+
}) as typeof fetch
|
|
14
|
+
expect(await runWeb(['performance',...args,'--app','app','--route','/orders/:id','--device','mobile'])).toBe(0)
|
|
15
|
+
})
|
|
16
|
+
test('project mismatch prevents a mutation',async()=>{
|
|
17
|
+
let calls=0
|
|
18
|
+
globalThis.fetch=(async()=>{calls++;return reply({project:{id:'other'}})}) as typeof fetch
|
|
19
|
+
expect(await runWeb(['run',...args,'--id','check','--project','expected'])).toBe(2)
|
|
20
|
+
expect(calls).toBe(1)
|
|
21
|
+
})
|
|
22
|
+
test('manual retries retain command ID and deployment trigger',async()=>{
|
|
23
|
+
const bodies: unknown[]=[]
|
|
24
|
+
globalThis.fetch=(async(_url,init)=>{bodies.push(JSON.parse(String(init?.body)));return reply({id:'run'})}) as typeof fetch
|
|
25
|
+
for(let i=0;i<2;i++) expect(await runWeb(['run',...args,'--id','check','--command-id','same-command','--trigger','deployment'])).toBe(0)
|
|
26
|
+
expect(bodies).toEqual(Array(2).fill({action:'run',commandId:'same-command',id:'check',trigger:'deployment'}))
|
|
27
|
+
})
|
|
28
|
+
test('strict distinguishes site failure, monitoring failure and successful runs',async()=>{
|
|
29
|
+
for(const [status,code] of [['passed',0],['failed',1],['error',2],['cancelled',2],['running',2]] as const){
|
|
30
|
+
globalThis.fetch=(async()=>reply({runs:[{id:'run',status}]})) as typeof fetch
|
|
31
|
+
expect(await runWeb(['runs',...args,'--app','app','--id','run','--strict'])).toBe(code)
|
|
32
|
+
expect(await runWeb(['runs',...args,'--app','app','--id','run'])).toBe(0)
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
test('wait reads the exact run and returns strict failure',async()=>{
|
|
36
|
+
globalThis.fetch=(async(url,init)=>{
|
|
37
|
+
if(init?.method==='POST')return reply({id:'exact-run'})
|
|
38
|
+
expect(new URL(String(url)).searchParams.get('id')).toBe('exact-run')
|
|
39
|
+
return reply({runs:[{id:'exact-run',status:'failed'}]})
|
|
40
|
+
}) as typeof fetch
|
|
41
|
+
expect(await runWeb(['run',...args,'--app','app','--id','check','--wait','--strict'])).toBe(1)
|
|
42
|
+
})
|
|
43
|
+
test('invalid mutation version and unscoped strict mode never reach transport',async()=>{
|
|
44
|
+
let calls=0;globalThis.fetch=(async()=>{calls++;return reply({})}) as typeof fetch
|
|
45
|
+
expect(await runWeb(['delete',...args,'--id','check','--version','NaN'])).toBe(2)
|
|
46
|
+
expect(await runWeb(['run',...args,'--id','check','--strict'])).toBe(2)
|
|
47
|
+
expect(calls).toBe(0)
|
|
48
|
+
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
|
|
2
2
|
import { createHash } from 'node:crypto'
|
|
3
|
-
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'
|
|
3
|
+
import { mkdtempSync, mkdirSync, rmSync, readFileSync, writeFileSync } from 'node:fs'
|
|
4
4
|
import { tmpdir } from 'node:os'
|
|
5
5
|
import { join } from 'node:path'
|
|
6
6
|
import { gunzipSync } from 'node:zlib'
|
|
@@ -42,7 +42,8 @@ describe('unified release upload', () => {
|
|
|
42
42
|
const bytes = gunzipSync(Buffer.from(await file.arrayBuffer()))
|
|
43
43
|
const kind = String(form.get('kind'))
|
|
44
44
|
if (kind === 'srcbundle') expect(inspectSourceArchive(bytes, 'app@1+7').files).toEqual(['src/a.ts'])
|
|
45
|
-
|
|
45
|
+
const contentHash = createHash('sha256').update(bytes).digest('hex')
|
|
46
|
+
uploaded.push({ kind, name: file.name.replace(/\.gz$/, ''), usable: true, contentHash, storageVerification: { integrity: 'verified', actualContentHash: contentHash, actualSizeBytes: bytes.length, usable: true } })
|
|
46
47
|
return reply({ id: String(uploaded.length), usable: true }, 201)
|
|
47
48
|
}
|
|
48
49
|
return reply({ release: 'app@1+7', known: uploaded.length > 0, artifacts: uploaded,
|
|
@@ -100,3 +101,77 @@ describe('unified release upload', () => {
|
|
|
100
101
|
})
|
|
101
102
|
|
|
102
103
|
})
|
|
104
|
+
|
|
105
|
+
test('expected project prevents doctor, upload and verification from accepting another project token', async () => {
|
|
106
|
+
writeFileSync(join(root, 'mapping.txt'), 'A -> a:\n')
|
|
107
|
+
const path = config({ mapping: ['mapping.txt'] })
|
|
108
|
+
const projectId = '31a8f496-faf3-4448-af1d-0118b7b5c8cd'
|
|
109
|
+
writeFileSync(path, JSON.stringify({ ...JSON.parse(readFileSync(path, 'utf8')), projectId }))
|
|
110
|
+
const calls: string[] = []
|
|
111
|
+
globalThis.fetch = (async (url) => {
|
|
112
|
+
calls.push(String(url))
|
|
113
|
+
return reply({ project: { id: '019fb8cd-8eed-7fa3-8611-7851e3b1f9ea', name: 'wrong' } })
|
|
114
|
+
}) as typeof fetch
|
|
115
|
+
for (const command of ['doctor', 'upload', 'verify'] as const) {
|
|
116
|
+
expect(await runWorkflow(command, ['--config', path, '--strict'])).toBe(1)
|
|
117
|
+
}
|
|
118
|
+
expect(calls).toEqual(Array(3).fill('https://upload.test/api/project'))
|
|
119
|
+
calls.length = 0
|
|
120
|
+
expect(await runWorkflow('upload', ['--config', path, '--dry-run'])).toBe(0)
|
|
121
|
+
expect(calls).toEqual([])
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
test('matching project is verified before artifact compatibility and upload', async () => {
|
|
125
|
+
const path = config()
|
|
126
|
+
const projectId = '31a8f496-faf3-4448-af1d-0118b7b5c8cd'
|
|
127
|
+
writeFileSync(path, JSON.stringify({ ...JSON.parse(readFileSync(path, 'utf8')), projectId }))
|
|
128
|
+
const calls: string[] = []
|
|
129
|
+
globalThis.fetch = (async (url) => {
|
|
130
|
+
calls.push(String(url))
|
|
131
|
+
return String(url).endsWith('/api/project')
|
|
132
|
+
? reply({ project: { id: projectId, name: 'home' } })
|
|
133
|
+
: reply({ release: 'app@1+7', known: false, artifacts: [], compatibility: { serverVersion: '5.1.17', artifactProtocol: 1, sourceBundleFormats: ['zip'], verification: ['sha256', 'format'] } })
|
|
134
|
+
}) as typeof fetch
|
|
135
|
+
expect(await runWorkflow('doctor', ['--config', path])).toBe(0)
|
|
136
|
+
expect(calls[0]).toBe('https://upload.test/api/project')
|
|
137
|
+
expect(calls).toHaveLength(2)
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
test('verification fails closed for stale metadata and corrupted or missing stored bytes', async () => {
|
|
142
|
+
writeFileSync(join(root, 'mapping.txt'), 'A -> a:\n')
|
|
143
|
+
const plan = prepareUploadPlan(config({ mapping: ['mapping.txt'] }))
|
|
144
|
+
const file = plan.files[0]!
|
|
145
|
+
const row = { kind: file.kind, name: file.name, contentHash: file.hash, usable: true }
|
|
146
|
+
for (const storageVerification of [undefined,
|
|
147
|
+
{ integrity: 'mismatch', actualContentHash: file.hash, actualSizeBytes: 0, usable: true },
|
|
148
|
+
{ integrity: 'unavailable' },
|
|
149
|
+
{ integrity: 'verified', actualContentHash: 'wrong', actualSizeBytes: file.bytes, usable: true },
|
|
150
|
+
]) {
|
|
151
|
+
globalThis.fetch = (async url => {
|
|
152
|
+
expect(String(url)).toEndWith('?verify=true')
|
|
153
|
+
return reply({ known: true, release: plan.release, artifacts: [{ ...row, storageVerification }] })
|
|
154
|
+
}) as typeof fetch
|
|
155
|
+
expect((await verifyUploadPlan(plan, 't'))[0]).toContain('stored bytes not verified')
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
test('strict upload preserves HTTP failure details even when verification also fails', async () => {
|
|
161
|
+
writeFileSync(join(root, 'mapping.txt'), 'A -> a:\n')
|
|
162
|
+
const path = config({ mapping: ['mapping.txt'] })
|
|
163
|
+
let posted = false
|
|
164
|
+
globalThis.fetch = (async (_url, init) => {
|
|
165
|
+
if (init?.method === 'POST') { posted = true; return reply({ error: 'upstream unavailable' }, 502) }
|
|
166
|
+
if (posted) return reply({ error: 'verification unavailable' }, 503)
|
|
167
|
+
return reply({ known: false, release: 'app@1+7', artifacts: [] })
|
|
168
|
+
}) as typeof fetch
|
|
169
|
+
const originalError = console.error, messages: string[] = []
|
|
170
|
+
console.error = (...args) => { messages.push(args.join(' ')) }
|
|
171
|
+
try { expect(await runWorkflow('upload', ['--config', path, '--strict'])).toBe(1) }
|
|
172
|
+
finally { console.error = originalError }
|
|
173
|
+
expect(messages.join('\n')).toContain('mapping.txt: 502')
|
|
174
|
+
expect(messages.join('\n')).toContain('upstream unavailable')
|
|
175
|
+
expect(messages.join('\n')).toContain('verification request failed: 503')
|
|
176
|
+
expect(messages.join('\n')).not.toContain('api-test')
|
|
177
|
+
})
|
package/src/artifacts.ts
CHANGED
|
@@ -31,6 +31,7 @@ export type ArtifactRow = {
|
|
|
31
31
|
* the check existed — "never looked at", not "looked at and
|
|
32
32
|
* fine". `false` means it stored and will symbolicate nothing. */
|
|
33
33
|
usable?: boolean | null
|
|
34
|
+
storageVerification?: { integrity: string; actualContentHash?: string; actualSizeBytes?: number; usable?: boolean | null }
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
export type ArtifactsResponse = {
|
|
@@ -55,10 +56,11 @@ export async function fetchArtifacts(opts: {
|
|
|
55
56
|
apiUrl: string
|
|
56
57
|
release: string
|
|
57
58
|
token: string
|
|
59
|
+
verify?: boolean
|
|
58
60
|
}): Promise<ArtifactsResponse> {
|
|
59
61
|
const url =
|
|
60
62
|
`${opts.apiUrl.replace(/\/+$/, '')}/v1/releases/` +
|
|
61
|
-
`${encodeURIComponent(opts.release)}/artifacts`
|
|
63
|
+
`${encodeURIComponent(opts.release)}/artifacts${opts.verify ? "?verify=true" : ""}`
|
|
62
64
|
const resp = await fetch(url, {
|
|
63
65
|
headers: { Authorization: `Bearer ${opts.token}` },
|
|
64
66
|
})
|
package/src/compatibility.ts
CHANGED
|
@@ -9,7 +9,7 @@ export function checkCompatibility(result: ArtifactsResponse, sourceZip: boolean
|
|
|
9
9
|
const info = result.compatibility
|
|
10
10
|
if (info === undefined) {
|
|
11
11
|
if (sourceZip) throw new Error('This server does not advertise source ZIP support. No files were uploaded. Upgrade the Sentori server to a build advertising artifact protocol 1 and sourceBundleFormats: ["zip"], then run sentori doctor. Existing CLI 1.5 pipelines may continue using legacy JSON sources.')
|
|
12
|
-
return 'Legacy artifact API: server capabilities are not advertised. Source maps, dSYM and mapping uploads remain available; verification
|
|
12
|
+
return 'Legacy artifact API: server capabilities are not advertised. Source maps, dSYM and mapping uploads remain available; verification requires a server that supplies fresh storageVerification proof; inventory metadata alone cannot pass.'
|
|
13
13
|
}
|
|
14
14
|
if (!info || typeof info.serverVersion !== 'string' || info.artifactProtocol !== 1
|
|
15
15
|
|| !Array.isArray(info.sourceBundleFormats) || !Array.isArray(info.verification)
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { runWeb, WEB_HELP } from './web.js'
|
|
2
3
|
import { parseArgs } from 'node:util'
|
|
3
4
|
import { runWorkflow, runSourcesPack, WORKFLOW_HELP } from './workflow.js'
|
|
4
5
|
import { checkCompatibility, CLI_VERSION } from './compatibility.js'
|
|
@@ -7,7 +8,7 @@ import { listApps, showProject } from './apps.js'
|
|
|
7
8
|
import {
|
|
8
9
|
fetchBundle,
|
|
9
10
|
formatIssueLine,
|
|
10
|
-
|
|
11
|
+
listIssuesPage,
|
|
11
12
|
noteIssue,
|
|
12
13
|
resolveIssue,
|
|
13
14
|
} from './issue.js'
|
|
@@ -27,7 +28,7 @@ import { reactNativeUpload } from './react-native.js'
|
|
|
27
28
|
import { fetchArtifacts } from './artifacts.js'
|
|
28
29
|
import { expandSourcemapPaths, uploadArtifact } from './upload.js'
|
|
29
30
|
|
|
30
|
-
const HELP = `${WORKFLOW_HELP}\n\nsentori — Sentori command-line interface
|
|
31
|
+
const HELP = `${WEB_HELP}\n${WORKFLOW_HELP}\n\nsentori — Sentori command-line interface
|
|
31
32
|
|
|
32
33
|
Symbolication artifacts (api-scope token; failures NEVER block your
|
|
33
34
|
build — exit 0 with a friendly note unless --strict):
|
|
@@ -57,7 +58,7 @@ CI triage (the same /api surface an AI agent uses):
|
|
|
57
58
|
sentori project show [--json] project selected by the API token
|
|
58
59
|
sentori app list [--json] apps within that project
|
|
59
60
|
sentori issue list [--status open] [--kind error] [--app <uuid>]
|
|
60
|
-
[--platform <platform>] [--environment <env>] [--release <release>] [--json]
|
|
61
|
+
[--platform <platform>] [--environment <env>] [--release <release>] [--limit 50] [--offset 0] [--json]
|
|
61
62
|
sentori issue resolve <issue-id> [--in-release <r>]
|
|
62
63
|
sentori issue note <issue-id> --body "fixed in abc123"
|
|
63
64
|
sentori issue bundle <issue-id>
|
|
@@ -465,7 +466,7 @@ async function cmdIssueList(argv: string[]): Promise<number> {
|
|
|
465
466
|
try {
|
|
466
467
|
parsed = parseArgs({
|
|
467
468
|
args: argv,
|
|
468
|
-
options: { ...ISSUE_OPTS, kind: { type: 'string' }, status: { type: 'string' }, app: { type: 'string' }, platform: { type: 'string' }, environment: { type: 'string' }, release: { type: 'string' }, json: { type: 'boolean' } },
|
|
469
|
+
options: { ...ISSUE_OPTS, kind: { type: 'string' }, status: { type: 'string' }, app: { type: 'string' }, platform: { type: 'string' }, environment: { type: 'string' }, release: { type: 'string' }, limit: { type: 'string' }, offset: { type: 'string' }, json: { type: 'boolean' } },
|
|
469
470
|
})
|
|
470
471
|
} catch (e) {
|
|
471
472
|
console.error(`error: ${(e as Error).message}\n${HELP}`)
|
|
@@ -478,15 +479,18 @@ async function cmdIssueList(argv: string[]): Promise<number> {
|
|
|
478
479
|
const cfg = parseApiCfg(parsed.values)
|
|
479
480
|
if (!cfg) return 2
|
|
480
481
|
try {
|
|
481
|
-
const
|
|
482
|
+
const page = await listIssuesPage(cfg, {
|
|
482
483
|
kind: parsed.values.kind as string | undefined,
|
|
483
484
|
status: (parsed.values.status as string | undefined) ?? 'open',
|
|
484
485
|
app: parsed.values.app,
|
|
485
486
|
platform: parsed.values.platform,
|
|
486
487
|
environment: parsed.values.environment,
|
|
487
488
|
release: parsed.values.release,
|
|
489
|
+
limit: parsed.values.limit === undefined ? undefined : Number(parsed.values.limit),
|
|
490
|
+
offset: parsed.values.offset === undefined ? undefined : Number(parsed.values.offset),
|
|
488
491
|
})
|
|
489
|
-
if (parsed.values.json) { console.log(JSON.stringify(
|
|
492
|
+
if (parsed.values.json) { console.log(JSON.stringify(page, null, 2)); return 0 }
|
|
493
|
+
const rows = page.issues
|
|
490
494
|
if (rows.length === 0) {
|
|
491
495
|
console.log('(no matching issues)')
|
|
492
496
|
return 0
|
|
@@ -721,6 +725,7 @@ async function main(argv: string[]): Promise<number> {
|
|
|
721
725
|
return 0
|
|
722
726
|
}
|
|
723
727
|
const [a, b, ...rest] = argv
|
|
728
|
+
if (a === 'web') return runWeb(argv.slice(1))
|
|
724
729
|
if (a === 'project' && b === 'show') return cmdProjectApps(rest, false)
|
|
725
730
|
if (a === 'app' && b === 'list') return cmdProjectApps(rest, true)
|
|
726
731
|
if (a === 'init') return runWorkflow('init', argv.slice(1))
|