@cofy-x/axern-sdk 0.2.1 → 0.4.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 CHANGED
@@ -43,7 +43,7 @@ const client = AxernClient.fromContext(
43
43
 
44
44
  const sandbox = await new Sandbox({
45
45
  client,
46
- image: "python:3.12-slim",
46
+ image: "docker.io/library/python:3.12-slim",
47
47
  namespace: "typescript-sdk-example",
48
48
  tunnel: {
49
49
  upstream: "127.0.0.1:8080",
@@ -40,11 +40,16 @@ export interface CreateServiceOptions {
40
40
  limitMemory?: ResourceQuantity;
41
41
  labels?: Record<string, string>;
42
42
  }
43
+ export interface ReadRunOutputOptions {
44
+ cursor?: string;
45
+ follow?: boolean;
46
+ }
43
47
  export declare class AxernClient {
44
48
  readonly endpoint: string;
45
49
  private readonly credentials;
46
50
  private readonly controlOptions;
47
51
  private readonly environmentControl;
52
+ private readonly runControl;
48
53
  private readonly serviceControl;
49
54
  private readonly tunnelControl;
50
55
  private readonly gatewayTransport;
@@ -54,6 +59,8 @@ export declare class AxernClient {
54
59
  close(): void;
55
60
  createEnvironment(options: CreateEnvironmentOptions): Promise<Record<string, unknown>>;
56
61
  deleteEnvironment(environmentId: string): Promise<void>;
62
+ watchRun(runId: string, afterVersion?: number): AsyncGenerator<Record<string, unknown>>;
63
+ readRunOutput(runId: string, options?: ReadRunOutputOptions): AsyncGenerator<Record<string, unknown>>;
57
64
  createService(options: CreateServiceOptions): Promise<Record<string, unknown>>;
58
65
  deleteService(serviceId: string): Promise<void>;
59
66
  listServiceReplicas(serviceId: string): Promise<Record<string, unknown>[]>;
@@ -17,6 +17,7 @@ export class AxernClient {
17
17
  credentials;
18
18
  controlOptions;
19
19
  environmentControl;
20
+ runControl;
20
21
  serviceControl;
21
22
  tunnelControl;
22
23
  gatewayTransport;
@@ -55,9 +56,11 @@ export class AxernClient {
55
56
  "v1",
56
57
  "EnvironmentControl",
57
58
  ]);
59
+ const RunControl = serviceConstructor(["axern", "control", "run", "v1", "RunControl"]);
58
60
  const ServiceControl = serviceConstructor(["axern", "control", "service", "v1", "ServiceControl"]);
59
61
  const TunnelControl = serviceConstructor(["axern", "control", "tunnel", "v1", "TunnelControl"]);
60
62
  this.environmentControl = new EnvironmentControl(this.endpoint, this.credentials, this.controlOptions);
63
+ this.runControl = new RunControl(this.endpoint, this.credentials, this.controlOptions);
61
64
  this.serviceControl = new ServiceControl(this.endpoint, this.credentials, this.controlOptions);
62
65
  this.tunnelControl = new TunnelControl(this.endpoint, this.credentials, this.controlOptions);
63
66
  }
@@ -78,6 +81,7 @@ export class AxernClient {
78
81
  }
79
82
  close() {
80
83
  this.environmentControl.close();
84
+ this.runControl.close();
81
85
  this.serviceControl.close();
82
86
  this.tunnelControl.close();
83
87
  }
@@ -114,6 +118,83 @@ export class AxernClient {
114
118
  throw mapRpcError(error, "delete environment");
115
119
  }
116
120
  }
121
+ async *watchRun(runId, afterVersion = 0) {
122
+ if (afterVersion < 0) {
123
+ throw new Error("afterVersion must be non-negative");
124
+ }
125
+ let version = afterVersion;
126
+ let retryDelayMs = 100;
127
+ for (;;) {
128
+ const stream = serverStream(this.runControl, "WatchRun", {
129
+ run_id: required("runId", runId),
130
+ after_version: version,
131
+ });
132
+ try {
133
+ for await (const response of stream) {
134
+ const run = response.run;
135
+ if (run === undefined)
136
+ continue;
137
+ const nextVersion = Number(run.version ?? 0);
138
+ if (nextVersion <= version)
139
+ continue;
140
+ version = nextVersion;
141
+ retryDelayMs = 100;
142
+ yield run;
143
+ }
144
+ return;
145
+ }
146
+ catch (error) {
147
+ if (!transientReadError(error))
148
+ throw mapRpcError(error, "watch run");
149
+ }
150
+ await sleep(retryDelayMs);
151
+ retryDelayMs = Math.min(retryDelayMs * 2, 2_000);
152
+ }
153
+ }
154
+ async *readRunOutput(runId, options = {}) {
155
+ const response = await unary(this.runControl, "GetRun", { run_id: required("runId", runId) });
156
+ const allocationId = String(response.run?.allocation_id ?? "");
157
+ if (allocationId === "")
158
+ throw new Error(`run ${runId} output is not available yet`);
159
+ let cursor = options.cursor ?? "";
160
+ let retryDelayMs = 100;
161
+ let notFoundSince = 0;
162
+ for (;;) {
163
+ const NodeSandbox = serviceConstructor(["axern", "node", "sandbox", "v1", "NodeSandbox"]);
164
+ const node = new NodeSandbox(this.endpoint, this.credentials, this.controlOptions);
165
+ const stream = serverStream(node, "ReadOutput", {
166
+ allocation_id: allocationId,
167
+ cursor,
168
+ follow: options.follow ?? false,
169
+ });
170
+ try {
171
+ for await (const event of stream) {
172
+ cursor = String(event.next_cursor ?? cursor);
173
+ retryDelayMs = 100;
174
+ notFoundSince = 0;
175
+ yield event;
176
+ }
177
+ return;
178
+ }
179
+ catch (error) {
180
+ const code = error.code;
181
+ const startupNotFound = code === grpc.status.NOT_FOUND;
182
+ if (!(options.follow ?? false) || (!transientReadError(error) && !startupNotFound)) {
183
+ throw mapRpcError(error, "read run output");
184
+ }
185
+ if (startupNotFound) {
186
+ notFoundSince ||= Date.now();
187
+ if (Date.now() - notFoundSince >= 30_000)
188
+ throw mapRpcError(error, "read run output");
189
+ }
190
+ }
191
+ finally {
192
+ node.close();
193
+ }
194
+ await sleep(retryDelayMs);
195
+ retryDelayMs = Math.min(retryDelayMs * 2, 2_000);
196
+ }
197
+ }
117
198
  async createService(options) {
118
199
  const resources = buildResourceSpec(options);
119
200
  try {
@@ -180,6 +261,17 @@ function serviceVolumeMounts(mounts) {
180
261
  options: [...(mount.options ?? [])],
181
262
  }));
182
263
  }
264
+ function serverStream(client, method, request) {
265
+ const fn = client[method];
266
+ return fn.call(client, request);
267
+ }
268
+ function transientReadError(error) {
269
+ const code = error.code;
270
+ return code === grpc.status.UNAVAILABLE || code === grpc.status.DEADLINE_EXCEEDED;
271
+ }
272
+ function sleep(milliseconds) {
273
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
274
+ }
183
275
  function controlCredentials(options) {
184
276
  const configured = [options.tlsCaCert, options.tlsCert, options.tlsKey].filter((value) => value !== undefined && value !== "");
185
277
  if (configured.length === 0) {
@@ -15,7 +15,7 @@ const defaultProtoRootCandidates = [
15
15
  ];
16
16
  const protoFiles = [
17
17
  "axern/control/environment/v1/environment.proto",
18
- "axern/control/gateway/v1/gateway.proto",
18
+ "axern/control/run/v1/run.proto",
19
19
  "axern/control/service/v1/service.proto",
20
20
  "axern/control/tunnel/v1/tunnel.proto",
21
21
  "axern/node/sandbox/v1/node.proto",
@@ -0,0 +1,123 @@
1
+ syntax = "proto3";
2
+
3
+ package axern.control.admin.v1;
4
+
5
+ option go_package = "github.com/cofy-x/axern/sdk/go/gen/axern/control/admin/v1;adminv1";
6
+
7
+ import "google/protobuf/timestamp.proto";
8
+
9
+ enum PrincipalKind {
10
+ PRINCIPAL_KIND_UNSPECIFIED = 0;
11
+ PRINCIPAL_KIND_HUMAN = 1;
12
+ PRINCIPAL_KIND_SERVICE = 2;
13
+ }
14
+
15
+ enum PrincipalStatus {
16
+ PRINCIPAL_STATUS_UNSPECIFIED = 0;
17
+ PRINCIPAL_STATUS_ACTIVE = 1;
18
+ PRINCIPAL_STATUS_DISABLED = 2;
19
+ }
20
+
21
+ enum AccessScopeType {
22
+ ACCESS_SCOPE_TYPE_UNSPECIFIED = 0;
23
+ ACCESS_SCOPE_TYPE_PLATFORM = 1;
24
+ ACCESS_SCOPE_TYPE_NAMESPACE = 2;
25
+ }
26
+
27
+ enum AccessRole {
28
+ ACCESS_ROLE_UNSPECIFIED = 0;
29
+ ACCESS_ROLE_PLATFORM_ADMIN = 1;
30
+ ACCESS_ROLE_NAMESPACE_ADMIN = 2;
31
+ ACCESS_ROLE_NAMESPACE_EDITOR = 3;
32
+ ACCESS_ROLE_NAMESPACE_VIEWER = 4;
33
+ ACCESS_ROLE_ROLLOUT_EXECUTOR = 5;
34
+ }
35
+
36
+ message Principal {
37
+ string principal_id = 1;
38
+ string name = 2;
39
+ string display_name = 3;
40
+ PrincipalKind kind = 4;
41
+ PrincipalStatus status = 5;
42
+ int64 version = 6;
43
+ google.protobuf.Timestamp created_at = 7;
44
+ google.protobuf.Timestamp updated_at = 8;
45
+ }
46
+
47
+ message PrincipalCredential {
48
+ string credential_id = 1;
49
+ string principal_id = 2;
50
+ string fingerprint = 3;
51
+ google.protobuf.Timestamp certificate_not_after = 4;
52
+ string label = 5;
53
+ google.protobuf.Timestamp created_at = 6;
54
+ google.protobuf.Timestamp revoked_at = 7;
55
+ }
56
+
57
+ message RoleBinding {
58
+ string binding_id = 1;
59
+ string principal_id = 2;
60
+ AccessScopeType scope_type = 3;
61
+ string namespace = 4;
62
+ AccessRole role = 5;
63
+ string created_by_principal_id = 6;
64
+ google.protobuf.Timestamp created_at = 7;
65
+ string revoked_by_principal_id = 8;
66
+ google.protobuf.Timestamp revoked_at = 9;
67
+ }
68
+
69
+ message CreatePrincipalRequest {
70
+ string name = 1;
71
+ string display_name = 2;
72
+ PrincipalKind kind = 3;
73
+ }
74
+ message CreatePrincipalResponse { Principal principal = 1; }
75
+
76
+ message ListPrincipalsRequest {}
77
+ message ListPrincipalsResponse { repeated Principal principals = 1; }
78
+
79
+ message DisablePrincipalRequest { string principal_id = 1; }
80
+ message DisablePrincipalResponse { Principal principal = 1; }
81
+
82
+ message AddPrincipalCredentialRequest {
83
+ string principal_id = 1;
84
+ bytes certificate_der = 2;
85
+ string label = 3;
86
+ }
87
+ message AddPrincipalCredentialResponse { PrincipalCredential credential = 1; }
88
+
89
+ message ListPrincipalCredentialsRequest { string principal_id = 1; }
90
+ message ListPrincipalCredentialsResponse { repeated PrincipalCredential credentials = 1; }
91
+
92
+ message RevokePrincipalCredentialRequest { string credential_id = 1; }
93
+ message RevokePrincipalCredentialResponse { PrincipalCredential credential = 1; }
94
+
95
+ message GrantRoleBindingRequest {
96
+ string principal_id = 1;
97
+ AccessScopeType scope_type = 2;
98
+ string namespace = 3;
99
+ AccessRole role = 4;
100
+ }
101
+ message GrantRoleBindingResponse { RoleBinding binding = 1; }
102
+
103
+ message ListRoleBindingsRequest {
104
+ string principal_id = 1;
105
+ string namespace = 2;
106
+ bool include_revoked = 3;
107
+ }
108
+ message ListRoleBindingsResponse { repeated RoleBinding bindings = 1; }
109
+
110
+ message RevokeRoleBindingRequest { string binding_id = 1; }
111
+ message RevokeRoleBindingResponse { RoleBinding binding = 1; }
112
+
113
+ service AccessAdmin {
114
+ rpc CreatePrincipal(CreatePrincipalRequest) returns (CreatePrincipalResponse) {}
115
+ rpc ListPrincipals(ListPrincipalsRequest) returns (ListPrincipalsResponse) {}
116
+ rpc DisablePrincipal(DisablePrincipalRequest) returns (DisablePrincipalResponse) {}
117
+ rpc AddPrincipalCredential(AddPrincipalCredentialRequest) returns (AddPrincipalCredentialResponse) {}
118
+ rpc ListPrincipalCredentials(ListPrincipalCredentialsRequest) returns (ListPrincipalCredentialsResponse) {}
119
+ rpc RevokePrincipalCredential(RevokePrincipalCredentialRequest) returns (RevokePrincipalCredentialResponse) {}
120
+ rpc GrantRoleBinding(GrantRoleBindingRequest) returns (GrantRoleBindingResponse) {}
121
+ rpc ListRoleBindings(ListRoleBindingsRequest) returns (ListRoleBindingsResponse) {}
122
+ rpc RevokeRoleBinding(RevokeRoleBindingRequest) returns (RevokeRoleBindingResponse) {}
123
+ }
@@ -14,6 +14,13 @@ enum AdminAuditOperation {
14
14
  ADMIN_AUDIT_OPERATION_RETRY_STORAGE_BINDING = 4;
15
15
  ADMIN_AUDIT_OPERATION_PURGE_SERVICE = 5;
16
16
  ADMIN_AUDIT_OPERATION_RETIRE_NODE = 6;
17
+ ADMIN_AUDIT_OPERATION_CREATE_PRINCIPAL = 7;
18
+ ADMIN_AUDIT_OPERATION_DISABLE_PRINCIPAL = 8;
19
+ ADMIN_AUDIT_OPERATION_ADD_CREDENTIAL = 9;
20
+ ADMIN_AUDIT_OPERATION_REVOKE_CREDENTIAL = 10;
21
+ ADMIN_AUDIT_OPERATION_GRANT_ROLE_BINDING = 11;
22
+ ADMIN_AUDIT_OPERATION_REVOKE_ROLE_BINDING = 12;
23
+ ADMIN_AUDIT_OPERATION_BOOTSTRAP_ACCESS = 13;
17
24
  }
18
25
 
19
26
  enum AdminAuditTargetType {
@@ -22,6 +29,9 @@ enum AdminAuditTargetType {
22
29
  ADMIN_AUDIT_TARGET_TYPE_STORAGE_BINDING = 2;
23
30
  ADMIN_AUDIT_TARGET_TYPE_SERVICE = 3;
24
31
  ADMIN_AUDIT_TARGET_TYPE_NODE = 4;
32
+ ADMIN_AUDIT_TARGET_TYPE_PRINCIPAL = 5;
33
+ ADMIN_AUDIT_TARGET_TYPE_CREDENTIAL = 6;
34
+ ADMIN_AUDIT_TARGET_TYPE_ROLE_BINDING = 7;
25
35
  }
26
36
 
27
37
  message AdminAuditEvent {
@@ -31,6 +41,7 @@ message AdminAuditEvent {
31
41
  string target_id = 4;
32
42
  string operator_reason = 5;
33
43
  google.protobuf.Timestamp created_at = 6;
44
+ string actor_principal_id = 7;
34
45
  }
35
46
 
36
47
  message AdminAuditEventFilter {
@@ -42,6 +42,15 @@ message ResolveServiceRouteResponse {
42
42
  message ResolveAllocationTerminalRequest {
43
43
  string allocation_id = 1;
44
44
  int64 ttl_seconds = 2;
45
+ string client_certificate_fingerprint = 3;
46
+ string rollout_execution_lease = 4;
47
+ AllocationAccessPurpose purpose = 5;
48
+ }
49
+
50
+ enum AllocationAccessPurpose {
51
+ ALLOCATION_ACCESS_PURPOSE_UNSPECIFIED = 0;
52
+ ALLOCATION_ACCESS_PURPOSE_INTERACTIVE = 1;
53
+ ALLOCATION_ACCESS_PURPOSE_RUN_OUTPUT = 2;
45
54
  }
46
55
 
47
56
  message ResolveAllocationTerminalResponse {
@@ -54,7 +63,30 @@ message ResolveAllocationTerminalResponse {
54
63
  axern.control.common.v1.ExecutionLease lease = 7;
55
64
  }
56
65
 
66
+ message ResolveTunnelRelayTargetRequest {
67
+ string session_id = 1;
68
+ }
69
+
70
+ message ResolveTunnelRelayTargetResponse {
71
+ string node_edge_target = 1;
72
+ }
73
+
74
+ message ResolveServiceReplicaTargetsRequest {
75
+ string service_id = 1;
76
+ }
77
+
78
+ message ServiceReplicaTarget {
79
+ string allocation_id = 1;
80
+ string node_id = 2;
81
+ }
82
+
83
+ message ResolveServiceReplicaTargetsResponse {
84
+ repeated ServiceReplicaTarget replicas = 1;
85
+ }
86
+
57
87
  service GatewayControl {
58
88
  rpc ResolveServiceRoute(ResolveServiceRouteRequest) returns (ResolveServiceRouteResponse) {}
59
89
  rpc ResolveAllocationTerminal(ResolveAllocationTerminalRequest) returns (ResolveAllocationTerminalResponse) {}
90
+ rpc ResolveTunnelRelayTarget(ResolveTunnelRelayTargetRequest) returns (ResolveTunnelRelayTargetResponse) {}
91
+ rpc ResolveServiceReplicaTargets(ResolveServiceReplicaTargetsRequest) returns (ResolveServiceReplicaTargetsResponse) {}
60
92
  }
@@ -0,0 +1,39 @@
1
+ syntax = "proto3";
2
+
3
+ package axern.control.identity.v1;
4
+
5
+ option go_package = "github.com/cofy-x/axern/sdk/go/gen/axern/control/identity/v1;identityv1";
6
+
7
+ import "google/protobuf/timestamp.proto";
8
+
9
+ message PrincipalIdentity {
10
+ string principal_id = 1;
11
+ string name = 2;
12
+ string display_name = 3;
13
+ string kind = 4;
14
+ }
15
+
16
+ message CredentialIdentity {
17
+ string credential_id = 1;
18
+ string label = 2;
19
+ string fingerprint = 3;
20
+ google.protobuf.Timestamp certificate_not_after = 4;
21
+ }
22
+
23
+ message EffectiveRole {
24
+ string role = 1;
25
+ string scope_type = 2;
26
+ string namespace = 3;
27
+ }
28
+
29
+ message WhoAmIRequest {}
30
+
31
+ message WhoAmIResponse {
32
+ PrincipalIdentity principal = 1;
33
+ CredentialIdentity credential = 2;
34
+ repeated EffectiveRole roles = 3;
35
+ }
36
+
37
+ service IdentityControl {
38
+ rpc WhoAmI(WhoAmIRequest) returns (WhoAmIResponse) {}
39
+ }
@@ -34,6 +34,9 @@ message Run {
34
34
  bool exit_code_known = 13;
35
35
  string message = 14;
36
36
  axern.control.common.v1.WorkloadDiagnosticCode diagnostic_code = 15;
37
+ // Reserved for durable output metadata once output retention is owned by
38
+ // the control plane rather than inferred from a node-local allocation.
39
+ reserved 16 to 18;
37
40
  }
38
41
 
39
42
  message RunListFilter {
@@ -63,6 +66,15 @@ message GetRunResponse {
63
66
  Run run = 1;
64
67
  }
65
68
 
69
+ message WatchRunRequest {
70
+ string run_id = 1;
71
+ int64 after_version = 2;
72
+ }
73
+
74
+ message WatchRunResponse {
75
+ Run run = 1;
76
+ }
77
+
66
78
  message ListRunsRequest {
67
79
  RunListFilter filter = 1;
68
80
  }
@@ -83,6 +95,7 @@ message CancelRunResponse {
83
95
  service RunControl {
84
96
  rpc CreateRun(CreateRunRequest) returns (CreateRunResponse) {}
85
97
  rpc GetRun(GetRunRequest) returns (GetRunResponse) {}
98
+ rpc WatchRun(WatchRunRequest) returns (stream WatchRunResponse) {}
86
99
  rpc ListRuns(ListRunsRequest) returns (ListRunsResponse) {}
87
100
  rpc CancelRun(CancelRunRequest) returns (CancelRunResponse) {}
88
101
  }
@@ -34,6 +34,7 @@ message SecretListFilter {
34
34
  message CreateSecretRequest {
35
35
  string namespace = 1;
36
36
  SecretType type = 2;
37
+ // The JSON-encoded map must not exceed 64 KiB. Values are preserved verbatim.
37
38
  map<string, string> string_data = 3;
38
39
  map<string, string> labels = 4;
39
40
  }
@@ -86,6 +86,8 @@ message TunnelSession {
86
86
  google.protobuf.Timestamp last_peer_event_at = 20;
87
87
  int64 bytes_in = 21;
88
88
  int64 bytes_out = 22;
89
+ string namespace = 23;
90
+ string creator_principal_id = 24;
89
91
  }
90
92
 
91
93
  message TunnelSessionEvent {
@@ -129,6 +131,7 @@ message ListTunnelSessionsRequest {
129
131
  string allocation_id = 1;
130
132
  string node_id = 2;
131
133
  bool include_terminal = 3;
134
+ string namespace = 4;
132
135
  }
133
136
 
134
137
  message ListTunnelSessionsResponse {
@@ -173,16 +176,6 @@ message RenewTunnelSessionResponse {
173
176
  TunnelSession session = 1;
174
177
  }
175
178
 
176
- message ValidateTunnelPeerRequest {
177
- string session_id = 1;
178
- TunnelPeerKind peer_kind = 2;
179
- string token = 3;
180
- }
181
-
182
- message ValidateTunnelPeerResponse {
183
- TunnelSession session = 1;
184
- }
185
-
186
179
  service TunnelControl {
187
180
  rpc CreateTunnelSession(CreateTunnelSessionRequest) returns (CreateTunnelSessionResponse) {}
188
181
  rpc GetTunnelSession(GetTunnelSessionRequest) returns (GetTunnelSessionResponse) {}
@@ -191,5 +184,4 @@ service TunnelControl {
191
184
  rpc InspectTunnelSession(InspectTunnelSessionRequest) returns (InspectTunnelSessionResponse) {}
192
185
  rpc RevokeTunnelSession(RevokeTunnelSessionRequest) returns (RevokeTunnelSessionResponse) {}
193
186
  rpc RenewTunnelSession(RenewTunnelSessionRequest) returns (RenewTunnelSessionResponse) {}
194
- rpc ValidateTunnelPeer(ValidateTunnelPeerRequest) returns (ValidateTunnelPeerResponse) {}
195
187
  }
@@ -199,6 +199,29 @@ message WaitSandboxResponse {
199
199
  string message = 4;
200
200
  }
201
201
 
202
+ enum OutputStream {
203
+ OUTPUT_STREAM_UNSPECIFIED = 0;
204
+ OUTPUT_STREAM_STDOUT = 1;
205
+ OUTPUT_STREAM_STDERR = 2;
206
+ }
207
+
208
+ message ReadOutputRequest {
209
+ string allocation_id = 1;
210
+ int64 attempt = 2;
211
+ string execution_lease_token = 3;
212
+ string cursor = 4;
213
+ bool follow = 5;
214
+ }
215
+
216
+ message ReadOutputResponse {
217
+ OutputStream stream = 1;
218
+ bytes data = 2;
219
+ string next_cursor = 3;
220
+ bool terminal = 4;
221
+ bool truncated = 5;
222
+ int64 observed_at_unix_milli = 6;
223
+ }
224
+
202
225
  // Capabilities
203
226
 
204
227
  message CapabilityStatusRequest {
@@ -620,6 +643,7 @@ service NodeSandbox {
620
643
  rpc ExecImage(ExecImageRequest) returns (ExecImageResponse) {}
621
644
  rpc ProcessImage(stream ProcessImageRequest) returns (stream ProcessImageResponse) {}
622
645
  rpc WaitSandbox(WaitSandboxRequest) returns (WaitSandboxResponse) {}
646
+ rpc ReadOutput(ReadOutputRequest) returns (stream ReadOutputResponse) {}
623
647
  rpc CapabilityStatus(CapabilityStatusRequest) returns (CapabilityStatusResponse) {}
624
648
  rpc ProxyHTTP(stream ProxyHTTPRequest) returns (stream ProxyHTTPResponse) {}
625
649
  rpc StatFile(StatFileRequest) returns (StatFileResponse) {}
package/dist/version.d.ts CHANGED
@@ -3,5 +3,5 @@
3
3
  * Copyright 2026 cofy-x
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- export declare const AXERN_VERSION = "0.2.1";
6
+ export declare const AXERN_VERSION = "0.4.0";
7
7
  export declare function platformName(): string;
package/dist/version.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Copyright 2026 cofy-x
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- export const AXERN_VERSION = "0.2.1";
6
+ export const AXERN_VERSION = "0.4.0";
7
7
  export function platformName() {
8
8
  return "axern";
9
9
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cofy-x/axern-sdk",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
4
  "description": "TypeScript SDK for Axern agentic infrastructure and isolated sandboxes",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {