@jetcrab/pi-desk-sdk 0.0.0-stage → 1.0.1-dev.9001

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,104 @@
1
+ import { z } from 'zod';
2
+ export declare const CapabilityKeySchema: z.ZodString;
3
+ export declare const CapabilityRuleSchema: z.ZodObject<{
4
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
5
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
6
+ }, z.core.$strict>;
7
+ export declare const CapabilityOptionSchema: z.ZodObject<{
8
+ value: z.ZodString;
9
+ label: z.ZodOptional<z.ZodString>;
10
+ description: z.ZodOptional<z.ZodString>;
11
+ }, z.core.$strict>;
12
+ export declare const CapabilityDeclarationSchema: z.ZodObject<{
13
+ label: z.ZodString;
14
+ options: z.ZodArray<z.ZodObject<{
15
+ value: z.ZodString;
16
+ label: z.ZodOptional<z.ZodString>;
17
+ description: z.ZodOptional<z.ZodString>;
18
+ }, z.core.$strict>>;
19
+ }, z.core.$strict>;
20
+ export declare const CapabilityDeclarationsSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
21
+ label: z.ZodString;
22
+ options: z.ZodArray<z.ZodObject<{
23
+ value: z.ZodString;
24
+ label: z.ZodOptional<z.ZodString>;
25
+ description: z.ZodOptional<z.ZodString>;
26
+ }, z.core.$strict>>;
27
+ }, z.core.$strict>>;
28
+ export declare const CapabilityModeKeySchema: z.ZodString;
29
+ export declare const CapabilityModeSchema: z.ZodObject<{
30
+ name: z.ZodString;
31
+ tools: z.ZodOptional<z.ZodObject<{
32
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
33
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
34
+ }, z.core.$strict>>;
35
+ skills: z.ZodOptional<z.ZodObject<{
36
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
37
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
38
+ }, z.core.$strict>>;
39
+ plugins: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
40
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
41
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
42
+ }, z.core.$strict>>>>;
43
+ }, z.core.$strict>;
44
+ export declare const CapabilityModesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
45
+ name: z.ZodString;
46
+ tools: z.ZodOptional<z.ZodObject<{
47
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
48
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
49
+ }, z.core.$strict>>;
50
+ skills: z.ZodOptional<z.ZodObject<{
51
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
52
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
53
+ }, z.core.$strict>>;
54
+ plugins: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
55
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
56
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
57
+ }, z.core.$strict>>>>;
58
+ }, z.core.$strict>>;
59
+ export declare const CapabilityModeNamesSchema: z.ZodRecord<z.ZodString, z.ZodString>;
60
+ export declare const CapabilityCatalogSchema: z.ZodObject<{
61
+ tools: z.ZodArray<z.ZodObject<{
62
+ value: z.ZodString;
63
+ label: z.ZodOptional<z.ZodString>;
64
+ description: z.ZodOptional<z.ZodString>;
65
+ }, z.core.$strict>>;
66
+ skills: z.ZodArray<z.ZodObject<{
67
+ value: z.ZodString;
68
+ label: z.ZodOptional<z.ZodString>;
69
+ description: z.ZodOptional<z.ZodString>;
70
+ }, z.core.$strict>>;
71
+ plugins: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodObject<{
72
+ label: z.ZodString;
73
+ options: z.ZodArray<z.ZodObject<{
74
+ value: z.ZodString;
75
+ label: z.ZodOptional<z.ZodString>;
76
+ description: z.ZodOptional<z.ZodString>;
77
+ }, z.core.$strict>>;
78
+ }, z.core.$strict>>>;
79
+ }, z.core.$strict>;
80
+ export declare const SessionCapabilityRulesSchema: z.ZodObject<{
81
+ tools: z.ZodObject<{
82
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
83
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
84
+ }, z.core.$strict>;
85
+ skills: z.ZodObject<{
86
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
87
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
88
+ }, z.core.$strict>;
89
+ capabilities: z.ZodRecord<z.ZodString, z.ZodObject<{
90
+ allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
91
+ deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
92
+ }, z.core.$strict>>;
93
+ }, z.core.$strict>;
94
+ export type CapabilityMode = z.infer<typeof CapabilityModeSchema>;
95
+ export type CapabilityModes = z.infer<typeof CapabilityModesSchema>;
96
+ export type CapabilityModeNames = z.infer<typeof CapabilityModeNamesSchema>;
97
+ export type CapabilityCatalog = z.infer<typeof CapabilityCatalogSchema>;
98
+ export type CapabilityRule = z.infer<typeof CapabilityRuleSchema>;
99
+ export type CapabilityOption = z.infer<typeof CapabilityOptionSchema>;
100
+ export type CapabilityDeclaration = z.infer<typeof CapabilityDeclarationSchema>;
101
+ export type CapabilityDeclarations = z.infer<typeof CapabilityDeclarationsSchema>;
102
+ export type SessionCapabilityRules = z.infer<typeof SessionCapabilityRulesSchema>;
103
+ /** Names are matched independently of discovery; a missing allowlist adds no restriction. */
104
+ export declare function isCapabilityAllowed(rule: CapabilityRule | undefined, value: string): boolean;
@@ -0,0 +1,89 @@
1
+ import { z } from 'zod';
2
+ export const CapabilityKeySchema = z
3
+ .string()
4
+ .min(1)
5
+ .max(64)
6
+ .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
7
+ const CapabilityPatternSchema = z.string().trim().min(1).max(256);
8
+ export const CapabilityRuleSchema = z
9
+ .object({
10
+ allow: z.array(CapabilityPatternSchema).max(5000).optional(),
11
+ deny: z.array(CapabilityPatternSchema).max(5000).optional()
12
+ })
13
+ .strict();
14
+ export const CapabilityOptionSchema = z
15
+ .object({
16
+ value: z.string().trim().min(1).max(256),
17
+ label: z.string().trim().min(1).max(120).optional(),
18
+ description: z.string().trim().max(1000).optional()
19
+ })
20
+ .strict();
21
+ export const CapabilityDeclarationSchema = z
22
+ .object({
23
+ label: z.string().trim().min(1).max(120),
24
+ options: z.array(CapabilityOptionSchema).max(5000)
25
+ })
26
+ .strict();
27
+ export const CapabilityDeclarationsSchema = z.record(CapabilityKeySchema, CapabilityDeclarationSchema);
28
+ export const CapabilityModeKeySchema = z.string().min(1).max(64);
29
+ export const CapabilityModeSchema = z
30
+ .object({
31
+ name: z.string().trim().min(1).max(64),
32
+ tools: CapabilityRuleSchema.optional(),
33
+ skills: CapabilityRuleSchema.optional(),
34
+ plugins: z
35
+ .record(CapabilityKeySchema, z.record(CapabilityKeySchema, CapabilityRuleSchema))
36
+ .optional()
37
+ })
38
+ .strict();
39
+ export const CapabilityModesSchema = z
40
+ .record(CapabilityModeKeySchema, CapabilityModeSchema)
41
+ .refine((modes) => Object.keys(modes).length <= 100, '最多保存 100 个能力模式')
42
+ .refine((modes) => new Set(Object.values(modes).map((mode) => mode.name)).size === Object.keys(modes).length, '模式名称不能重复');
43
+ export const CapabilityModeNamesSchema = z.record(CapabilityModeKeySchema, CapabilityModeSchema.shape.name);
44
+ export const CapabilityCatalogSchema = z
45
+ .object({
46
+ tools: z.array(CapabilityOptionSchema),
47
+ skills: z.array(CapabilityOptionSchema),
48
+ plugins: z.record(CapabilityKeySchema, CapabilityDeclarationsSchema)
49
+ })
50
+ .strict();
51
+ export const SessionCapabilityRulesSchema = z
52
+ .object({
53
+ tools: CapabilityRuleSchema,
54
+ skills: CapabilityRuleSchema,
55
+ capabilities: z.record(CapabilityKeySchema, CapabilityRuleSchema)
56
+ })
57
+ .strict();
58
+ function matchesCapability(pattern, value) {
59
+ let patternIndex = 0;
60
+ let valueIndex = 0;
61
+ let starIndex = -1;
62
+ let retryIndex = 0;
63
+ while (valueIndex < value.length) {
64
+ if (pattern[patternIndex] === '*') {
65
+ starIndex = patternIndex++;
66
+ retryIndex = valueIndex;
67
+ }
68
+ else if (pattern[patternIndex] === value[valueIndex]) {
69
+ patternIndex += 1;
70
+ valueIndex += 1;
71
+ }
72
+ else if (starIndex >= 0) {
73
+ patternIndex = starIndex + 1;
74
+ valueIndex = ++retryIndex;
75
+ }
76
+ else {
77
+ return false;
78
+ }
79
+ }
80
+ while (pattern[patternIndex] === '*')
81
+ patternIndex += 1;
82
+ return patternIndex === pattern.length;
83
+ }
84
+ /** Names are matched independently of discovery; a missing allowlist adds no restriction. */
85
+ export function isCapabilityAllowed(rule, value) {
86
+ return ((rule?.allow === undefined ||
87
+ rule.allow.some((pattern) => matchesCapability(pattern, value))) &&
88
+ !rule?.deny?.some((pattern) => matchesCapability(pattern, value)));
89
+ }
@@ -0,0 +1,137 @@
1
+ import type { CapabilityDeclarations } from './capabilities.js';
2
+ import type { HostSettings } from './settings.js';
3
+ export type { HostRegion, HostSettings, HostSettingsSnapshot } from './settings.js';
4
+ import { type PluginDisposer, type PluginJsonObject, type PluginJsonValue, type PluginNotificationLevel, type PluginSource, type PluginWorkSession } from './shared.ts';
5
+ export type { BrowserBuiltinIconName, BrowserContributionIcon, PluginDisposer, PluginJsonObject, PluginJsonValue, PluginNotificationLevel, PluginSource, PluginWorkSession } from './shared.js';
6
+ export interface GlobalPluginMethodContext {
7
+ readonly signal: AbortSignal;
8
+ }
9
+ export type PluginCapabilityLoader = (context: GlobalPluginMethodContext) => CapabilityDeclarations | Promise<CapabilityDeclarations>;
10
+ export type GlobalPluginMethodHandler = (input: PluginJsonObject, context: GlobalPluginMethodContext) => Promise<PluginJsonObject>;
11
+ export interface GlobalPluginFacade {
12
+ readonly name: string;
13
+ registerMethod(method: string, execute: GlobalPluginMethodHandler): () => void;
14
+ }
15
+ export interface GlobalPluginAPI {
16
+ bindPlugin(pluginName: string): GlobalPluginFacade;
17
+ }
18
+ export type GlobalPluginDisposer = PluginDisposer;
19
+ export type GlobalPluginFactory = (api: GlobalPluginAPI) => void | GlobalPluginDisposer | Promise<void | GlobalPluginDisposer>;
20
+ export type PluginPushTarget = {
21
+ scope: 'global';
22
+ } | {
23
+ scope: 'session';
24
+ source: PluginSource;
25
+ };
26
+ export interface PluginPushMessage {
27
+ pluginName: string;
28
+ target: PluginPushTarget;
29
+ event: string;
30
+ data: PluginJsonObject;
31
+ }
32
+ export interface PiDeskWorkSessionCapability {
33
+ listWorkSessions(): Promise<readonly PluginWorkSession[]>;
34
+ }
35
+ export interface PiDeskPluginHost {
36
+ readonly settings: HostSettings;
37
+ readonly workSessions: PiDeskWorkSessionCapability;
38
+ }
39
+ export interface PluginNotificationEventInput {
40
+ name: string;
41
+ data: PluginJsonObject;
42
+ }
43
+ export interface PluginNotificationPublishInput {
44
+ level: PluginNotificationLevel;
45
+ title: string;
46
+ description?: string;
47
+ event?: PluginNotificationEventInput;
48
+ }
49
+ export interface PluginNotificationChanges {
50
+ level?: PluginNotificationLevel;
51
+ title?: string;
52
+ description?: string | null;
53
+ }
54
+ export interface PiDeskPluginNotifications {
55
+ publish(input: PluginNotificationPublishInput): string;
56
+ update(notificationId: string, changes: PluginNotificationChanges): void;
57
+ delete(notificationId: string): void;
58
+ }
59
+ export type PluginMessageProjectionStage = 'temporary' | 'update' | 'final' | 'durable';
60
+ export interface PluginNativeImageMetadata {
61
+ mimeType: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif';
62
+ width: number;
63
+ height: number;
64
+ }
65
+ export type PluginNativePiMessage = {
66
+ kind: 'user';
67
+ text: string;
68
+ images: readonly PluginNativeImageMetadata[];
69
+ } | {
70
+ kind: 'assistant';
71
+ text: string;
72
+ thinking: string;
73
+ stopReason: string | null;
74
+ } | {
75
+ kind: 'tool';
76
+ toolName: string;
77
+ toolCallId: string;
78
+ arguments: PluginJsonObject;
79
+ partialResult: PluginJsonValue;
80
+ result: PluginJsonValue;
81
+ isError: boolean;
82
+ } | {
83
+ kind: 'bash';
84
+ command: string;
85
+ output: string;
86
+ exitCode: number | null;
87
+ cancelled: boolean;
88
+ truncated: boolean;
89
+ } | {
90
+ kind: 'custom';
91
+ customType: string;
92
+ content: string;
93
+ details: PluginJsonValue;
94
+ };
95
+ export interface PluginMessageProjectionResult {
96
+ viewKey: string;
97
+ summary: PluginJsonObject;
98
+ detail: PluginJsonObject | null;
99
+ }
100
+ export interface PluginMessageDeclarationInput {
101
+ source: PluginSource;
102
+ stage: PluginMessageProjectionStage;
103
+ message: PluginNativePiMessage;
104
+ raw: unknown;
105
+ defaultProjection: PluginMessageProjectionResult;
106
+ }
107
+ export interface PluginMessageDeclaration {
108
+ priority: number;
109
+ match(input: PluginMessageDeclarationInput): boolean;
110
+ project(input: PluginMessageDeclarationInput): PluginMessageProjectionResult;
111
+ }
112
+ export interface PiDeskPluginFacade {
113
+ readonly name: string;
114
+ readonly host: PiDeskPluginHost;
115
+ readonly notifications: PiDeskPluginNotifications;
116
+ setState(state: PluginJsonObject | null): void;
117
+ registerMethod(method: string, execute: GlobalPluginMethodHandler): PluginDisposer;
118
+ registerBrowserEntry(relativePath: string): PluginDisposer;
119
+ declareCapabilities(load: PluginCapabilityLoader): PluginDisposer;
120
+ declareMessage(declarationName: string, declaration: PluginMessageDeclaration): PluginDisposer;
121
+ pushGlobal(event: string, data: PluginJsonObject): void;
122
+ pushSession(source: PluginSource, event: string, data: PluginJsonObject): void;
123
+ }
124
+ export interface PiDeskPluginReloadContext {
125
+ readonly signal: AbortSignal;
126
+ }
127
+ export interface PiDeskPluginLifecycle {
128
+ beforeReload?(context: PiDeskPluginReloadContext): void | Promise<void>;
129
+ dispose?: PluginDisposer;
130
+ }
131
+ export type PiDeskPluginSetupResult = void | PluginDisposer | PiDeskPluginLifecycle;
132
+ export interface PiDeskPluginDefinition {
133
+ readonly name: string;
134
+ setup(plugin: PiDeskPluginFacade): PiDeskPluginSetupResult | Promise<PiDeskPluginSetupResult>;
135
+ }
136
+ export type PiDeskPluginFactory = PiDeskPluginDefinition;
137
+ export declare function definePiDeskPlugin(definition: PiDeskPluginDefinition): PiDeskPluginDefinition;
package/dist/entry.js ADDED
@@ -0,0 +1,11 @@
1
+ import { normalizePluginIdentifier } from "./shared.js";
2
+ export function definePiDeskPlugin(definition) {
3
+ if (!definition || typeof definition !== 'object') {
4
+ throw new Error('Pi Desk Plugin definition must be an object');
5
+ }
6
+ const name = normalizePluginIdentifier(definition.name, 'pluginName');
7
+ if (typeof definition.setup !== 'function') {
8
+ throw new Error('Pi Desk Plugin setup must be a function');
9
+ }
10
+ return Object.freeze({ name, setup: definition.setup });
11
+ }
@@ -0,0 +1,8 @@
1
+ export type PluginMethodErrorCode = 400 | 404 | 409;
2
+ export declare class PluginMethodError extends Error {
3
+ readonly code: PluginMethodErrorCode;
4
+ constructor(code: PluginMethodErrorCode, message: string);
5
+ }
6
+ export declare function isPluginMethodError(value: unknown): value is Error & {
7
+ readonly code: PluginMethodErrorCode;
8
+ };
package/dist/errors.js ADDED
@@ -0,0 +1,14 @@
1
+ export class PluginMethodError extends Error {
2
+ code;
3
+ constructor(code, message) {
4
+ super(message);
5
+ this.name = 'PiDeskPluginMethodError';
6
+ this.code = code;
7
+ }
8
+ }
9
+ export function isPluginMethodError(value) {
10
+ if (!(value instanceof Error) || value.name !== 'PiDeskPluginMethodError')
11
+ return false;
12
+ const code = value.code;
13
+ return code === 400 || code === 404 || code === 409;
14
+ }