@pugi/sdk 0.1.0-alpha.10

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.
@@ -0,0 +1,185 @@
1
+ import { z } from 'zod';
2
+ import { permissionDecisionSchema } from './permission-rules.js';
3
+ import { subagentIsolationSchema, subagentRoleSchema } from './subagent-contracts.js';
4
+ export const auditEventBaseSchema = z.object({
5
+ id: z.string().min(1),
6
+ sessionId: z.string().min(1),
7
+ timestamp: z.string().datetime(),
8
+ });
9
+ export const toolCallEventSchema = auditEventBaseSchema.extend({
10
+ type: z.literal('tool_call'),
11
+ tool: z.string().min(1),
12
+ inputSummary: z.string().min(1),
13
+ permissionDecision: permissionDecisionSchema.optional(),
14
+ });
15
+ export const toolResultEventSchema = auditEventBaseSchema.extend({
16
+ type: z.literal('tool_result'),
17
+ toolCallId: z.string().min(1),
18
+ status: z.enum(['success', 'error', 'cancelled']),
19
+ outputSummary: z.string().min(1),
20
+ outputRef: z.string().min(1).optional(),
21
+ });
22
+ export const fileMutationEventSchema = auditEventBaseSchema.extend({
23
+ type: z.literal('file_mutation'),
24
+ toolCallId: z.string().min(1),
25
+ path: z.string().min(1),
26
+ operation: z.enum(['create', 'update', 'delete', 'move']),
27
+ beforeBlob: z.string().min(1).optional(),
28
+ afterBlob: z.string().min(1).optional(),
29
+ beforeHash: z.string().min(1).optional(),
30
+ afterHash: z.string().min(1).optional(),
31
+ diffRef: z.string().min(1).optional(),
32
+ });
33
+ export const sessionEventSchema = auditEventBaseSchema.extend({
34
+ type: z.literal('session'),
35
+ name: z.enum(['created', 'command_started', 'command_completed']),
36
+ command: z.string().min(1).optional(),
37
+ status: z.enum(['success', 'error']).optional(),
38
+ });
39
+ const hookEventName = z.enum([
40
+ 'SessionStart',
41
+ 'UserPromptSubmit',
42
+ 'PreToolUse',
43
+ 'PermissionRequest',
44
+ 'PostToolUse',
45
+ 'PostToolUseFailure',
46
+ 'Stop',
47
+ 'SessionEnd',
48
+ ]);
49
+ export const hookInvokedEventSchema = auditEventBaseSchema.extend({
50
+ type: z.literal('hook.invoked'),
51
+ event: hookEventName,
52
+ matchSummary: z.string().min(1),
53
+ runSummary: z.string().min(1),
54
+ });
55
+ export const hookResultEventSchema = auditEventBaseSchema.extend({
56
+ type: z.literal('hook.result'),
57
+ event: hookEventName,
58
+ ok: z.boolean(),
59
+ exitCode: z.number().int(),
60
+ elapsedMs: z.number().int().nonnegative(),
61
+ stdoutLen: z.number().int().nonnegative(),
62
+ stderrLen: z.number().int().nonnegative(),
63
+ });
64
+ export const hookSkippedEventSchema = auditEventBaseSchema.extend({
65
+ type: z.literal('hook.skipped'),
66
+ event: hookEventName,
67
+ reason: z.enum(['dedup', 'no-match', 'untrusted-project']),
68
+ });
69
+ export const compactionTierSchema = z.enum([
70
+ 'microcompact',
71
+ 'cached_microcompact',
72
+ 'reactive_summary',
73
+ 'session_memory',
74
+ 'full_compaction',
75
+ 'reset',
76
+ ]);
77
+ export const compactionStartedEventSchema = auditEventBaseSchema.extend({
78
+ type: z.literal('compaction.started'),
79
+ tier: compactionTierSchema,
80
+ trigger: z.object({
81
+ budgetUsed: z.number().nonnegative(),
82
+ budgetMax: z.number().positive(),
83
+ }),
84
+ });
85
+ export const compactionCompletedEventSchema = auditEventBaseSchema.extend({
86
+ type: z.literal('compaction.completed'),
87
+ tier: compactionTierSchema,
88
+ bytesReclaimed: z.number().nonnegative(),
89
+ newContextSize: z.number().nonnegative(),
90
+ artifactsCreated: z.array(z.object({
91
+ sha256: z.string().min(1),
92
+ size: z.number().nonnegative(),
93
+ producedBy: z.string().min(1),
94
+ })),
95
+ });
96
+ export const compactionSkippedEventSchema = auditEventBaseSchema.extend({
97
+ type: z.literal('compaction.skipped'),
98
+ tier: compactionTierSchema,
99
+ reason: z.string(),
100
+ });
101
+ export const compactionInvariantViolatedEventSchema = auditEventBaseSchema.extend({
102
+ type: z.literal('compaction.invariant_violated'),
103
+ invariant: z.enum([
104
+ 'secrets-never-summarize',
105
+ 'open-decisions-preserved',
106
+ 'artifact-refs-resolvable',
107
+ 'static-hash-unchanged',
108
+ ]),
109
+ evidence: z.string(),
110
+ artifactRef: z.string().min(1).optional(),
111
+ });
112
+ /**
113
+ * Subagent lifecycle events. Extended in Sprint a5.4 (M1 gap remediation D)
114
+ * so dispatcher activity surfaces in the same `.pugi/events.jsonl` audit
115
+ * stream as tool calls, hooks, and compactions. The dispatcher
116
+ * implementation lives in `apps/pugi-cli/src/core/subagents/dispatcher.ts`;
117
+ * the wire-level shape and role/isolation enums are defined in
118
+ * `subagent-contracts.ts` and re-used here so a single source of truth
119
+ * governs validation on both sides of the boundary.
120
+ */
121
+ export const subagentSpawnedAuditEventSchema = auditEventBaseSchema.extend({
122
+ type: z.literal('subagent.spawned'),
123
+ taskId: z.string().min(1),
124
+ role: subagentRoleSchema,
125
+ personaSlug: z.string().min(1),
126
+ parentSessionId: z.string().min(1),
127
+ isolation: subagentIsolationSchema,
128
+ });
129
+ export const subagentToolCallAuditEventSchema = auditEventBaseSchema.extend({
130
+ type: z.literal('subagent.tool_call'),
131
+ taskId: z.string().min(1),
132
+ role: subagentRoleSchema,
133
+ personaSlug: z.string().min(1),
134
+ toolName: z.string().min(1),
135
+ toolCallId: z.string().min(1),
136
+ });
137
+ export const subagentCompletedAuditEventSchema = auditEventBaseSchema.extend({
138
+ type: z.literal('subagent.completed'),
139
+ taskId: z.string().min(1),
140
+ role: subagentRoleSchema,
141
+ personaSlug: z.string().min(1),
142
+ toolCallCount: z.number().int().nonnegative(),
143
+ tokensIn: z.number().int().nonnegative(),
144
+ tokensOut: z.number().int().nonnegative(),
145
+ durationMs: z.number().int().nonnegative(),
146
+ });
147
+ export const subagentBlockedAuditEventSchema = auditEventBaseSchema.extend({
148
+ type: z.literal('subagent.blocked'),
149
+ taskId: z.string().min(1),
150
+ role: subagentRoleSchema,
151
+ personaSlug: z.string().min(1),
152
+ reason: z.enum([
153
+ 'budget_exhausted',
154
+ 'plan_mode_refused',
155
+ 'permission_denied',
156
+ 'tool_unavailable',
157
+ ]),
158
+ detail: z.string().min(1),
159
+ });
160
+ export const subagentFailedAuditEventSchema = auditEventBaseSchema.extend({
161
+ type: z.literal('subagent.failed'),
162
+ taskId: z.string().min(1),
163
+ role: subagentRoleSchema,
164
+ personaSlug: z.string().min(1),
165
+ error: z.string().min(1),
166
+ });
167
+ export const auditEventSchema = z.discriminatedUnion('type', [
168
+ sessionEventSchema,
169
+ toolCallEventSchema,
170
+ toolResultEventSchema,
171
+ fileMutationEventSchema,
172
+ hookInvokedEventSchema,
173
+ hookResultEventSchema,
174
+ hookSkippedEventSchema,
175
+ compactionStartedEventSchema,
176
+ compactionCompletedEventSchema,
177
+ compactionSkippedEventSchema,
178
+ compactionInvariantViolatedEventSchema,
179
+ subagentSpawnedAuditEventSchema,
180
+ subagentToolCallAuditEventSchema,
181
+ subagentCompletedAuditEventSchema,
182
+ subagentBlockedAuditEventSchema,
183
+ subagentFailedAuditEventSchema,
184
+ ]);
185
+ //# sourceMappingURL=audit-trace.js.map
@@ -0,0 +1,98 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * OAuth 2.0 Device Authorization Grant (RFC 8628) wire contracts.
4
+ *
5
+ * The CLI hits two endpoints:
6
+ * POST /api/auth/device/start
7
+ * POST /api/auth/device/poll
8
+ *
9
+ * The cabinet UI hits two more (JWT-authenticated):
10
+ * POST /api/auth/device/approve
11
+ * POST /api/auth/device/deny
12
+ *
13
+ * Field naming follows RFC 8628 (snake_case) on the wire, not the
14
+ * camelCase server type used by Prisma — Zod schemas below are the
15
+ * canonical wire shape. CLI consumers parse the response with these
16
+ * schemas to defeat a hostile or buggy runtime returning malformed
17
+ * fields.
18
+ */
19
+ export declare const pugiDeviceStartRequestSchema: z.ZodObject<{
20
+ clientId: z.ZodLiteral<"pugi-cli">;
21
+ }, "strip", z.ZodTypeAny, {
22
+ clientId: "pugi-cli";
23
+ }, {
24
+ clientId: "pugi-cli";
25
+ }>;
26
+ export type PugiDeviceStartRequest = z.infer<typeof pugiDeviceStartRequestSchema>;
27
+ export declare const pugiDeviceStartResponseSchema: z.ZodObject<{
28
+ device_code: z.ZodString;
29
+ user_code: z.ZodString;
30
+ verification_uri: z.ZodString;
31
+ verification_uri_complete: z.ZodString;
32
+ expires_in: z.ZodNumber;
33
+ interval: z.ZodNumber;
34
+ }, "strip", z.ZodTypeAny, {
35
+ device_code: string;
36
+ user_code: string;
37
+ verification_uri: string;
38
+ verification_uri_complete: string;
39
+ expires_in: number;
40
+ interval: number;
41
+ }, {
42
+ device_code: string;
43
+ user_code: string;
44
+ verification_uri: string;
45
+ verification_uri_complete: string;
46
+ expires_in: number;
47
+ interval: number;
48
+ }>;
49
+ export type PugiDeviceStartResponse = z.infer<typeof pugiDeviceStartResponseSchema>;
50
+ export declare const pugiDevicePollRequestSchema: z.ZodObject<{
51
+ deviceCode: z.ZodString;
52
+ }, "strip", z.ZodTypeAny, {
53
+ deviceCode: string;
54
+ }, {
55
+ deviceCode: string;
56
+ }>;
57
+ export type PugiDevicePollRequest = z.infer<typeof pugiDevicePollRequestSchema>;
58
+ export declare const pugiDevicePollStatusSchema: z.ZodEnum<["pending", "authorized", "denied", "expired", "redeemed"]>;
59
+ export type PugiDevicePollStatus = z.infer<typeof pugiDevicePollStatusSchema>;
60
+ export declare const pugiDevicePollResponseSchema: z.ZodDiscriminatedUnion<"status", [z.ZodObject<{
61
+ status: z.ZodLiteral<"authorized">;
62
+ access_token: z.ZodString;
63
+ token_type: z.ZodLiteral<"Bearer">;
64
+ }, "strip", z.ZodTypeAny, {
65
+ status: "authorized";
66
+ access_token: string;
67
+ token_type: "Bearer";
68
+ }, {
69
+ status: "authorized";
70
+ access_token: string;
71
+ token_type: "Bearer";
72
+ }>, z.ZodObject<{
73
+ status: z.ZodLiteral<"pending">;
74
+ }, "strip", z.ZodTypeAny, {
75
+ status: "pending";
76
+ }, {
77
+ status: "pending";
78
+ }>, z.ZodObject<{
79
+ status: z.ZodLiteral<"denied">;
80
+ }, "strip", z.ZodTypeAny, {
81
+ status: "denied";
82
+ }, {
83
+ status: "denied";
84
+ }>, z.ZodObject<{
85
+ status: z.ZodLiteral<"expired">;
86
+ }, "strip", z.ZodTypeAny, {
87
+ status: "expired";
88
+ }, {
89
+ status: "expired";
90
+ }>, z.ZodObject<{
91
+ status: z.ZodLiteral<"redeemed">;
92
+ }, "strip", z.ZodTypeAny, {
93
+ status: "redeemed";
94
+ }, {
95
+ status: "redeemed";
96
+ }>]>;
97
+ export type PugiDevicePollResponse = z.infer<typeof pugiDevicePollResponseSchema>;
98
+ //# sourceMappingURL=device-flow.d.ts.map
@@ -0,0 +1,55 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * OAuth 2.0 Device Authorization Grant (RFC 8628) wire contracts.
4
+ *
5
+ * The CLI hits two endpoints:
6
+ * POST /api/auth/device/start
7
+ * POST /api/auth/device/poll
8
+ *
9
+ * The cabinet UI hits two more (JWT-authenticated):
10
+ * POST /api/auth/device/approve
11
+ * POST /api/auth/device/deny
12
+ *
13
+ * Field naming follows RFC 8628 (snake_case) on the wire, not the
14
+ * camelCase server type used by Prisma — Zod schemas below are the
15
+ * canonical wire shape. CLI consumers parse the response with these
16
+ * schemas to defeat a hostile or buggy runtime returning malformed
17
+ * fields.
18
+ */
19
+ export const pugiDeviceStartRequestSchema = z.object({
20
+ clientId: z.literal('pugi-cli'),
21
+ });
22
+ export const pugiDeviceStartResponseSchema = z.object({
23
+ device_code: z.string().length(64),
24
+ user_code: z.string().min(8).max(16),
25
+ verification_uri: z.string().url(),
26
+ verification_uri_complete: z.string().url(),
27
+ // Cap `expires_in` at 1 hour so a hostile or misconfigured runtime
28
+ // cannot trap the CLI in a year-long poll loop by returning a huge
29
+ // expiration. The server today uses 10 min; this is just the upper
30
+ // bound the SDK trusts.
31
+ expires_in: z.number().int().positive().max(3600),
32
+ interval: z.number().int().min(1).max(60),
33
+ });
34
+ export const pugiDevicePollRequestSchema = z.object({
35
+ deviceCode: z.string().min(32).max(128),
36
+ });
37
+ export const pugiDevicePollStatusSchema = z.enum([
38
+ 'pending',
39
+ 'authorized',
40
+ 'denied',
41
+ 'expired',
42
+ 'redeemed',
43
+ ]);
44
+ export const pugiDevicePollResponseSchema = z.discriminatedUnion('status', [
45
+ z.object({
46
+ status: z.literal('authorized'),
47
+ access_token: z.string().min(1),
48
+ token_type: z.literal('Bearer'),
49
+ }),
50
+ z.object({ status: z.literal('pending') }),
51
+ z.object({ status: z.literal('denied') }),
52
+ z.object({ status: z.literal('expired') }),
53
+ z.object({ status: z.literal('redeemed') }),
54
+ ]);
55
+ //# sourceMappingURL=device-flow.js.map