@serviceme/devtools-protocol 0.0.3

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/LICENSE.md ADDED
@@ -0,0 +1,46 @@
1
+ SERVICEME Protocol Package — Commercial License
2
+
3
+ Copyright (c) 2024 Medalsoft Technology Co., Ltd. All rights reserved.
4
+
5
+ This software and associated documentation files (the "Software") are proprietary
6
+ and confidential to Medalsoft Technology Co., Ltd. ("Medalsoft").
7
+
8
+ GRANT OF LICENSE
9
+ Medalsoft grants authorized users a non-exclusive, non-transferable, limited license
10
+ to use the Software solely for internal business purposes in connection with
11
+ Medalsoft's SERVICEME platform.
12
+
13
+ RESTRICTIONS
14
+ You may not, and may not permit others to:
15
+ 1. Copy, modify, merge, publish, distribute, sublicense, or sell copies of the Software;
16
+ 2. Reverse engineer, decompile, disassemble, or attempt to derive the source code;
17
+ 3. Remove or alter any proprietary notices, labels, or marks on the Software;
18
+ 4. Use the Software for any purpose other than as expressly authorized above;
19
+ 5. Transfer, assign, or sublicense your rights under this license to any third party.
20
+
21
+ INTELLECTUAL PROPERTY
22
+ The Software is protected by copyright laws and international treaties. Medalsoft
23
+ retains all intellectual property rights in and to the Software, including all
24
+ copyright, patent, trade secret, and other proprietary rights.
25
+
26
+ NO WARRANTY
27
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
28
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
29
+ PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
30
+
31
+ LIMITATION OF LIABILITY
32
+ IN NO EVENT SHALL MEDALSOFT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
33
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION WITH THIS
34
+ LICENSE OR THE USE OF THE SOFTWARE.
35
+
36
+ TERMINATION
37
+ This license is effective until terminated. It will terminate automatically if you
38
+ fail to comply with any term or condition. Upon termination, you must destroy all
39
+ copies of the Software in your possession.
40
+
41
+ GOVERNING LAW
42
+ This license shall be governed by and construed in accordance with the laws of
43
+ the People's Republic of China.
44
+
45
+ CONTACT
46
+ For licensing inquiries, contact: marketing@medalsoft.com
package/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # @serviceme/devtools-protocol
2
+
3
+ Shared protocol contracts and runtime validators for SERVICEME CLI, bridge communication, and extension integration boundaries.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @serviceme/devtools-protocol
9
+ ```
10
+
11
+ ## Build
12
+
13
+ ```bash
14
+ pnpm -F @serviceme/devtools-protocol run build
15
+ ```
16
+
17
+ ## Test
18
+
19
+ ```bash
20
+ pnpm -F @serviceme/devtools-protocol run test
21
+ ```
@@ -0,0 +1,159 @@
1
+ import type { ServicemeErrorDetails } from "./errors";
2
+ import type { AgentSessionStatus, OpenCodeAgentEvent, OpenCodeRuntimeOptions, OpenCodeServerState } from "./opencode";
3
+ export declare const SERVICEME_PROTOCOL_VERSION: 1;
4
+ export interface BridgeCapabilities {
5
+ bridge: true;
6
+ opencode: 1;
7
+ json: 1;
8
+ env: 1;
9
+ }
10
+ export declare function isBridgeCapabilities(value: unknown): value is BridgeCapabilities;
11
+ export interface BridgeMethodMap {
12
+ "system.hello": {
13
+ params: {
14
+ clientName: string;
15
+ clientVersion: string;
16
+ wantedCapabilities?: string[];
17
+ };
18
+ result: {
19
+ cliVersion: string;
20
+ protocolVersion: typeof SERVICEME_PROTOCOL_VERSION;
21
+ capabilities: BridgeCapabilities;
22
+ pid: number;
23
+ };
24
+ };
25
+ "system.ping": {
26
+ params: Record<string, never>;
27
+ result: {
28
+ now: string;
29
+ };
30
+ };
31
+ "system.shutdown": {
32
+ params: Record<string, never>;
33
+ result: {
34
+ shuttingDown: true;
35
+ };
36
+ };
37
+ "opencode.server.ensure": {
38
+ params: OpenCodeRuntimeOptions;
39
+ result: OpenCodeServerState;
40
+ };
41
+ "opencode.server.status": {
42
+ params: OpenCodeRuntimeOptions;
43
+ result: OpenCodeServerState;
44
+ };
45
+ "opencode.session.create": {
46
+ params: {
47
+ chatSessionId: string;
48
+ workspaceRoot?: string;
49
+ runtime?: OpenCodeRuntimeOptions;
50
+ };
51
+ result: {
52
+ sessionId: string;
53
+ title?: string;
54
+ status: AgentSessionStatus;
55
+ };
56
+ };
57
+ "opencode.session.prompt": {
58
+ params: {
59
+ sessionId: string;
60
+ promptId: string;
61
+ prompt: string;
62
+ workspaceRoot?: string;
63
+ runtime?: OpenCodeRuntimeOptions;
64
+ };
65
+ result: {
66
+ accepted: true;
67
+ sessionId: string;
68
+ promptId: string;
69
+ };
70
+ };
71
+ "opencode.session.status": {
72
+ params: {
73
+ sessionId: string;
74
+ workspaceRoot?: string;
75
+ };
76
+ result: {
77
+ sessionId: string;
78
+ status: AgentSessionStatus;
79
+ };
80
+ };
81
+ "opencode.session.abort": {
82
+ params: {
83
+ sessionId: string;
84
+ workspaceRoot?: string;
85
+ };
86
+ result: {
87
+ aborted: true;
88
+ sessionId: string;
89
+ };
90
+ };
91
+ "opencode.session.dispose": {
92
+ params: {
93
+ sessionId: string;
94
+ };
95
+ result: {
96
+ disposed: true;
97
+ sessionId: string;
98
+ };
99
+ };
100
+ }
101
+ export declare const BRIDGE_METHODS: readonly ["system.hello", "system.ping", "system.shutdown", "opencode.server.ensure", "opencode.server.status", "opencode.session.create", "opencode.session.prompt", "opencode.session.status", "opencode.session.abort", "opencode.session.dispose"];
102
+ export type BridgeMethod = keyof BridgeMethodMap;
103
+ export type BridgeParams<M extends BridgeMethod> = BridgeMethodMap[M]["params"];
104
+ export type BridgeResult<M extends BridgeMethod> = BridgeMethodMap[M]["result"];
105
+ export interface BridgeEventMap {
106
+ "opencode.session.event": {
107
+ sessionId: string;
108
+ promptId?: string;
109
+ payload: OpenCodeAgentEvent;
110
+ };
111
+ }
112
+ export declare const BRIDGE_EVENTS: readonly ["opencode.session.event"];
113
+ export type BridgeEventName = keyof BridgeEventMap;
114
+ export type BridgeEventParams<E extends BridgeEventName> = BridgeEventMap[E];
115
+ export interface BridgeRequest<M extends BridgeMethod = BridgeMethod> {
116
+ protocolVersion: typeof SERVICEME_PROTOCOL_VERSION;
117
+ kind: "request";
118
+ id: string;
119
+ method: M;
120
+ params: BridgeParams<M>;
121
+ }
122
+ export interface BridgeSuccessResponse<M extends BridgeMethod = BridgeMethod> {
123
+ protocolVersion: typeof SERVICEME_PROTOCOL_VERSION;
124
+ kind: "response";
125
+ id: string;
126
+ ok: true;
127
+ result: BridgeResult<M>;
128
+ }
129
+ export interface BridgeErrorResponse {
130
+ protocolVersion: typeof SERVICEME_PROTOCOL_VERSION;
131
+ kind: "response";
132
+ id: string;
133
+ ok: false;
134
+ error: ServicemeErrorDetails;
135
+ }
136
+ export type BridgeResponse<M extends BridgeMethod = BridgeMethod> = BridgeSuccessResponse<M> | BridgeErrorResponse;
137
+ export interface BridgeEvent<E extends BridgeEventName = BridgeEventName> {
138
+ protocolVersion: typeof SERVICEME_PROTOCOL_VERSION;
139
+ kind: "event";
140
+ event: E;
141
+ params: BridgeEventParams<E>;
142
+ }
143
+ export type BridgeMessage = BridgeRequest | BridgeResponse | BridgeEvent;
144
+ export declare function isSystemHelloResult(value: unknown): value is BridgeResult<"system.hello">;
145
+ export declare function isSystemPingResult(value: unknown): value is BridgeResult<"system.ping">;
146
+ export declare function isSystemShutdownResult(value: unknown): value is BridgeResult<"system.shutdown">;
147
+ export declare function isOpenCodeSessionCreateResult(value: unknown): value is BridgeResult<"opencode.session.create">;
148
+ export declare function isOpenCodeSessionPromptResult(value: unknown): value is BridgeResult<"opencode.session.prompt">;
149
+ export declare function isOpenCodeSessionStatusResult(value: unknown): value is BridgeResult<"opencode.session.status">;
150
+ export declare function isOpenCodeSessionAbortResult(value: unknown): value is BridgeResult<"opencode.session.abort">;
151
+ export declare function isOpenCodeSessionDisposeResult(value: unknown): value is BridgeResult<"opencode.session.dispose">;
152
+ export declare function getBridgeResultValidator(method: BridgeMethod): ((value: unknown) => boolean) | undefined;
153
+ export declare function isOpenCodeSessionEventParams(value: unknown): value is BridgeEventParams<"opencode.session.event">;
154
+ export declare function getBridgeEventParamsValidator(event: BridgeEventName): ((value: unknown) => boolean) | undefined;
155
+ export declare function isBridgeMethod(value: unknown): value is BridgeMethod;
156
+ export declare function isBridgeEventName(value: unknown): value is BridgeEventName;
157
+ export declare function isBridgeRequest(value: unknown): value is BridgeRequest;
158
+ export declare function isBridgeResponse(value: unknown): value is BridgeResponse;
159
+ export declare function isBridgeEvent(value: unknown): value is BridgeEvent;
package/dist/bridge.js ADDED
@@ -0,0 +1,139 @@
1
+ import { isAgentSessionStatus, isOpenCodeAgentEvent, isOpenCodeServerState } from "./opencode";
2
+ export const SERVICEME_PROTOCOL_VERSION = 1;
3
+ function isRecord(value) {
4
+ return typeof value === "object" && value !== null;
5
+ }
6
+ export function isBridgeCapabilities(value) {
7
+ return (isRecord(value) &&
8
+ value.bridge === true &&
9
+ value.opencode === 1 &&
10
+ value.json === 1 &&
11
+ value.env === 1);
12
+ }
13
+ export const BRIDGE_METHODS = [
14
+ "system.hello",
15
+ "system.ping",
16
+ "system.shutdown",
17
+ "opencode.server.ensure",
18
+ "opencode.server.status",
19
+ "opencode.session.create",
20
+ "opencode.session.prompt",
21
+ "opencode.session.status",
22
+ "opencode.session.abort",
23
+ "opencode.session.dispose",
24
+ ];
25
+ export const BRIDGE_EVENTS = ["opencode.session.event"];
26
+ export function isSystemHelloResult(value) {
27
+ return (isRecord(value) &&
28
+ typeof value.cliVersion === "string" &&
29
+ value.protocolVersion === SERVICEME_PROTOCOL_VERSION &&
30
+ isBridgeCapabilities(value.capabilities) &&
31
+ typeof value.pid === "number");
32
+ }
33
+ export function isSystemPingResult(value) {
34
+ return isRecord(value) && typeof value.now === "string";
35
+ }
36
+ export function isSystemShutdownResult(value) {
37
+ return isRecord(value) && value.shuttingDown === true;
38
+ }
39
+ export function isOpenCodeSessionCreateResult(value) {
40
+ return (isRecord(value) &&
41
+ typeof value.sessionId === "string" &&
42
+ (value.title === undefined || typeof value.title === "string") &&
43
+ isAgentSessionStatus(value.status));
44
+ }
45
+ export function isOpenCodeSessionPromptResult(value) {
46
+ return (isRecord(value) &&
47
+ value.accepted === true &&
48
+ typeof value.sessionId === "string" &&
49
+ typeof value.promptId === "string");
50
+ }
51
+ export function isOpenCodeSessionStatusResult(value) {
52
+ return (isRecord(value) && typeof value.sessionId === "string" && isAgentSessionStatus(value.status));
53
+ }
54
+ export function isOpenCodeSessionAbortResult(value) {
55
+ return isRecord(value) && value.aborted === true && typeof value.sessionId === "string";
56
+ }
57
+ export function isOpenCodeSessionDisposeResult(value) {
58
+ return isRecord(value) && value.disposed === true && typeof value.sessionId === "string";
59
+ }
60
+ export function getBridgeResultValidator(method) {
61
+ switch (method) {
62
+ case "system.hello":
63
+ return isSystemHelloResult;
64
+ case "system.ping":
65
+ return isSystemPingResult;
66
+ case "system.shutdown":
67
+ return isSystemShutdownResult;
68
+ case "opencode.server.ensure":
69
+ case "opencode.server.status":
70
+ return isOpenCodeServerState;
71
+ case "opencode.session.create":
72
+ return isOpenCodeSessionCreateResult;
73
+ case "opencode.session.prompt":
74
+ return isOpenCodeSessionPromptResult;
75
+ case "opencode.session.status":
76
+ return isOpenCodeSessionStatusResult;
77
+ case "opencode.session.abort":
78
+ return isOpenCodeSessionAbortResult;
79
+ case "opencode.session.dispose":
80
+ return isOpenCodeSessionDisposeResult;
81
+ default:
82
+ return undefined;
83
+ }
84
+ }
85
+ export function isOpenCodeSessionEventParams(value) {
86
+ return (isRecord(value) &&
87
+ typeof value.sessionId === "string" &&
88
+ (value.promptId === undefined || typeof value.promptId === "string") &&
89
+ isOpenCodeAgentEvent(value.payload));
90
+ }
91
+ export function getBridgeEventParamsValidator(event) {
92
+ switch (event) {
93
+ case "opencode.session.event":
94
+ return isOpenCodeSessionEventParams;
95
+ default:
96
+ return undefined;
97
+ }
98
+ }
99
+ export function isBridgeMethod(value) {
100
+ return typeof value === "string" && BRIDGE_METHODS.includes(value);
101
+ }
102
+ export function isBridgeEventName(value) {
103
+ return typeof value === "string" && BRIDGE_EVENTS.includes(value);
104
+ }
105
+ export function isBridgeRequest(value) {
106
+ if (!isRecord(value)) {
107
+ return false;
108
+ }
109
+ return (value.protocolVersion === SERVICEME_PROTOCOL_VERSION &&
110
+ value.kind === "request" &&
111
+ typeof value.id === "string" &&
112
+ isBridgeMethod(value.method) &&
113
+ "params" in value);
114
+ }
115
+ export function isBridgeResponse(value) {
116
+ if (!isRecord(value)) {
117
+ return false;
118
+ }
119
+ if (value.protocolVersion !== SERVICEME_PROTOCOL_VERSION ||
120
+ value.kind !== "response" ||
121
+ typeof value.id !== "string" ||
122
+ typeof value.ok !== "boolean") {
123
+ return false;
124
+ }
125
+ if (value.ok) {
126
+ return "result" in value;
127
+ }
128
+ return "error" in value;
129
+ }
130
+ export function isBridgeEvent(value) {
131
+ if (!isRecord(value)) {
132
+ return false;
133
+ }
134
+ return (value.protocolVersion === SERVICEME_PROTOCOL_VERSION &&
135
+ value.kind === "event" &&
136
+ isBridgeEventName(value.event) &&
137
+ "params" in value);
138
+ }
139
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type { ServicemeErrorDetails } from "./errors";
2
+ export declare const SERVICEME_CLI_SCHEMA_VERSION: 1;
3
+ export interface CliSuccess<T> {
4
+ schemaVersion: typeof SERVICEME_CLI_SCHEMA_VERSION;
5
+ ok: true;
6
+ data: T;
7
+ }
8
+ export interface CliFailure {
9
+ schemaVersion: typeof SERVICEME_CLI_SCHEMA_VERSION;
10
+ ok: false;
11
+ error: ServicemeErrorDetails;
12
+ }
13
+ export type CliEnvelope<T> = CliSuccess<T> | CliFailure;
14
+ export declare function createCliSuccess<T>(data: T): CliSuccess<T>;
15
+ export declare function createCliFailure(error: ServicemeErrorDetails): CliFailure;
16
+ export declare function isCliEnvelope(value: unknown): value is CliEnvelope<unknown>;
package/dist/cli.js ADDED
@@ -0,0 +1,31 @@
1
+ export const SERVICEME_CLI_SCHEMA_VERSION = 1;
2
+ function isRecord(value) {
3
+ return typeof value === "object" && value !== null;
4
+ }
5
+ export function createCliSuccess(data) {
6
+ return {
7
+ schemaVersion: SERVICEME_CLI_SCHEMA_VERSION,
8
+ ok: true,
9
+ data,
10
+ };
11
+ }
12
+ export function createCliFailure(error) {
13
+ return {
14
+ schemaVersion: SERVICEME_CLI_SCHEMA_VERSION,
15
+ ok: false,
16
+ error,
17
+ };
18
+ }
19
+ export function isCliEnvelope(value) {
20
+ if (!isRecord(value)) {
21
+ return false;
22
+ }
23
+ if (value.schemaVersion !== SERVICEME_CLI_SCHEMA_VERSION || typeof value.ok !== "boolean") {
24
+ return false;
25
+ }
26
+ if (value.ok) {
27
+ return "data" in value;
28
+ }
29
+ return "error" in value;
30
+ }
31
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAU,CAAC;AAgBvD,SAAS,QAAQ,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAI,IAAO;IAC1C,OAAO;QACN,aAAa,EAAE,4BAA4B;QAC3C,EAAE,EAAE,IAAI;QACR,IAAI;KACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IAC5D,OAAO;QACN,aAAa,EAAE,4BAA4B;QAC3C,EAAE,EAAE,KAAK;QACT,KAAK;KACL,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC3C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,KAAK,CAAC,aAAa,KAAK,4BAA4B,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC3F,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,MAAM,IAAI,KAAK,CAAC;IACxB,CAAC;IAED,OAAO,OAAO,IAAI,KAAK,CAAC;AACzB,CAAC"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export declare const KNOWN_ENVIRONMENT_TOOLS: readonly ["git", "node", "npm", "pnpm", "nvm", "nrm", "dotnet", "nuget"];
2
+ export type KnownEnvironmentTool = (typeof KNOWN_ENVIRONMENT_TOOLS)[number];
3
+ export interface ToolCheckResult {
4
+ installed: boolean;
5
+ version?: string;
6
+ path?: string;
7
+ error?: string;
8
+ }
9
+ export type EnvironmentCheckResult = Record<KnownEnvironmentTool, ToolCheckResult>;
10
+ export declare function isKnownEnvironmentTool(value: string): value is KnownEnvironmentTool;
11
+ export declare function isToolCheckResult(value: unknown): value is ToolCheckResult;
12
+ export declare function isEnvironmentCheckResult(value: unknown): value is EnvironmentCheckResult;
package/dist/env.js ADDED
@@ -0,0 +1,32 @@
1
+ export const KNOWN_ENVIRONMENT_TOOLS = [
2
+ "git",
3
+ "node",
4
+ "npm",
5
+ "pnpm",
6
+ "nvm",
7
+ "nrm",
8
+ "dotnet",
9
+ "nuget",
10
+ ];
11
+ function isRecord(value) {
12
+ return typeof value === "object" && value !== null;
13
+ }
14
+ export function isKnownEnvironmentTool(value) {
15
+ return KNOWN_ENVIRONMENT_TOOLS.includes(value);
16
+ }
17
+ export function isToolCheckResult(value) {
18
+ if (!isRecord(value)) {
19
+ return false;
20
+ }
21
+ return (typeof value.installed === "boolean" &&
22
+ (value.version === undefined || typeof value.version === "string") &&
23
+ (value.path === undefined || typeof value.path === "string") &&
24
+ (value.error === undefined || typeof value.error === "string"));
25
+ }
26
+ export function isEnvironmentCheckResult(value) {
27
+ if (!isRecord(value)) {
28
+ return false;
29
+ }
30
+ return KNOWN_ENVIRONMENT_TOOLS.every((tool) => isToolCheckResult(value[tool]));
31
+ }
32
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACtC,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,QAAQ;IACR,OAAO;CACE,CAAC;AAaX,SAAS,QAAQ,CAAC,KAAc;IAC/B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAa;IACnD,OAAO,uBAAuB,CAAC,QAAQ,CAAC,KAA6B,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC/C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACd,CAAC;IAED,OAAO,CACN,OAAO,KAAK,CAAC,SAAS,KAAK,SAAS;QACpC,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC;QAClE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;QAC5D,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAC9D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACtD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACd,CAAC;IAED,OAAO,uBAAuB,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC"}
@@ -0,0 +1,25 @@
1
+ export type ServicemeErrorCode = "protocol_mismatch" | "cli_not_found" | "cli_start_failed" | "command_timeout" | "request_cancelled" | "invalid_params" | "opencode_not_installed" | "opencode_startup_timeout" | "opencode_request_failed" | "opencode_backend_not_running" | "opencode_session_not_found" | "json_invalid_input" | "env_tool_not_found" | "internal_error";
2
+ export declare const SERVICEME_ERROR_CODES: readonly ["protocol_mismatch", "cli_not_found", "cli_start_failed", "command_timeout", "request_cancelled", "invalid_params", "opencode_not_installed", "opencode_startup_timeout", "opencode_request_failed", "opencode_backend_not_running", "opencode_session_not_found", "json_invalid_input", "env_tool_not_found", "internal_error"];
3
+ export interface ServicemeErrorDetails {
4
+ code: ServicemeErrorCode;
5
+ message: string;
6
+ retryable: boolean;
7
+ details?: unknown;
8
+ }
9
+ export declare function isServicemeErrorCode(value: unknown): value is ServicemeErrorCode;
10
+ export declare function isServicemeErrorDetails(value: unknown): value is ServicemeErrorDetails;
11
+ export declare function isRetryableErrorCode(code: ServicemeErrorCode): boolean;
12
+ export declare class ServicemeProtocolError extends Error {
13
+ readonly code: ServicemeErrorCode;
14
+ readonly retryable: boolean;
15
+ readonly details?: unknown;
16
+ constructor(input: {
17
+ code: ServicemeErrorCode;
18
+ message: string;
19
+ retryable?: boolean;
20
+ details?: unknown;
21
+ });
22
+ toJSON(): ServicemeErrorDetails;
23
+ }
24
+ export declare function createServicemeError(code: ServicemeErrorCode, message: string, details?: unknown): ServicemeProtocolError;
25
+ export declare function normalizeServicemeError(error: unknown, fallbackCode?: ServicemeErrorCode): ServicemeErrorDetails;
package/dist/errors.js ADDED
@@ -0,0 +1,98 @@
1
+ export const SERVICEME_ERROR_CODES = [
2
+ "protocol_mismatch",
3
+ "cli_not_found",
4
+ "cli_start_failed",
5
+ "command_timeout",
6
+ "request_cancelled",
7
+ "invalid_params",
8
+ "opencode_not_installed",
9
+ "opencode_startup_timeout",
10
+ "opencode_request_failed",
11
+ "opencode_backend_not_running",
12
+ "opencode_session_not_found",
13
+ "json_invalid_input",
14
+ "env_tool_not_found",
15
+ "internal_error",
16
+ ];
17
+ const RETRYABLE_ERROR_CODES = new Set([
18
+ "command_timeout",
19
+ "request_cancelled",
20
+ "opencode_startup_timeout",
21
+ "opencode_request_failed",
22
+ "opencode_backend_not_running",
23
+ "internal_error",
24
+ ]);
25
+ function isRecord(value) {
26
+ return typeof value === "object" && value !== null;
27
+ }
28
+ export function isServicemeErrorCode(value) {
29
+ return typeof value === "string" && SERVICEME_ERROR_CODES.includes(value);
30
+ }
31
+ export function isServicemeErrorDetails(value) {
32
+ if (!isRecord(value)) {
33
+ return false;
34
+ }
35
+ return (isServicemeErrorCode(value.code) &&
36
+ typeof value.message === "string" &&
37
+ typeof value.retryable === "boolean");
38
+ }
39
+ export function isRetryableErrorCode(code) {
40
+ return RETRYABLE_ERROR_CODES.has(code);
41
+ }
42
+ export class ServicemeProtocolError extends Error {
43
+ constructor(input) {
44
+ super(input.message);
45
+ this.name = "ServicemeProtocolError";
46
+ this.code = input.code;
47
+ this.retryable = input.retryable ?? isRetryableErrorCode(input.code);
48
+ this.details = input.details;
49
+ Object.setPrototypeOf(this, new.target.prototype);
50
+ }
51
+ toJSON() {
52
+ return {
53
+ code: this.code,
54
+ message: this.message,
55
+ retryable: this.retryable,
56
+ details: this.details,
57
+ };
58
+ }
59
+ }
60
+ export function createServicemeError(code, message, details) {
61
+ return new ServicemeProtocolError({
62
+ code,
63
+ message,
64
+ details,
65
+ });
66
+ }
67
+ export function normalizeServicemeError(error, fallbackCode = "internal_error") {
68
+ if (error instanceof ServicemeProtocolError) {
69
+ return error.toJSON();
70
+ }
71
+ if (isServicemeErrorDetails(error)) {
72
+ return error;
73
+ }
74
+ if (isRecord(error)) {
75
+ const code = isServicemeErrorCode(error.code) ? error.code : fallbackCode;
76
+ const message = typeof error.message === "string" ? error.message : "Unexpected serviceme error.";
77
+ const retryable = typeof error.retryable === "boolean" ? error.retryable : isRetryableErrorCode(code);
78
+ return {
79
+ code,
80
+ message,
81
+ retryable,
82
+ details: error.details,
83
+ };
84
+ }
85
+ if (error instanceof Error) {
86
+ return {
87
+ code: fallbackCode,
88
+ message: error.message,
89
+ retryable: isRetryableErrorCode(fallbackCode),
90
+ };
91
+ }
92
+ return {
93
+ code: fallbackCode,
94
+ message: typeof error === "string" ? error : "Unexpected serviceme error.",
95
+ retryable: isRetryableErrorCode(fallbackCode),
96
+ };
97
+ }
98
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export type ServiceMeImageFormat = "jpeg" | "png" | "webp";
2
+ export declare const SERVICEME_IMAGE_FORMATS: readonly ["jpeg", "png", "webp"];
3
+ export interface ServiceMeImageCompressOptions {
4
+ quality: number;
5
+ replaceOriginImage: boolean;
6
+ outputPath?: string;
7
+ format?: ServiceMeImageFormat;
8
+ sharpModulePath?: string;
9
+ minimumCompressionRatio?: number;
10
+ }
11
+ export interface ServiceMeImageCompressResult {
12
+ originalSize: number;
13
+ compressedSize: number;
14
+ compressionRatio: number;
15
+ outputPath: string;
16
+ }
17
+ export interface ServiceMeImageInfo {
18
+ width: number;
19
+ height: number;
20
+ format: string;
21
+ size: number;
22
+ colorSpace?: string;
23
+ }
24
+ export interface ServiceMeImageValidationResult {
25
+ valid: boolean;
26
+ }
27
+ export declare function isServiceMeImageFormat(value: unknown): value is ServiceMeImageFormat;
28
+ export declare function isServiceMeImageCompressOptions(value: unknown): value is ServiceMeImageCompressOptions;
29
+ export declare function isServiceMeImageCompressResult(value: unknown): value is ServiceMeImageCompressResult;
30
+ export declare function isServiceMeImageInfo(value: unknown): value is ServiceMeImageInfo;
31
+ export declare function isServiceMeImageValidationResult(value: unknown): value is ServiceMeImageValidationResult;