cdeops 13.4.1-alpha.48 → 13.4.1

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/client.d.ts CHANGED
@@ -636,4 +636,182 @@ declare module 'cdeops/client' {
636
636
  export function getNodeById(nodeId: string): Promise<IAINodeContribution | undefined>;
637
637
  }
638
638
  }
639
+
640
+ // ── Gateway SPI ──
641
+
642
+ /** Configuration returned by a gateway provider. */
643
+ export interface IGatewayConfig {
644
+ config?: Record<string, unknown> | null;
645
+ hash: string;
646
+ }
647
+
648
+ /** Health/status of a gateway. */
649
+ export interface IGatewayStatus {
650
+ healthy: boolean;
651
+ version?: string;
652
+ uptime?: number;
653
+ }
654
+
655
+ /** Status of a messaging channel on the gateway. */
656
+ export interface IGatewayChannelStatus {
657
+ channel: string;
658
+ configured: boolean;
659
+ connected: boolean;
660
+ enabled: boolean;
661
+ accountId?: string;
662
+ error?: string;
663
+ }
664
+
665
+ /** A provisioned gateway instance. */
666
+ export interface IGatewayInstance {
667
+ releaseName: string;
668
+ slug: string;
669
+ url: string;
670
+ status: string;
671
+ userId: string;
672
+ projectId?: string;
673
+ namespace?: string;
674
+ replicas: number;
675
+ readyReplicas: number;
676
+ imageVariant?: string;
677
+ }
678
+
679
+ /** Resource usage metrics for a gateway instance. */
680
+ export interface IGatewayResourceUsage {
681
+ cpuRequest?: string;
682
+ cpuLimit?: string;
683
+ cpuActual?: string;
684
+ memoryRequest?: string;
685
+ memoryLimit?: string;
686
+ memoryActual?: string;
687
+ storageCapacity?: string;
688
+ }
689
+
690
+ /** Session URL for browser access to a gateway instance. */
691
+ export interface IGatewaySessionUrl {
692
+ sessionUrl: string;
693
+ expiresAt: number;
694
+ }
695
+
696
+ /** WebSocket chat connection details. */
697
+ export interface IGatewayChatConnection {
698
+ url: string;
699
+ wsUrl: string;
700
+ token: string;
701
+ proxyToken: string;
702
+ expiresAt?: number;
703
+ }
704
+
705
+ /** Input for provisioning a new gateway instance. */
706
+ export interface IProvisionGatewayInput {
707
+ userId: string;
708
+ userName?: string;
709
+ email?: string;
710
+ imageVariant?: string;
711
+ tier?: string;
712
+ workspaceEnabled?: boolean;
713
+ workspaceSize?: string;
714
+ persistenceEnabled?: boolean;
715
+ }
716
+
717
+ /** Agent detail from the gateway. */
718
+ export interface IGatewayAgentDetail {
719
+ id: string;
720
+ name?: string;
721
+ isDefault: boolean;
722
+ workspace?: string;
723
+ heartbeat?: { enabled: boolean; every?: string };
724
+ sessions?: { count: number };
725
+ files?: Array<{ name: string; path: string; missing: boolean; size?: number }>;
726
+ }
727
+
728
+ /**
729
+ * Service interface for interacting with a gateway's configuration and agents.
730
+ * Extensions implement this to provide gateway functionality.
731
+ */
732
+ export interface IGatewayService {
733
+ getConfig(projectId: string, userId: string): Promise<IGatewayConfig>;
734
+ updateConfig(projectId: string, userId: string, patch: Record<string, unknown>): Promise<void>;
735
+ replaceConfig(projectId: string, userId: string, config: Record<string, unknown>): Promise<void>;
736
+ getStatus(projectId: string, userId: string): Promise<IGatewayStatus>;
737
+ getModels(projectId: string, userId: string): Promise<unknown[]>;
738
+ getUsage(projectId: string, userId: string): Promise<unknown>;
739
+ listAgents(projectId: string, userId: string): Promise<unknown[]>;
740
+ getAgentDetail(projectId: string, userId: string, agentId: string): Promise<IGatewayAgentDetail>;
741
+ createAgent(
742
+ projectId: string,
743
+ userId: string,
744
+ name: string,
745
+ workspace?: string,
746
+ ): Promise<{ ok: boolean; agentId: string }>;
747
+ updateAgent(
748
+ projectId: string,
749
+ userId: string,
750
+ agentId: string,
751
+ params: { name?: string; model?: string },
752
+ ): Promise<{ ok: boolean; agentId: string }>;
753
+ deleteAgent(projectId: string, userId: string, agentId: string): Promise<{ ok: boolean; agentId: string }>;
754
+ listSessions(projectId: string, userId: string): Promise<unknown>;
755
+ setAgentFile(projectId: string, userId: string, agentId: string, name: string, content: string): Promise<void>;
756
+ }
757
+
758
+ /** Service interface for managing messaging channels on a gateway. */
759
+ export interface IGatewayChannelService {
760
+ connectChannel(
761
+ projectId: string,
762
+ userId: string,
763
+ channel: string,
764
+ credentials: Record<string, unknown>,
765
+ ): Promise<void>;
766
+ disconnectChannel(projectId: string, userId: string, channel: string, accountId?: string): Promise<void>;
767
+ getChannelsStatus(projectId: string, userId: string, probe?: boolean): Promise<IGatewayChannelStatus[]>;
768
+ }
769
+
770
+ /** Service interface for managing gateway instance lifecycle. */
771
+ export interface IGatewayInstanceService {
772
+ provisionInstance(projectId: string, req: IProvisionGatewayInput): Promise<IGatewayInstance>;
773
+ stopInstance(projectId: string, userId: string): Promise<IGatewayInstance>;
774
+ startInstance(projectId: string, userId: string): Promise<IGatewayInstance>;
775
+ deleteInstance(projectId: string, userId: string, deletePVCs?: boolean): Promise<void>;
776
+ getInstanceStatus(projectId: string, userId: string): Promise<IGatewayInstance>;
777
+ listInstances(projectId: string): Promise<IGatewayInstance[]>;
778
+ getResourceUsage(projectId: string, userId: string): Promise<IGatewayResourceUsage>;
779
+ generateSessionUrl(
780
+ projectId: string,
781
+ userId: string,
782
+ agentId?: string,
783
+ workspaceId?: number,
784
+ ): Promise<IGatewaySessionUrl>;
785
+ getChatConnection(projectId: string, userId: string): Promise<IGatewayChatConnection>;
786
+ }
787
+
788
+ /** A registered gateway provider returned by an extension. */
789
+ export interface IGatewayProvider {
790
+ /** Unique identifier for this gateway type (e.g. 'openclaw', 'custom'). */
791
+ id: string;
792
+ /** Human-readable display name. */
793
+ displayName: string;
794
+ /** Gateway config/agent/model service. */
795
+ gatewayService: IGatewayService;
796
+ /** Channel management service. */
797
+ channelService: IGatewayChannelService;
798
+ /** Instance lifecycle service. */
799
+ instanceService: IGatewayInstanceService;
800
+ }
801
+
802
+ /**
803
+ * Namespace for gateway provider registration.
804
+ * Extensions call `registerProvider` during activation;
805
+ * the host queries registered providers at runtime.
806
+ */
807
+ export namespace gateway {
808
+ /** Register a gateway provider. Returns a disposable to unregister. */
809
+ export function registerProvider(provider: IGatewayProvider): Disposable;
810
+
811
+ /** Get a registered gateway provider by id. */
812
+ export function getProvider(id: string): IGatewayProvider | undefined;
813
+
814
+ /** Get all registered gateway providers. */
815
+ export function getProviders(): IGatewayProvider[];
816
+ }
639
817
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdeops",
3
- "version": "13.4.1-alpha.48",
3
+ "version": "13.4.1",
4
4
  "description": "Cdecode - Extension API: build extensions that enhance coding experience in your cdeops editor",
5
5
  "license": "Apache-2.0",
6
6
  "author": "adminide-stack-user",
@@ -52,9 +52,6 @@
52
52
  "build:lib": "",
53
53
  "build:lib:watch": "npm run build:lib -- --watch",
54
54
  "docs": "typedoc",
55
- "prepublishOnly": "npm run tslint && npm run docs",
56
- "tslint": "tslint -c tslint.json -p tsconfig.json './src/**/*.{ts,js}'",
57
55
  "watch": "npm run build:lib:watch"
58
- },
59
- "gitHead": "626ea1c0f93abb3dcbccd92c9c1691f7d346d79f"
56
+ }
60
57
  }
package/server.d.ts CHANGED
@@ -635,4 +635,182 @@ declare module 'cdeops/server' {
635
635
  export function getNodeById(nodeId: string): Promise<IAINodeContribution | undefined>;
636
636
  }
637
637
  }
638
+
639
+ // ── Gateway SPI ──
640
+
641
+ /** Configuration returned by a gateway provider. */
642
+ export interface IGatewayConfig {
643
+ config?: Record<string, unknown> | null;
644
+ hash: string;
645
+ }
646
+
647
+ /** Health/status of a gateway. */
648
+ export interface IGatewayStatus {
649
+ healthy: boolean;
650
+ version?: string;
651
+ uptime?: number;
652
+ }
653
+
654
+ /** Status of a messaging channel on the gateway. */
655
+ export interface IGatewayChannelStatus {
656
+ channel: string;
657
+ configured: boolean;
658
+ connected: boolean;
659
+ enabled: boolean;
660
+ accountId?: string;
661
+ error?: string;
662
+ }
663
+
664
+ /** A provisioned gateway instance. */
665
+ export interface IGatewayInstance {
666
+ releaseName: string;
667
+ slug: string;
668
+ url: string;
669
+ status: string;
670
+ userId: string;
671
+ projectId?: string;
672
+ namespace?: string;
673
+ replicas: number;
674
+ readyReplicas: number;
675
+ imageVariant?: string;
676
+ }
677
+
678
+ /** Resource usage metrics for a gateway instance. */
679
+ export interface IGatewayResourceUsage {
680
+ cpuRequest?: string;
681
+ cpuLimit?: string;
682
+ cpuActual?: string;
683
+ memoryRequest?: string;
684
+ memoryLimit?: string;
685
+ memoryActual?: string;
686
+ storageCapacity?: string;
687
+ }
688
+
689
+ /** Session URL for browser access to a gateway instance. */
690
+ export interface IGatewaySessionUrl {
691
+ sessionUrl: string;
692
+ expiresAt: number;
693
+ }
694
+
695
+ /** WebSocket chat connection details. */
696
+ export interface IGatewayChatConnection {
697
+ url: string;
698
+ wsUrl: string;
699
+ token: string;
700
+ proxyToken: string;
701
+ expiresAt?: number;
702
+ }
703
+
704
+ /** Input for provisioning a new gateway instance. */
705
+ export interface IProvisionGatewayInput {
706
+ userId: string;
707
+ userName?: string;
708
+ email?: string;
709
+ imageVariant?: string;
710
+ tier?: string;
711
+ workspaceEnabled?: boolean;
712
+ workspaceSize?: string;
713
+ persistenceEnabled?: boolean;
714
+ }
715
+
716
+ /** Agent detail from the gateway. */
717
+ export interface IGatewayAgentDetail {
718
+ id: string;
719
+ name?: string;
720
+ isDefault: boolean;
721
+ workspace?: string;
722
+ heartbeat?: { enabled: boolean; every?: string };
723
+ sessions?: { count: number };
724
+ files?: Array<{ name: string; path: string; missing: boolean; size?: number }>;
725
+ }
726
+
727
+ /**
728
+ * Service interface for interacting with a gateway's configuration and agents.
729
+ * Extensions implement this to provide gateway functionality.
730
+ */
731
+ export interface IGatewayService {
732
+ getConfig(projectId: string, userId: string): Promise<IGatewayConfig>;
733
+ updateConfig(projectId: string, userId: string, patch: Record<string, unknown>): Promise<void>;
734
+ replaceConfig(projectId: string, userId: string, config: Record<string, unknown>): Promise<void>;
735
+ getStatus(projectId: string, userId: string): Promise<IGatewayStatus>;
736
+ getModels(projectId: string, userId: string): Promise<unknown[]>;
737
+ getUsage(projectId: string, userId: string): Promise<unknown>;
738
+ listAgents(projectId: string, userId: string): Promise<unknown[]>;
739
+ getAgentDetail(projectId: string, userId: string, agentId: string): Promise<IGatewayAgentDetail>;
740
+ createAgent(
741
+ projectId: string,
742
+ userId: string,
743
+ name: string,
744
+ workspace?: string,
745
+ ): Promise<{ ok: boolean; agentId: string }>;
746
+ updateAgent(
747
+ projectId: string,
748
+ userId: string,
749
+ agentId: string,
750
+ params: { name?: string; model?: string },
751
+ ): Promise<{ ok: boolean; agentId: string }>;
752
+ deleteAgent(projectId: string, userId: string, agentId: string): Promise<{ ok: boolean; agentId: string }>;
753
+ listSessions(projectId: string, userId: string): Promise<unknown>;
754
+ setAgentFile(projectId: string, userId: string, agentId: string, name: string, content: string): Promise<void>;
755
+ }
756
+
757
+ /** Service interface for managing messaging channels on a gateway. */
758
+ export interface IGatewayChannelService {
759
+ connectChannel(
760
+ projectId: string,
761
+ userId: string,
762
+ channel: string,
763
+ credentials: Record<string, unknown>,
764
+ ): Promise<void>;
765
+ disconnectChannel(projectId: string, userId: string, channel: string, accountId?: string): Promise<void>;
766
+ getChannelsStatus(projectId: string, userId: string, probe?: boolean): Promise<IGatewayChannelStatus[]>;
767
+ }
768
+
769
+ /** Service interface for managing gateway instance lifecycle. */
770
+ export interface IGatewayInstanceService {
771
+ provisionInstance(projectId: string, req: IProvisionGatewayInput): Promise<IGatewayInstance>;
772
+ stopInstance(projectId: string, userId: string): Promise<IGatewayInstance>;
773
+ startInstance(projectId: string, userId: string): Promise<IGatewayInstance>;
774
+ deleteInstance(projectId: string, userId: string, deletePVCs?: boolean): Promise<void>;
775
+ getInstanceStatus(projectId: string, userId: string): Promise<IGatewayInstance>;
776
+ listInstances(projectId: string): Promise<IGatewayInstance[]>;
777
+ getResourceUsage(projectId: string, userId: string): Promise<IGatewayResourceUsage>;
778
+ generateSessionUrl(
779
+ projectId: string,
780
+ userId: string,
781
+ agentId?: string,
782
+ workspaceId?: number,
783
+ ): Promise<IGatewaySessionUrl>;
784
+ getChatConnection(projectId: string, userId: string): Promise<IGatewayChatConnection>;
785
+ }
786
+
787
+ /** A registered gateway provider returned by an extension. */
788
+ export interface IGatewayProvider {
789
+ /** Unique identifier for this gateway type (e.g. 'openclaw', 'custom'). */
790
+ id: string;
791
+ /** Human-readable display name. */
792
+ displayName: string;
793
+ /** Gateway config/agent/model service. */
794
+ gatewayService: IGatewayService;
795
+ /** Channel management service. */
796
+ channelService: IGatewayChannelService;
797
+ /** Instance lifecycle service. */
798
+ instanceService: IGatewayInstanceService;
799
+ }
800
+
801
+ /**
802
+ * Namespace for gateway provider registration.
803
+ * Extensions call `registerProvider` during activation;
804
+ * the host queries registered providers at runtime.
805
+ */
806
+ export namespace gateway {
807
+ /** Register a gateway provider. Returns a disposable to unregister. */
808
+ export function registerProvider(provider: IGatewayProvider): Disposable;
809
+
810
+ /** Get a registered gateway provider by id. */
811
+ export function getProvider(id: string): IGatewayProvider | undefined;
812
+
813
+ /** Get all registered gateway providers. */
814
+ export function getProviders(): IGatewayProvider[];
815
+ }
638
816
  }
package/server.js CHANGED
@@ -2,8 +2,54 @@
2
2
  // `require('cdeops/server')`. It delegates to the extension host's runtime implementation of this module by calling
3
3
  // `global.require` (which ensures that the extension host's `require` is called at runtime).
4
4
  //
5
+ // When running outside an extension host (e.g., standalone CLI execution), this module provides a
6
+ // lightweight fallback that captures registerCommand handlers so they can be invoked directly.
7
+ //
5
8
  // This dummy file is used when extension is bundled with a JavaScript bundler that lacks support for externals
6
9
  // (or when `cdeops/server` is not configured as an external module). Parcel does not support extenals
7
10
  // (https://github.com/parcel-bundler/parcel/issues/144). Webpack, Rollup, and Microbundle support externals.
8
11
 
9
- module.exports = require('cdeops/server')
12
+ // Try the extension host first; fall back to a standalone shim for CLI use.
13
+ let hostModule;
14
+ try {
15
+ // In the extension host, global.require('cdeops/server') returns the real API.
16
+ // Outside the host this will either throw or return this same module (circular), so we detect both.
17
+ const candidate = global.require('cdeops/server');
18
+ if (candidate && candidate !== module.exports && candidate !== exports && typeof candidate.commands === 'object') {
19
+ hostModule = candidate;
20
+ }
21
+ } catch (_) {
22
+ // No extension host — use standalone fallback below.
23
+ }
24
+
25
+ if (hostModule) {
26
+ module.exports = hostModule;
27
+ } else {
28
+ // ── Standalone fallback ─────────────────────────────────────────────────────
29
+ // Provides just enough of the cdeops/server API for extensions to activate
30
+ // and register command handlers when executed by the CLI outside the IDE.
31
+ const _handlers = Object.create(null);
32
+
33
+ const commands = {
34
+ _handlers,
35
+ registerCommand(id, handler) {
36
+ _handlers[id] = handler;
37
+ return {
38
+ dispose() {
39
+ delete _handlers[id];
40
+ },
41
+ };
42
+ },
43
+ executeCommand(id) {
44
+ const args = Array.prototype.slice.call(arguments, 1);
45
+ const h = _handlers[id];
46
+ if (!h) throw new Error('Command not found: ' + id);
47
+ return h.apply(null, args);
48
+ },
49
+ getCommands() {
50
+ return Promise.resolve(Object.keys(_handlers));
51
+ },
52
+ };
53
+
54
+ module.exports = { commands: commands, _handlers: _handlers };
55
+ }
package/server.mjs CHANGED
@@ -2,12 +2,45 @@
2
2
  // It delegates to the extension host's runtime implementation of this module by calling
3
3
  // `globalThis.require` (which ensures that the extension host's `require` is called at runtime).
4
4
  //
5
+ // When running outside an extension host (e.g., standalone CLI execution), this module provides a
6
+ // lightweight fallback that captures registerCommand handlers so they can be invoked directly.
7
+ //
5
8
  // This dummy file is used when extension is bundled with a JavaScript bundler that lacks support for externals
6
9
  // (or when `cdeops/server` is not configured as an external module). Parcel does not support externals
7
10
  // (https://github.com/parcel-bundler/parcel/issues/144). Webpack, Rollup, and Microbundle support externals.
8
11
 
9
- // ESM named exports must be statically analyzable, so we can only reliably export the module as default.
10
- // Consumers should use: import cdeopsServer from 'cdeops/server'; then access cdeopsServer.commands, etc.
11
- // Or use: import cdeopsServer from 'cdeops/server'; const { commands, configuration } = cdeopsServer;
12
- const cdeopsServer = globalThis.require('cdeops/server');
12
+ // Try the extension host first; fall back to a standalone shim for CLI use.
13
+ let cdeopsServer;
14
+ try {
15
+ const candidate = globalThis.require('cdeops/server');
16
+ if (candidate && typeof candidate.commands === 'object') {
17
+ cdeopsServer = candidate;
18
+ }
19
+ } catch (_) {
20
+ // No extension host — use standalone fallback below.
21
+ }
22
+
23
+ if (!cdeopsServer) {
24
+ // ── Standalone fallback ─────────────────────────────────────────────────────
25
+ const _handlers = Object.create(null);
26
+ const commands = {
27
+ _handlers,
28
+ registerCommand(id, handler) {
29
+ _handlers[id] = handler;
30
+ return { dispose() { delete _handlers[id]; } };
31
+ },
32
+ executeCommand(id, ...args) {
33
+ const h = _handlers[id];
34
+ if (!h) throw new Error('Command not found: ' + id);
35
+ return h(...args);
36
+ },
37
+ getCommands() {
38
+ return Promise.resolve(Object.keys(_handlers));
39
+ },
40
+ };
41
+ cdeopsServer = { commands, _handlers };
42
+ }
43
+
13
44
  export default cdeopsServer;
45
+ export const commands = cdeopsServer.commands;
46
+ export const _handlers = cdeopsServer._handlers;