@agentdock/wire 0.0.70 → 0.0.72
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/dist/activityPreferences.d.ts.map +1 -0
- package/dist/activityPreferences.js +2 -1
- package/dist/activityPreferences.js.map +1 -0
- package/dist/agentCapabilities.d.ts.map +1 -0
- package/dist/agentCapabilities.js +199 -1
- package/dist/agentCapabilities.js.map +1 -0
- package/dist/agentCommonEnv.d.ts.map +1 -0
- package/dist/agentCommonEnv.js +20 -1
- package/dist/agentCommonEnv.js.map +1 -0
- package/dist/agentInstallGuide.d.ts.map +1 -0
- package/dist/agentInstallGuide.js +81 -1
- package/dist/agentInstallGuide.js.map +1 -0
- package/dist/bgTask.d.ts.map +1 -0
- package/dist/bgTask.js +128 -1
- package/dist/bgTask.js.map +1 -0
- package/dist/checkpointSchemas.d.ts.map +1 -0
- package/dist/checkpointSchemas.js +46 -1
- package/dist/checkpointSchemas.js.map +1 -0
- package/dist/controlLevel.d.ts.map +1 -0
- package/dist/controlLevel.js +11 -1
- package/dist/controlLevel.js.map +1 -0
- package/dist/edition.d.ts.map +1 -0
- package/dist/edition.js +13 -1
- package/dist/edition.js.map +1 -0
- package/dist/envelope.d.ts.map +1 -0
- package/dist/envelope.js +77 -1
- package/dist/envelope.js.map +1 -0
- package/dist/errorMessage.d.ts.map +1 -0
- package/dist/errorMessage.js +6 -1
- package/dist/errorMessage.js.map +1 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +107 -1
- package/dist/events.js.map +1 -0
- package/dist/features.d.ts.map +1 -0
- package/dist/features.js +123 -1
- package/dist/features.js.map +1 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/feedback.js +61 -1
- package/dist/feedback.js.map +1 -0
- package/dist/fileWhitelist.d.ts.map +1 -0
- package/dist/fileWhitelist.js +189 -1
- package/dist/fileWhitelist.js.map +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +73 -1
- package/dist/index.js.map +1 -0
- package/dist/interactionEvents.d.ts.map +1 -0
- package/dist/interactionEvents.js +111 -1
- package/dist/interactionEvents.js.map +1 -0
- package/dist/legacyProtocol.d.ts.map +1 -0
- package/dist/legacyProtocol.js +30 -1
- package/dist/legacyProtocol.js.map +1 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +28 -1
- package/dist/license.js.map +1 -0
- package/dist/machine.d.ts.map +1 -0
- package/dist/machine.js +66 -1
- package/dist/machine.js.map +1 -0
- package/dist/messageMeta.d.ts.map +1 -0
- package/dist/messageMeta.js +60 -1
- package/dist/messageMeta.js.map +1 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +35 -1
- package/dist/messages.js.map +1 -0
- package/dist/ops.d.ts.map +1 -0
- package/dist/ops.js +74 -1
- package/dist/ops.js.map +1 -0
- package/dist/pairing.d.ts.map +1 -0
- package/dist/pairing.js +150 -1
- package/dist/pairing.js.map +1 -0
- package/dist/permissionSubject.d.ts.map +1 -0
- package/dist/permissionSubject.js +68 -1
- package/dist/permissionSubject.js.map +1 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +7 -1
- package/dist/protocol.js.map +1 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +269 -1
- package/dist/rpc.js.map +1 -0
- package/dist/scheduledTasks.d.ts.map +1 -0
- package/dist/scheduledTasks.js +188 -1
- package/dist/scheduledTasks.js.map +1 -0
- package/dist/semver.d.ts.map +1 -0
- package/dist/semver.js +60 -1
- package/dist/semver.js.map +1 -0
- package/dist/sessionResult.d.ts.map +1 -0
- package/dist/sessionResult.js +23 -1
- package/dist/sessionResult.js.map +1 -0
- package/dist/socketEvents.d.ts.map +1 -0
- package/dist/socketEvents.js +55 -1
- package/dist/socketEvents.js.map +1 -0
- package/dist/spawnError.d.ts.map +1 -0
- package/dist/spawnError.js +31 -1
- package/dist/spawnError.js.map +1 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +117 -1
- package/dist/stats.js.map +1 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +99 -1
- package/dist/sync.js.map +1 -0
- package/dist/taskResult.d.ts.map +1 -0
- package/dist/taskResult.js +113 -1
- package/dist/taskResult.js.map +1 -0
- package/dist/telemetry.d.ts +9 -9
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +115 -1
- package/dist/telemetry.js.map +1 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +2 -1
- package/dist/utils.js.map +1 -0
- package/package.json +1 -1
package/dist/envelope.js
CHANGED
|
@@ -1 +1,77 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Session envelope schema.
|
|
3
|
+
*
|
|
4
|
+
* Wraps a SessionEvent with metadata (id, time, role, turn, subagent).
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { isCuid } from '@paralleldrive/cuid2';
|
|
8
|
+
import { createId } from './utils.js';
|
|
9
|
+
import { SessionEventSchema } from './events.js';
|
|
10
|
+
export const SessionRoleSchema = z.enum(['user', 'agent']);
|
|
11
|
+
export const SessionEnvelopeSchema = z
|
|
12
|
+
.object({
|
|
13
|
+
id: z.string(),
|
|
14
|
+
time: z.number(),
|
|
15
|
+
role: SessionRoleSchema,
|
|
16
|
+
turn: z.string().optional(),
|
|
17
|
+
subagent: z
|
|
18
|
+
.string()
|
|
19
|
+
.refine((value) => isCuid(value), { message: 'subagent must be a cuid2 value' })
|
|
20
|
+
.optional(),
|
|
21
|
+
/** Claude CLI message UUID — used for precise conversation rollback. */
|
|
22
|
+
messageUuid: z.string().optional(),
|
|
23
|
+
/** Tool call ID — routes child events (e.g. bg-task:completed) to the parent card. */
|
|
24
|
+
toolCallId: z.string().optional(),
|
|
25
|
+
ev: SessionEventSchema,
|
|
26
|
+
})
|
|
27
|
+
.superRefine((envelope, ctx) => {
|
|
28
|
+
if (envelope.ev.t === 'service' && envelope.role !== 'agent') {
|
|
29
|
+
ctx.addIssue({
|
|
30
|
+
code: z.ZodIssueCode.custom,
|
|
31
|
+
message: 'service events must use role "agent"',
|
|
32
|
+
path: ['role'],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
if ((envelope.ev.t === 'start' || envelope.ev.t === 'stop') && envelope.role !== 'agent') {
|
|
36
|
+
ctx.addIssue({
|
|
37
|
+
code: z.ZodIssueCode.custom,
|
|
38
|
+
message: `${envelope.ev.t} events must use role "agent"`,
|
|
39
|
+
path: ['role'],
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if ((envelope.ev.t === 'question' || envelope.ev.t === 'permission-request') &&
|
|
43
|
+
envelope.role !== 'agent') {
|
|
44
|
+
ctx.addIssue({
|
|
45
|
+
code: z.ZodIssueCode.custom,
|
|
46
|
+
message: `${envelope.ev.t} events must use role "agent"`,
|
|
47
|
+
path: ['role'],
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (envelope.ev.t === 'answer' && envelope.role !== 'user') {
|
|
51
|
+
ctx.addIssue({
|
|
52
|
+
code: z.ZodIssueCode.custom,
|
|
53
|
+
message: 'answer events must use role "user"',
|
|
54
|
+
path: ['role'],
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* Create a SessionEnvelope by direct construction (hot path).
|
|
60
|
+
*
|
|
61
|
+
* Skips Zod `.parse()` for performance — the discriminated union with
|
|
62
|
+
* 14 variants + 4 superRefine checks is expensive on every streaming token.
|
|
63
|
+
* Validation still happens at ingress boundaries (server API handlers).
|
|
64
|
+
*/
|
|
65
|
+
export function createEnvelope(role, ev, opts = {}) {
|
|
66
|
+
return {
|
|
67
|
+
id: opts.id ?? createId(),
|
|
68
|
+
time: opts.time ?? Date.now(),
|
|
69
|
+
role,
|
|
70
|
+
ev,
|
|
71
|
+
...(opts.turn ? { turn: opts.turn } : {}),
|
|
72
|
+
...(opts.subagent ? { subagent: opts.subagent } : {}),
|
|
73
|
+
...(opts.messageUuid ? { messageUuid: opts.messageUuid } : {}),
|
|
74
|
+
...(opts.toolCallId ? { toolCallId: opts.toolCallId } : {}),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorMessage.d.ts","sourceRoot":"","sources":["../src/errorMessage.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAGjD"}
|
package/dist/errorMessage.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorMessage.js","sourceRoot":"","sources":["../src/errorMessage.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC7C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYjC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;EAGpC,CAAC;AAEH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;EAO1C,CAAC;AAEH,eAAO,MAAM,6BAA6B;;;IAGxC,qDAAqD;;IAErD,mDAAmD;;;;;;;;;;;;EAEnD,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYjC,CAAC;AAEH,eAAO,MAAM,2BAA2B;;;;;;EAEtC,CAAC;AAEH,eAAO,MAAM,0BAA0B,iDAA+C,CAAC;AACvF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,8CAA8C;AAC9C,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;EAK1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;IAKpC,yEAAyE;;;;;;;;;;;;;;;;;;;;;;;;EAEzE,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;IAGlC,oEAAoE;;;;;;;;;;EAEpE,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;EAEjC,CAAC;AAEH,0DAA0D;AAC1D,eAAO,MAAM,uBAAuB;;IAElC,iCAAiC;;IAEjC,+DAA+D;;;;;;;;;;EAE/D,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAjE7B,qDAAqD;;IAErD,mDAAmD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAuCnD,yEAAyE;;;;;;;;;;;;;;;;;;;;;;;;;;;IAOzE,oEAAoE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAWpE,iCAAiC;;IAEjC,+DAA+D;;;;;;;;;;IAmB/D,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAG9D,OAAO,EACL,0BAA0B,EAC1B,mCAAmC,EACnC,wBAAwB,EACxB,oCAAoC,EACpC,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,oBAAoB,EACpB,6BAA6B,EAC7B,kBAAkB,EAClB,8BAA8B,EAC9B,gBAAgB,EAChB,eAAe,GAChB,MAAM,wBAAwB,CAAC"}
|
package/dist/events.js
CHANGED
|
@@ -1 +1,107 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Session event schemas.
|
|
3
|
+
*
|
|
4
|
+
* Event types: text, service, tool-call-start, tool-call-end,
|
|
5
|
+
* file, turn-start, turn-end, start, stop.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { SessionQuestionEventSchema, SessionPermissionRequestEventSchema, SessionAnswerEventSchema, SessionPermissionResolvedEventSchema, } from './interactionEvents.js';
|
|
9
|
+
export const SessionTextEventSchema = z.object({
|
|
10
|
+
t: z.literal('text'),
|
|
11
|
+
text: z.string(),
|
|
12
|
+
thinking: z.boolean().optional(),
|
|
13
|
+
images: z
|
|
14
|
+
.array(z.object({
|
|
15
|
+
data: z.string(),
|
|
16
|
+
mediaType: z.string(),
|
|
17
|
+
}))
|
|
18
|
+
.optional(),
|
|
19
|
+
});
|
|
20
|
+
export const SessionServiceEventSchema = z.object({
|
|
21
|
+
t: z.literal('service'),
|
|
22
|
+
text: z.string(),
|
|
23
|
+
});
|
|
24
|
+
export const SessionToolCallStartEventSchema = z.object({
|
|
25
|
+
t: z.literal('tool-call-start'),
|
|
26
|
+
call: z.string(),
|
|
27
|
+
name: z.string(),
|
|
28
|
+
title: z.string(),
|
|
29
|
+
description: z.string(),
|
|
30
|
+
args: z.record(z.string(), z.unknown()),
|
|
31
|
+
});
|
|
32
|
+
export const SessionToolCallEndEventSchema = z.object({
|
|
33
|
+
t: z.literal('tool-call-end'),
|
|
34
|
+
call: z.string(),
|
|
35
|
+
/** Tool output text (may be truncated at source). */
|
|
36
|
+
result: z.string().optional(),
|
|
37
|
+
/** True when the tool returned an error result. */
|
|
38
|
+
error: z.boolean().optional(),
|
|
39
|
+
});
|
|
40
|
+
export const SessionFileEventSchema = z.object({
|
|
41
|
+
t: z.literal('file'),
|
|
42
|
+
ref: z.string(),
|
|
43
|
+
name: z.string(),
|
|
44
|
+
size: z.number(),
|
|
45
|
+
image: z
|
|
46
|
+
.object({
|
|
47
|
+
width: z.number(),
|
|
48
|
+
height: z.number(),
|
|
49
|
+
thumbhash: z.string(),
|
|
50
|
+
})
|
|
51
|
+
.optional(),
|
|
52
|
+
});
|
|
53
|
+
export const SessionTurnStartEventSchema = z.object({
|
|
54
|
+
t: z.literal('turn-start'),
|
|
55
|
+
});
|
|
56
|
+
export const SessionTurnEndStatusSchema = z.enum(['completed', 'failed', 'cancelled']);
|
|
57
|
+
/** Token usage stats reported at turn end. */
|
|
58
|
+
export const TurnUsageSchema = z.object({
|
|
59
|
+
inputTokens: z.number().int().nonnegative(),
|
|
60
|
+
outputTokens: z.number().int().nonnegative(),
|
|
61
|
+
cacheReadTokens: z.number().int().nonnegative().optional(),
|
|
62
|
+
cacheWriteTokens: z.number().int().nonnegative().optional(),
|
|
63
|
+
});
|
|
64
|
+
export const SessionTurnEndEventSchema = z.object({
|
|
65
|
+
t: z.literal('turn-end'),
|
|
66
|
+
status: SessionTurnEndStatusSchema,
|
|
67
|
+
usage: TurnUsageSchema.optional(),
|
|
68
|
+
model: z.string().optional(),
|
|
69
|
+
/** Wall-clock duration of the turn in milliseconds (Date.now() diff). */
|
|
70
|
+
durationMs: z.number().int().nonnegative().optional(),
|
|
71
|
+
});
|
|
72
|
+
export const SessionStartEventSchema = z.object({
|
|
73
|
+
t: z.literal('start'),
|
|
74
|
+
title: z.string().optional(),
|
|
75
|
+
/** Claude background task ID for cancellation (RFC-058 Phase 2). */
|
|
76
|
+
taskId: z.string().optional(),
|
|
77
|
+
});
|
|
78
|
+
export const SessionStopEventSchema = z.object({
|
|
79
|
+
t: z.literal('stop'),
|
|
80
|
+
});
|
|
81
|
+
/** User-sent image stored inline in envelope (base64). */
|
|
82
|
+
export const SessionImageEventSchema = z.object({
|
|
83
|
+
t: z.literal('image'),
|
|
84
|
+
/** Base64-encoded image data. */
|
|
85
|
+
data: z.string(),
|
|
86
|
+
/** MIME type: image/jpeg, image/png, image/gif, image/webp. */
|
|
87
|
+
mediaType: z.string(),
|
|
88
|
+
});
|
|
89
|
+
export const SessionEventSchema = z.discriminatedUnion('t', [
|
|
90
|
+
SessionTextEventSchema,
|
|
91
|
+
SessionServiceEventSchema,
|
|
92
|
+
SessionToolCallStartEventSchema,
|
|
93
|
+
SessionToolCallEndEventSchema,
|
|
94
|
+
SessionFileEventSchema,
|
|
95
|
+
SessionTurnStartEventSchema,
|
|
96
|
+
SessionTurnEndEventSchema,
|
|
97
|
+
SessionStartEventSchema,
|
|
98
|
+
SessionStopEventSchema,
|
|
99
|
+
SessionQuestionEventSchema,
|
|
100
|
+
SessionPermissionRequestEventSchema,
|
|
101
|
+
SessionAnswerEventSchema,
|
|
102
|
+
SessionPermissionResolvedEventSchema,
|
|
103
|
+
SessionImageEventSchema,
|
|
104
|
+
]);
|
|
105
|
+
// Re-export interaction event schemas for convenience
|
|
106
|
+
export { SessionQuestionEventSchema, SessionPermissionRequestEventSchema, SessionAnswerEventSchema, SessionPermissionResolvedEventSchema, PermissionActionSchema, ImageAttachmentSchema, } from './interactionEvents.js';
|
|
107
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":"AASA,sFAAsF;AACtF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AAED,sFAAsF;AACtF,MAAM,WAAW,iBAAiB;IAChC,iCAAiC;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,uDAAuD;IACvD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IAC7C,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACxD;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,iBAAiB,EAiD/C,CAAC;AAEX;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,OAAO,CAKT;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,SAAS,MAAM,EAAE,EACnC,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,OAAO,CAYT;AAED,8DAA8D;AAC9D,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,MAAM,GAAG,SAAS,CAGpB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,gBAAgB,EAAE,SAAS,MAAM,EAAE,EACnC,aAAa,CAAC,EAAE,MAAM,GACrB,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,EAAE,CAkBjD"}
|
package/dist/features.js
CHANGED
|
@@ -1 +1,123 @@
|
|
|
1
|
-
|
|
1
|
+
/* Feature availability layer (RFC-035).
|
|
2
|
+
*
|
|
3
|
+
* Maps high-level features to the RPC methods they require.
|
|
4
|
+
* Used by web to determine which features a daemon supports
|
|
5
|
+
* based on the methods it has registered.
|
|
6
|
+
*/
|
|
7
|
+
import { satisfiesMin } from './semver.js';
|
|
8
|
+
/**
|
|
9
|
+
* Registry of all known features and their RPC dependencies.
|
|
10
|
+
* Add new entries here when introducing features that require new daemon RPC methods.
|
|
11
|
+
*/
|
|
12
|
+
export const FEATURE_REGISTRY = [
|
|
13
|
+
{
|
|
14
|
+
id: 'agent-settings',
|
|
15
|
+
requiredMethods: ['get-agent-settings', 'set-agent-settings'],
|
|
16
|
+
sinceVersion: '0.0.4',
|
|
17
|
+
subFeatures: [{ id: 'startup-scripts', sinceVersion: '0.0.30' }],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'labs-settings',
|
|
21
|
+
requiredMethods: ['get-labs-settings', 'set-labs-settings'],
|
|
22
|
+
sinceVersion: '0.0.12',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'history-sync',
|
|
26
|
+
requiredMethods: ['backfill-history-session'],
|
|
27
|
+
sinceVersion: '0.0.12',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: 'check-path',
|
|
31
|
+
requiredMethods: ['check-path'],
|
|
32
|
+
sinceVersion: '0.0.7',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'remote-upgrade',
|
|
36
|
+
requiredMethods: ['trigger-upgrade'],
|
|
37
|
+
sinceVersion: '0.0.30',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 'checkpoint',
|
|
41
|
+
requiredMethods: ['checkpoint-list', 'checkpoint-diff', 'checkpoint-rollback'],
|
|
42
|
+
sinceVersion: '0.0.30',
|
|
43
|
+
subFeatures: [{ id: 'conversation-rollback', sinceVersion: '0.0.32' }],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 'scheduled-tasks',
|
|
47
|
+
requiredMethods: ['spawn-session'],
|
|
48
|
+
sinceVersion: '0.0.35',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'auto-upgrade-daemon',
|
|
52
|
+
requiredMethods: ['set-auto-upgrade-daemon'],
|
|
53
|
+
sinceVersion: '0.0.31',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'file-upload',
|
|
57
|
+
requiredMethods: ['file-relay-receive'],
|
|
58
|
+
sinceVersion: '0.0.36',
|
|
59
|
+
edition: 'personal',
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
/**
|
|
63
|
+
* Check whether a specific feature is available given the set of supported methods.
|
|
64
|
+
* A feature is available when ALL its required methods are present.
|
|
65
|
+
*/
|
|
66
|
+
export function isFeatureAvailable(featureId, supportedMethods) {
|
|
67
|
+
const feature = FEATURE_REGISTRY.find((f) => f.id === featureId);
|
|
68
|
+
if (!feature)
|
|
69
|
+
return false;
|
|
70
|
+
const methodSet = new Set(supportedMethods);
|
|
71
|
+
return feature.requiredMethods.every((m) => methodSet.has(m));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Check whether a sub-feature is available given supported methods and daemon version.
|
|
75
|
+
* Requires the parent feature to be available AND the daemon version to satisfy the sub-feature minimum.
|
|
76
|
+
*/
|
|
77
|
+
export function isSubFeatureAvailable(featureId, subFeatureId, supportedMethods, daemonVersion) {
|
|
78
|
+
const feature = FEATURE_REGISTRY.find((f) => f.id === featureId);
|
|
79
|
+
if (!feature)
|
|
80
|
+
return false;
|
|
81
|
+
if (!isFeatureAvailable(featureId, supportedMethods))
|
|
82
|
+
return false;
|
|
83
|
+
const sub = feature.subFeatures?.find((s) => s.id === subFeatureId);
|
|
84
|
+
if (!sub)
|
|
85
|
+
return false;
|
|
86
|
+
if (!daemonVersion || !satisfiesMin(daemonVersion, sub.sinceVersion))
|
|
87
|
+
return false;
|
|
88
|
+
if (sub.requiredMethods) {
|
|
89
|
+
const methodSet = new Set(supportedMethods);
|
|
90
|
+
return sub.requiredMethods.every((m) => methodSet.has(m));
|
|
91
|
+
}
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
/** Look up the minimum version required for a sub-feature. */
|
|
95
|
+
export function getSubFeatureMinVersion(featureId, subFeatureId) {
|
|
96
|
+
const feature = FEATURE_REGISTRY.find((f) => f.id === featureId);
|
|
97
|
+
return feature?.subFeatures?.find((s) => s.id === subFeatureId)?.sinceVersion;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Return all features (and sub-features) that are NOT available.
|
|
101
|
+
* Sub-features are returned as "parentId/subId" when the parent is available
|
|
102
|
+
* but the daemon version is too low for the sub-feature.
|
|
103
|
+
*/
|
|
104
|
+
export function getUnavailableFeatures(supportedMethods, daemonVersion) {
|
|
105
|
+
const results = [];
|
|
106
|
+
const methodSet = new Set(supportedMethods);
|
|
107
|
+
for (const f of FEATURE_REGISTRY) {
|
|
108
|
+
if (!f.requiredMethods.every((m) => methodSet.has(m))) {
|
|
109
|
+
results.push({ id: f.id, sinceVersion: f.sinceVersion });
|
|
110
|
+
}
|
|
111
|
+
else if (f.subFeatures && daemonVersion) {
|
|
112
|
+
for (const sub of f.subFeatures) {
|
|
113
|
+
const versionLocked = !satisfiesMin(daemonVersion, sub.sinceVersion);
|
|
114
|
+
const methodsLocked = sub.requiredMethods != null && !sub.requiredMethods.every((m) => methodSet.has(m));
|
|
115
|
+
if (versionLocked || methodsLocked) {
|
|
116
|
+
results.push({ id: `${f.id}/${sub.id}`, sinceVersion: sub.sinceVersion });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return results;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=features.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features.js","sourceRoot":"","sources":["../src/features.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB,wCAAsC,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,oBAAoB,2CAAyC,CAAC;AAC3E,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,aAAa,4EAMxB,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,eAAO,MAAM,cAAc,gGAAgC,CAAC;AAE5D,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;EAK1B,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;IAQjC,6FAA6F;;;;;;;;;;;;;;;;;;;;;;EAI7F,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAShC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAnB3B,6FAA6F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuB7F,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA1B/B,6FAA6F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmC7F,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,eAAO,MAAM,oBAAoB;;;;;;;;;EAG/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
package/dist/feedback.js
CHANGED
|
@@ -1 +1,61 @@
|
|
|
1
|
-
|
|
1
|
+
// KNOWN-DEBT: feedback 模块导出类型零消费 + web 侧重复定义 (see docs/ops/KNOWN-DEBT.md)
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export const FeedbackTypeSchema = z.enum(['BUG', 'FEATURE', 'OTHER']);
|
|
4
|
+
export const FeedbackStatusSchema = z.enum(['UNREAD', 'READ', 'ARCHIVED']);
|
|
5
|
+
export const RunModeSchema = z.enum([
|
|
6
|
+
'web-session',
|
|
7
|
+
'cli-spawn',
|
|
8
|
+
'cli-run',
|
|
9
|
+
'scheduled',
|
|
10
|
+
'unknown',
|
|
11
|
+
]);
|
|
12
|
+
export const RunModesSchema = z.array(RunModeSchema).max(5);
|
|
13
|
+
export const BugFieldsSchema = z.object({
|
|
14
|
+
reproSteps: z.string().max(2000).optional(),
|
|
15
|
+
expectedBehavior: z.string().max(1000).optional(),
|
|
16
|
+
actualBehavior: z.string().max(1000).optional(),
|
|
17
|
+
errorMessages: z.string().max(2000).optional(),
|
|
18
|
+
});
|
|
19
|
+
export const SettingsSnapshotSchema = z.object({
|
|
20
|
+
browser: z
|
|
21
|
+
.object({
|
|
22
|
+
userAgent: z.string(),
|
|
23
|
+
viewport: z.string(),
|
|
24
|
+
language: z.string(),
|
|
25
|
+
})
|
|
26
|
+
.optional(),
|
|
27
|
+
/** Per-machine diagnostics: platform, arch, daemonVersion, availableAgents, agentCliPaths */
|
|
28
|
+
machines: z.record(z.string(), z.record(z.unknown())).optional(),
|
|
29
|
+
preferences: z.record(z.unknown()).optional(),
|
|
30
|
+
labs: z.record(z.unknown()).optional(),
|
|
31
|
+
});
|
|
32
|
+
export const MachineSnapshotSchema = z.object({
|
|
33
|
+
machineId: z.string(),
|
|
34
|
+
platform: z.string().optional(),
|
|
35
|
+
arch: z.string().optional(),
|
|
36
|
+
hostname: z.string().optional(),
|
|
37
|
+
daemonVersion: z.string().optional(),
|
|
38
|
+
availableAgents: z.array(z.string()).optional(),
|
|
39
|
+
agentVersions: z.record(z.string()).optional(),
|
|
40
|
+
nodeVersion: z.string().optional(),
|
|
41
|
+
});
|
|
42
|
+
export const DeviceInfoSchema = z.object({
|
|
43
|
+
machines: z.array(MachineSnapshotSchema).optional(),
|
|
44
|
+
appVersion: z.string().optional(),
|
|
45
|
+
settingsSnapshot: SettingsSnapshotSchema.optional(),
|
|
46
|
+
});
|
|
47
|
+
export const CreateFeedbackSchema = z.object({
|
|
48
|
+
type: FeedbackTypeSchema,
|
|
49
|
+
description: z.string().min(0).max(5000),
|
|
50
|
+
screenshots: z.array(z.string().max(700_000)).max(3).optional(),
|
|
51
|
+
deviceInfo: DeviceInfoSchema,
|
|
52
|
+
affectedMachineIds: z.array(z.string()).max(20).optional(),
|
|
53
|
+
affectedAgents: z.array(z.string()).max(10).optional(),
|
|
54
|
+
runModes: RunModesSchema.optional(),
|
|
55
|
+
bugFields: BugFieldsSchema.optional(),
|
|
56
|
+
});
|
|
57
|
+
export const UpdateFeedbackSchema = z.object({
|
|
58
|
+
status: z.enum(['READ', 'ARCHIVED']).optional(),
|
|
59
|
+
reply: z.string().min(1).max(5000).optional(),
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.js","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileWhitelist.d.ts","sourceRoot":"","sources":["../src/fileWhitelist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;AAYlE,eAAO,MAAM,SAAS,EAAE,SAAS,MAAM,EAWtC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,SAAS,MAAM,EAgBtC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,SAAS,MAAM,EAQrC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,SAAS,MAAM,EAQrC,CAAC;AAEF,6CAA6C;AAC7C,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAKzE,CAAC;AAEF,2DAA2D;AAC3D,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAS3C,CAAC;AAEH,oDAAoD;AACpD,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAKjD,CAAC;AASH;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CACpC,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAexE,CAAC;AAEF,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAMpE;AAsBD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAqBvE"}
|
package/dist/fileWhitelist.js
CHANGED
|
@@ -1 +1,189 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* File upload whitelist — single source of truth for personal-edition file
|
|
3
|
+
* upload validation, shared across web (PWA client), server (relay preflight),
|
|
4
|
+
* and daemon (receiver second-check).
|
|
5
|
+
*
|
|
6
|
+
* Contains ONLY isomorphic data + pure byte logic (no node:/DOM deps):
|
|
7
|
+
* - per-category extension lists and max sizes
|
|
8
|
+
* - blocked (executable) extensions
|
|
9
|
+
* - magic-byte signatures
|
|
10
|
+
* - category resolution + magic-byte verification over Uint8Array
|
|
11
|
+
*
|
|
12
|
+
* File reading differs per platform (File/FileReader on web, Buffer on
|
|
13
|
+
* server/daemon), so callers read the head bytes themselves and pass a
|
|
14
|
+
* Uint8Array in. Buffer is a Uint8Array subclass, so `verifyMagicBytes`
|
|
15
|
+
* works unchanged on both.
|
|
16
|
+
*/
|
|
17
|
+
/** All file categories in priority order (first match wins in resolveFileCategory). */
|
|
18
|
+
const FILE_CATEGORIES = ['text', 'document', 'code', 'image'];
|
|
19
|
+
export const TEXT_EXTS = [
|
|
20
|
+
'.txt',
|
|
21
|
+
'.md',
|
|
22
|
+
'.log',
|
|
23
|
+
'.csv',
|
|
24
|
+
'.json',
|
|
25
|
+
'.xml',
|
|
26
|
+
'.yaml',
|
|
27
|
+
'.yml',
|
|
28
|
+
'.toml',
|
|
29
|
+
'.env',
|
|
30
|
+
];
|
|
31
|
+
export const CODE_EXTS = [
|
|
32
|
+
'.ts',
|
|
33
|
+
'.tsx',
|
|
34
|
+
'.js',
|
|
35
|
+
'.jsx',
|
|
36
|
+
'.py',
|
|
37
|
+
'.rs',
|
|
38
|
+
'.go',
|
|
39
|
+
'.java',
|
|
40
|
+
'.c',
|
|
41
|
+
'.cpp',
|
|
42
|
+
'.h',
|
|
43
|
+
'.css',
|
|
44
|
+
'.html',
|
|
45
|
+
'.sql',
|
|
46
|
+
'.sh',
|
|
47
|
+
];
|
|
48
|
+
export const DOC_EXTS = [
|
|
49
|
+
'.pdf',
|
|
50
|
+
'.doc',
|
|
51
|
+
'.docx',
|
|
52
|
+
'.xls',
|
|
53
|
+
'.xlsx',
|
|
54
|
+
'.ppt',
|
|
55
|
+
'.pptx',
|
|
56
|
+
];
|
|
57
|
+
export const IMG_EXTS = [
|
|
58
|
+
'.png',
|
|
59
|
+
'.jpg',
|
|
60
|
+
'.jpeg',
|
|
61
|
+
'.gif',
|
|
62
|
+
'.webp',
|
|
63
|
+
'.svg',
|
|
64
|
+
'.bmp',
|
|
65
|
+
];
|
|
66
|
+
/** Per-category max upload size in bytes. */
|
|
67
|
+
export const FILE_CATEGORY_MAX_SIZE = {
|
|
68
|
+
text: 1 * 1024 * 1024, // 1 MB
|
|
69
|
+
document: 2 * 1024 * 1024, // 2 MB
|
|
70
|
+
code: 1 * 1024 * 1024, // 1 MB
|
|
71
|
+
image: 1 * 1024 * 1024, // 1 MB
|
|
72
|
+
};
|
|
73
|
+
/** Executable / dangerous extensions — always rejected. */
|
|
74
|
+
export const BLOCKED_EXTS = new Set([
|
|
75
|
+
'.exe',
|
|
76
|
+
'.bat',
|
|
77
|
+
'.cmd',
|
|
78
|
+
'.msi',
|
|
79
|
+
'.dmg',
|
|
80
|
+
'.app',
|
|
81
|
+
'.com',
|
|
82
|
+
'.scr',
|
|
83
|
+
]);
|
|
84
|
+
/** All allowed extensions across every category. */
|
|
85
|
+
export const ALLOWED_EXTENSIONS = new Set([
|
|
86
|
+
...TEXT_EXTS,
|
|
87
|
+
...CODE_EXTS,
|
|
88
|
+
...DOC_EXTS,
|
|
89
|
+
...IMG_EXTS,
|
|
90
|
+
]);
|
|
91
|
+
const CATEGORY_EXTS = {
|
|
92
|
+
text: TEXT_EXTS,
|
|
93
|
+
code: CODE_EXTS,
|
|
94
|
+
document: DOC_EXTS,
|
|
95
|
+
image: IMG_EXTS,
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Binary magic-byte signatures keyed by extension. `subSig` is checked at an
|
|
99
|
+
* offset immediately after `sig` (used by WEBP's RIFF...WEBP layout).
|
|
100
|
+
* Text-based formats (text/code/svg) are not here — they use UTF-8 validation.
|
|
101
|
+
*/
|
|
102
|
+
export const FILE_SIGNATURES = {
|
|
103
|
+
'.pdf': { sig: [0x25, 0x50, 0x44, 0x46, 0x2d] },
|
|
104
|
+
'.doc': { sig: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1] },
|
|
105
|
+
'.xls': { sig: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1] },
|
|
106
|
+
'.ppt': { sig: [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1] },
|
|
107
|
+
'.docx': { sig: [0x50, 0x4b, 0x03, 0x04] },
|
|
108
|
+
'.xlsx': { sig: [0x50, 0x4b, 0x03, 0x04] },
|
|
109
|
+
'.pptx': { sig: [0x50, 0x4b, 0x03, 0x04] },
|
|
110
|
+
'.png': { sig: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a] },
|
|
111
|
+
'.jpg': { sig: [0xff, 0xd8, 0xff] },
|
|
112
|
+
'.jpeg': { sig: [0xff, 0xd8, 0xff] },
|
|
113
|
+
'.gif': { sig: [0x47, 0x49, 0x46, 0x38] }, // GIF8
|
|
114
|
+
'.webp': { sig: [0x52, 0x49, 0x46, 0x46], subSigAt: 8, subSig: [0x57, 0x45, 0x42, 0x50] }, // RIFF....WEBP
|
|
115
|
+
'.bmp': { sig: [0x42, 0x4d] }, // BM
|
|
116
|
+
};
|
|
117
|
+
/** Lowercased extension (including leading dot) or '' if none. */
|
|
118
|
+
export function getFileExt(filename) {
|
|
119
|
+
const lastDot = filename.lastIndexOf('.');
|
|
120
|
+
return lastDot >= 0 ? filename.substring(lastDot).toLowerCase() : '';
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Resolve the whitelist category for an extension.
|
|
124
|
+
* Returns null for blocked, unknown, or extension-less files.
|
|
125
|
+
*/
|
|
126
|
+
export function resolveFileCategory(ext) {
|
|
127
|
+
if (ext === '' || BLOCKED_EXTS.has(ext))
|
|
128
|
+
return null;
|
|
129
|
+
for (const cat of FILE_CATEGORIES) {
|
|
130
|
+
if (CATEGORY_EXTS[cat].includes(ext))
|
|
131
|
+
return cat;
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
/** UTF-8 decode without throwing — returns null on invalid bytes. */
|
|
136
|
+
function tryUtf8Decode(bytes) {
|
|
137
|
+
try {
|
|
138
|
+
return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// SILENT-CATCH-OK: tryUtf8Decode returns null on decode failure, caller handles
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** True if the head bytes look like SVG (XML text starting with <?xml/<svg/<!DOCTYPE svg). */
|
|
146
|
+
function looksLikeSvg(head) {
|
|
147
|
+
const s = tryUtf8Decode(head.subarray(0, Math.min(head.length, 512)));
|
|
148
|
+
if (s === null)
|
|
149
|
+
return false;
|
|
150
|
+
const trimmed = (s.charCodeAt(0) === 0xfeff ? s.slice(1) : s).trimStart();
|
|
151
|
+
return (trimmed.startsWith('<?xml') || trimmed.startsWith('<svg') || trimmed.startsWith('<!DOCTYPE svg'));
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Verify head bytes match the expected type for `ext`.
|
|
155
|
+
* - text/code: valid UTF-8
|
|
156
|
+
* - svg: XML text sniff
|
|
157
|
+
* - binary formats: magic-byte signature (+ optional sub-signature)
|
|
158
|
+
*
|
|
159
|
+
* `ext` must already be lowercased (use getFileExt). Buffer is a Uint8Array
|
|
160
|
+
* subclass, so server/daemon can pass a Buffer directly.
|
|
161
|
+
*/
|
|
162
|
+
export function verifyMagicBytes(head, ext) {
|
|
163
|
+
if (TEXT_EXTS.includes(ext) || CODE_EXTS.includes(ext)) {
|
|
164
|
+
return tryUtf8Decode(head) !== null;
|
|
165
|
+
}
|
|
166
|
+
if (ext === '.svg') {
|
|
167
|
+
return looksLikeSvg(head);
|
|
168
|
+
}
|
|
169
|
+
const rule = FILE_SIGNATURES[ext];
|
|
170
|
+
if (!rule)
|
|
171
|
+
return false;
|
|
172
|
+
if (head.length < rule.sig.length)
|
|
173
|
+
return false;
|
|
174
|
+
for (let i = 0; i < rule.sig.length; i++) {
|
|
175
|
+
if (head[i] !== rule.sig[i])
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
if (rule.subSig) {
|
|
179
|
+
const offset = rule.subSigAt ?? rule.sig.length;
|
|
180
|
+
if (head.length < offset + rule.subSig.length)
|
|
181
|
+
return false;
|
|
182
|
+
for (let i = 0; i < rule.subSig.length; i++) {
|
|
183
|
+
if (head[offset + i] !== rule.subSig[i])
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=fileWhitelist.js.map
|