pi-app-server 0.1.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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/command-classification.d.ts +59 -0
  4. package/dist/command-classification.d.ts.map +1 -0
  5. package/dist/command-classification.js +78 -0
  6. package/dist/command-classification.js.map +7 -0
  7. package/dist/command-execution-engine.d.ts +118 -0
  8. package/dist/command-execution-engine.d.ts.map +1 -0
  9. package/dist/command-execution-engine.js +259 -0
  10. package/dist/command-execution-engine.js.map +7 -0
  11. package/dist/command-replay-store.d.ts +241 -0
  12. package/dist/command-replay-store.d.ts.map +1 -0
  13. package/dist/command-replay-store.js +306 -0
  14. package/dist/command-replay-store.js.map +7 -0
  15. package/dist/command-router.d.ts +25 -0
  16. package/dist/command-router.d.ts.map +1 -0
  17. package/dist/command-router.js +353 -0
  18. package/dist/command-router.js.map +7 -0
  19. package/dist/extension-ui.d.ts +139 -0
  20. package/dist/extension-ui.d.ts.map +1 -0
  21. package/dist/extension-ui.js +189 -0
  22. package/dist/extension-ui.js.map +7 -0
  23. package/dist/resource-governor.d.ts +254 -0
  24. package/dist/resource-governor.d.ts.map +1 -0
  25. package/dist/resource-governor.js +603 -0
  26. package/dist/resource-governor.js.map +7 -0
  27. package/dist/server-command-handlers.d.ts +120 -0
  28. package/dist/server-command-handlers.d.ts.map +1 -0
  29. package/dist/server-command-handlers.js +234 -0
  30. package/dist/server-command-handlers.js.map +7 -0
  31. package/dist/server-ui-context.d.ts +22 -0
  32. package/dist/server-ui-context.d.ts.map +1 -0
  33. package/dist/server-ui-context.js +221 -0
  34. package/dist/server-ui-context.js.map +7 -0
  35. package/dist/server.d.ts +82 -0
  36. package/dist/server.d.ts.map +1 -0
  37. package/dist/server.js +561 -0
  38. package/dist/server.js.map +7 -0
  39. package/dist/session-lock-manager.d.ts +100 -0
  40. package/dist/session-lock-manager.d.ts.map +1 -0
  41. package/dist/session-lock-manager.js +199 -0
  42. package/dist/session-lock-manager.js.map +7 -0
  43. package/dist/session-manager.d.ts +196 -0
  44. package/dist/session-manager.d.ts.map +1 -0
  45. package/dist/session-manager.js +1010 -0
  46. package/dist/session-manager.js.map +7 -0
  47. package/dist/session-store.d.ts +190 -0
  48. package/dist/session-store.d.ts.map +1 -0
  49. package/dist/session-store.js +446 -0
  50. package/dist/session-store.js.map +7 -0
  51. package/dist/session-version-store.d.ts +83 -0
  52. package/dist/session-version-store.d.ts.map +1 -0
  53. package/dist/session-version-store.js +117 -0
  54. package/dist/session-version-store.js.map +7 -0
  55. package/dist/type-guards.d.ts +59 -0
  56. package/dist/type-guards.d.ts.map +1 -0
  57. package/dist/type-guards.js +40 -0
  58. package/dist/type-guards.js.map +7 -0
  59. package/dist/types.d.ts +621 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +23 -0
  62. package/dist/types.js.map +7 -0
  63. package/dist/validation.d.ts +22 -0
  64. package/dist/validation.d.ts.map +1 -0
  65. package/dist/validation.js +323 -0
  66. package/dist/validation.js.map +7 -0
  67. package/package.json +135 -0
@@ -0,0 +1,117 @@
1
+ import { getSessionId } from "./types.js";
2
+ import { isMutationCommand } from "./command-classification.js";
3
+ class SessionVersionStore {
4
+ /** Monotonic per-session version counter. */
5
+ sessionVersions = /* @__PURE__ */ new Map();
6
+ // ==========================================================================
7
+ // VERSION ACCESS
8
+ // ==========================================================================
9
+ /**
10
+ * Get the current version for a session.
11
+ * Returns undefined if session has no version (doesn't exist).
12
+ */
13
+ getVersion(sessionId) {
14
+ return this.sessionVersions.get(sessionId);
15
+ }
16
+ /**
17
+ * Check if a session has a version record.
18
+ */
19
+ hasVersion(sessionId) {
20
+ return this.sessionVersions.has(sessionId);
21
+ }
22
+ /**
23
+ * Get statistics about the store state.
24
+ */
25
+ getStats() {
26
+ return { sessionCount: this.sessionVersions.size };
27
+ }
28
+ // ==========================================================================
29
+ // VERSION MUTATION
30
+ // ==========================================================================
31
+ /**
32
+ * Initialize version for a new session (starts at 0).
33
+ */
34
+ initialize(sessionId) {
35
+ this.sessionVersions.set(sessionId, 0);
36
+ }
37
+ /**
38
+ * Increment version for a session.
39
+ * Returns the new version number.
40
+ */
41
+ increment(sessionId) {
42
+ const current = this.sessionVersions.get(sessionId) ?? 0;
43
+ const next = current + 1;
44
+ this.sessionVersions.set(sessionId, next);
45
+ return next;
46
+ }
47
+ /**
48
+ * Set version for a session explicitly.
49
+ */
50
+ set(sessionId, version) {
51
+ this.sessionVersions.set(sessionId, version);
52
+ }
53
+ /**
54
+ * Remove version record for a session.
55
+ */
56
+ delete(sessionId) {
57
+ this.sessionVersions.delete(sessionId);
58
+ }
59
+ /**
60
+ * Clear all version records.
61
+ */
62
+ clear() {
63
+ this.sessionVersions.clear();
64
+ }
65
+ // ==========================================================================
66
+ // COMMAND CLASSIFICATION
67
+ // ==========================================================================
68
+ /**
69
+ * Check if a command type mutates session state.
70
+ * Delegates to command-classification.ts for single source of truth.
71
+ * Mutating commands advance the session version.
72
+ */
73
+ isMutation(commandType) {
74
+ return isMutationCommand(commandType);
75
+ }
76
+ // ==========================================================================
77
+ // RESPONSE VERSIONING
78
+ // ==========================================================================
79
+ /**
80
+ * Apply session version to a response.
81
+ *
82
+ * For successful responses:
83
+ * - create_session: initialize new session at version 0
84
+ * - load_session: initialize loaded session at version 0
85
+ * - delete_session: remove version record
86
+ * - other session commands: increment if mutating
87
+ *
88
+ * Failed responses are returned unchanged.
89
+ */
90
+ applyVersion(command, response) {
91
+ if (!response.success) return response;
92
+ if (command.type === "create_session" && response.command === "create_session" && response.success) {
93
+ const createdSessionId = response.data.sessionId;
94
+ this.sessionVersions.set(createdSessionId, 0);
95
+ return { ...response, sessionVersion: 0 };
96
+ }
97
+ if (command.type === "load_session" && response.command === "load_session" && response.success) {
98
+ const loadedSessionId = response.data.sessionId;
99
+ this.sessionVersions.set(loadedSessionId, 0);
100
+ return { ...response, sessionVersion: 0 };
101
+ }
102
+ if (command.type === "delete_session" && response.command === "delete_session" && response.success) {
103
+ this.sessionVersions.delete(command.sessionId);
104
+ return response;
105
+ }
106
+ const sessionId = getSessionId(command);
107
+ if (!sessionId) return response;
108
+ const current = this.sessionVersions.get(sessionId) ?? 0;
109
+ const next = this.isMutation(command.type) ? current + 1 : current;
110
+ this.sessionVersions.set(sessionId, next);
111
+ return { ...response, sessionVersion: next };
112
+ }
113
+ }
114
+ export {
115
+ SessionVersionStore
116
+ };
117
+ //# sourceMappingURL=session-version-store.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/session-version-store.ts"],
4
+ "sourcesContent": ["/**\n * Session Version Store - manages monotonic version counters per session.\n *\n * Responsibilities:\n * - Track session version numbers (for optimistic concurrency)\n * - Apply version increments to responses\n *\n * Note: Mutation classification is delegated to command-classification.ts\n * to maintain single source of truth.\n */\n\nimport type { RpcCommand, RpcResponse } from \"./types.js\";\nimport { getSessionId } from \"./types.js\";\nimport { isMutationCommand } from \"./command-classification.js\";\n\n/**\n * Statistics about the session version store.\n */\nexport interface SessionVersionStoreStats {\n /** Number of sessions being tracked */\n sessionCount: number;\n}\n\n/**\n * Session Version Store - manages monotonic version counters.\n *\n * Extracted from PiSessionManager to isolate:\n * - Version initialization (create session)\n * - Version deletion (delete session)\n * - Version increment logic (mutation classification)\n */\nexport class SessionVersionStore {\n /** Monotonic per-session version counter. */\n private sessionVersions = new Map<string, number>();\n\n // ==========================================================================\n // VERSION ACCESS\n // ==========================================================================\n\n /**\n * Get the current version for a session.\n * Returns undefined if session has no version (doesn't exist).\n */\n getVersion(sessionId: string): number | undefined {\n return this.sessionVersions.get(sessionId);\n }\n\n /**\n * Check if a session has a version record.\n */\n hasVersion(sessionId: string): boolean {\n return this.sessionVersions.has(sessionId);\n }\n\n /**\n * Get statistics about the store state.\n */\n getStats(): SessionVersionStoreStats {\n return { sessionCount: this.sessionVersions.size };\n }\n\n // ==========================================================================\n // VERSION MUTATION\n // ==========================================================================\n\n /**\n * Initialize version for a new session (starts at 0).\n */\n initialize(sessionId: string): void {\n this.sessionVersions.set(sessionId, 0);\n }\n\n /**\n * Increment version for a session.\n * Returns the new version number.\n */\n increment(sessionId: string): number {\n const current = this.sessionVersions.get(sessionId) ?? 0;\n const next = current + 1;\n this.sessionVersions.set(sessionId, next);\n return next;\n }\n\n /**\n * Set version for a session explicitly.\n */\n set(sessionId: string, version: number): void {\n this.sessionVersions.set(sessionId, version);\n }\n\n /**\n * Remove version record for a session.\n */\n delete(sessionId: string): void {\n this.sessionVersions.delete(sessionId);\n }\n\n /**\n * Clear all version records.\n */\n clear(): void {\n this.sessionVersions.clear();\n }\n\n // ==========================================================================\n // COMMAND CLASSIFICATION\n // ==========================================================================\n\n /**\n * Check if a command type mutates session state.\n * Delegates to command-classification.ts for single source of truth.\n * Mutating commands advance the session version.\n */\n isMutation(commandType: string): boolean {\n return isMutationCommand(commandType);\n }\n\n // ==========================================================================\n // RESPONSE VERSIONING\n // ==========================================================================\n\n /**\n * Apply session version to a response.\n *\n * For successful responses:\n * - create_session: initialize new session at version 0\n * - load_session: initialize loaded session at version 0\n * - delete_session: remove version record\n * - other session commands: increment if mutating\n *\n * Failed responses are returned unchanged.\n */\n applyVersion(command: RpcCommand, response: RpcResponse): RpcResponse {\n if (!response.success) return response;\n\n // Handle create_session specially\n if (\n command.type === \"create_session\" &&\n response.command === \"create_session\" &&\n response.success\n ) {\n const createdSessionId = response.data.sessionId;\n this.sessionVersions.set(createdSessionId, 0);\n return { ...response, sessionVersion: 0 };\n }\n\n // Handle load_session specially\n if (\n command.type === \"load_session\" &&\n response.command === \"load_session\" &&\n response.success\n ) {\n const loadedSessionId = response.data.sessionId;\n this.sessionVersions.set(loadedSessionId, 0);\n return { ...response, sessionVersion: 0 };\n }\n\n // Handle delete_session specially\n if (\n command.type === \"delete_session\" &&\n response.command === \"delete_session\" &&\n response.success\n ) {\n this.sessionVersions.delete(command.sessionId);\n return response;\n }\n\n // Regular session commands\n const sessionId = getSessionId(command);\n if (!sessionId) return response;\n\n const current = this.sessionVersions.get(sessionId) ?? 0;\n const next = this.isMutation(command.type) ? current + 1 : current;\n this.sessionVersions.set(sessionId, next);\n\n return { ...response, sessionVersion: next };\n }\n}\n"],
5
+ "mappings": "AAYA,SAAS,oBAAoB;AAC7B,SAAS,yBAAyB;AAkB3B,MAAM,oBAAoB;AAAA;AAAA,EAEvB,kBAAkB,oBAAI,IAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUlD,WAAW,WAAuC;AAChD,WAAO,KAAK,gBAAgB,IAAI,SAAS;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,WAA4B;AACrC,WAAO,KAAK,gBAAgB,IAAI,SAAS;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKA,WAAqC;AACnC,WAAO,EAAE,cAAc,KAAK,gBAAgB,KAAK;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,WAAyB;AAClC,SAAK,gBAAgB,IAAI,WAAW,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,WAA2B;AACnC,UAAM,UAAU,KAAK,gBAAgB,IAAI,SAAS,KAAK;AACvD,UAAM,OAAO,UAAU;AACvB,SAAK,gBAAgB,IAAI,WAAW,IAAI;AACxC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAAmB,SAAuB;AAC5C,SAAK,gBAAgB,IAAI,WAAW,OAAO;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,WAAyB;AAC9B,SAAK,gBAAgB,OAAO,SAAS;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,gBAAgB,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,WAAW,aAA8B;AACvC,WAAO,kBAAkB,WAAW;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,aAAa,SAAqB,UAAoC;AACpE,QAAI,CAAC,SAAS,QAAS,QAAO;AAG9B,QACE,QAAQ,SAAS,oBACjB,SAAS,YAAY,oBACrB,SAAS,SACT;AACA,YAAM,mBAAmB,SAAS,KAAK;AACvC,WAAK,gBAAgB,IAAI,kBAAkB,CAAC;AAC5C,aAAO,EAAE,GAAG,UAAU,gBAAgB,EAAE;AAAA,IAC1C;AAGA,QACE,QAAQ,SAAS,kBACjB,SAAS,YAAY,kBACrB,SAAS,SACT;AACA,YAAM,kBAAkB,SAAS,KAAK;AACtC,WAAK,gBAAgB,IAAI,iBAAiB,CAAC;AAC3C,aAAO,EAAE,GAAG,UAAU,gBAAgB,EAAE;AAAA,IAC1C;AAGA,QACE,QAAQ,SAAS,oBACjB,SAAS,YAAY,oBACrB,SAAS,SACT;AACA,WAAK,gBAAgB,OAAO,QAAQ,SAAS;AAC7C,aAAO;AAAA,IACT;AAGA,UAAM,YAAY,aAAa,OAAO;AACtC,QAAI,CAAC,UAAW,QAAO;AAEvB,UAAM,UAAU,KAAK,gBAAgB,IAAI,SAAS,KAAK;AACvD,UAAM,OAAO,KAAK,WAAW,QAAQ,IAAI,IAAI,UAAU,IAAI;AAC3D,SAAK,gBAAgB,IAAI,WAAW,IAAI;AAExC,WAAO,EAAE,GAAG,UAAU,gBAAgB,KAAK;AAAA,EAC7C;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Type guards and accessor functions for RPC commands and responses.
3
+ *
4
+ * Extracted from types.ts to keep type definitions separate from runtime utilities.
5
+ * These functions provide type-safe access to command fields and response discrimination.
6
+ */
7
+ import type { SessionInfo } from "./types.js";
8
+ import type { RpcCommand, RpcResponse, RpcResponseBase, SessionCommand } from "./types.js";
9
+ /**
10
+ * Get the optional command ID from any RpcCommand.
11
+ */
12
+ export declare function getCommandId(cmd: RpcCommand): string | undefined;
13
+ /**
14
+ * Get the command type as a string.
15
+ */
16
+ export declare function getCommandType(cmd: RpcCommand): string;
17
+ /**
18
+ * Get the sessionId from a command, if present.
19
+ * Returns undefined for server commands that don't have sessionId.
20
+ */
21
+ export declare function getSessionId(cmd: RpcCommand): string | undefined;
22
+ /**
23
+ * Optional causal dependencies for command ordering.
24
+ */
25
+ export declare function getCommandDependsOn(cmd: RpcCommand): string[] | undefined;
26
+ /**
27
+ * Optional optimistic concurrency precondition.
28
+ */
29
+ export declare function getCommandIfSessionVersion(cmd: RpcCommand): number | undefined;
30
+ /**
31
+ * Optional idempotency key for replay-safe command retries.
32
+ */
33
+ export declare function getCommandIdempotencyKey(cmd: RpcCommand): string | undefined;
34
+ /**
35
+ * Type guard: true if command targets a session (has sessionId).
36
+ */
37
+ export declare function isSessionCommand(cmd: RpcCommand): cmd is SessionCommand;
38
+ /**
39
+ * Type guard: true if response is a successful create_session response.
40
+ */
41
+ export declare function isCreateSessionResponse(response: RpcResponse): response is RpcResponseBase & {
42
+ command: "create_session";
43
+ success: true;
44
+ data: {
45
+ sessionId: string;
46
+ sessionInfo: SessionInfo;
47
+ };
48
+ };
49
+ /**
50
+ * Type guard: true if response is a successful switch_session response.
51
+ */
52
+ export declare function isSwitchSessionResponse(response: RpcResponse): response is RpcResponseBase & {
53
+ command: "switch_session";
54
+ success: true;
55
+ data: {
56
+ sessionInfo: SessionInfo;
57
+ };
58
+ };
59
+ //# sourceMappingURL=type-guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-guards.d.ts","sourceRoot":"","sources":["../src/type-guards.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAM3F;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAEhE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAEtD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAGhE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,EAAE,GAAG,SAAS,CAIzE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAE9E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAE5E;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,GAAG,IAAI,cAAc,CAEvE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,IAAI,eAAe,GAAG;IAC5F,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,CAAC;CACvD,CAEA;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,IAAI,eAAe,GAAG;IAC5F,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE;QAAE,WAAW,EAAE,WAAW,CAAA;KAAE,CAAC;CACpC,CAEA"}
@@ -0,0 +1,40 @@
1
+ function getCommandId(cmd) {
2
+ return cmd.id;
3
+ }
4
+ function getCommandType(cmd) {
5
+ return cmd.type;
6
+ }
7
+ function getSessionId(cmd) {
8
+ if ("sessionId" in cmd) return cmd.sessionId;
9
+ return void 0;
10
+ }
11
+ function getCommandDependsOn(cmd) {
12
+ return Array.isArray(cmd.dependsOn) ? cmd.dependsOn.filter((value) => typeof value === "string") : void 0;
13
+ }
14
+ function getCommandIfSessionVersion(cmd) {
15
+ return typeof cmd.ifSessionVersion === "number" ? cmd.ifSessionVersion : void 0;
16
+ }
17
+ function getCommandIdempotencyKey(cmd) {
18
+ return typeof cmd.idempotencyKey === "string" ? cmd.idempotencyKey : void 0;
19
+ }
20
+ function isSessionCommand(cmd) {
21
+ return "sessionId" in cmd;
22
+ }
23
+ function isCreateSessionResponse(response) {
24
+ return response.success && response.command === "create_session";
25
+ }
26
+ function isSwitchSessionResponse(response) {
27
+ return response.success && response.command === "switch_session";
28
+ }
29
+ export {
30
+ getCommandDependsOn,
31
+ getCommandId,
32
+ getCommandIdempotencyKey,
33
+ getCommandIfSessionVersion,
34
+ getCommandType,
35
+ getSessionId,
36
+ isCreateSessionResponse,
37
+ isSessionCommand,
38
+ isSwitchSessionResponse
39
+ };
40
+ //# sourceMappingURL=type-guards.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/type-guards.ts"],
4
+ "sourcesContent": ["/**\n * Type guards and accessor functions for RPC commands and responses.\n *\n * Extracted from types.ts to keep type definitions separate from runtime utilities.\n * These functions provide type-safe access to command fields and response discrimination.\n */\n\nimport type { SessionInfo } from \"./types.js\";\nimport type { RpcCommand, RpcResponse, RpcResponseBase, SessionCommand } from \"./types.js\";\n\n// =============================================================================\n// COMMAND ACCESSORS\n// =============================================================================\n\n/**\n * Get the optional command ID from any RpcCommand.\n */\nexport function getCommandId(cmd: RpcCommand): string | undefined {\n return cmd.id;\n}\n\n/**\n * Get the command type as a string.\n */\nexport function getCommandType(cmd: RpcCommand): string {\n return cmd.type;\n}\n\n/**\n * Get the sessionId from a command, if present.\n * Returns undefined for server commands that don't have sessionId.\n */\nexport function getSessionId(cmd: RpcCommand): string | undefined {\n if (\"sessionId\" in cmd) return cmd.sessionId;\n return undefined;\n}\n\n/**\n * Optional causal dependencies for command ordering.\n */\nexport function getCommandDependsOn(cmd: RpcCommand): string[] | undefined {\n return Array.isArray(cmd.dependsOn)\n ? cmd.dependsOn.filter((value): value is string => typeof value === \"string\")\n : undefined;\n}\n\n/**\n * Optional optimistic concurrency precondition.\n */\nexport function getCommandIfSessionVersion(cmd: RpcCommand): number | undefined {\n return typeof cmd.ifSessionVersion === \"number\" ? cmd.ifSessionVersion : undefined;\n}\n\n/**\n * Optional idempotency key for replay-safe command retries.\n */\nexport function getCommandIdempotencyKey(cmd: RpcCommand): string | undefined {\n return typeof cmd.idempotencyKey === \"string\" ? cmd.idempotencyKey : undefined;\n}\n\n// =============================================================================\n// TYPE GUARDS\n// =============================================================================\n\n/**\n * Type guard: true if command targets a session (has sessionId).\n */\nexport function isSessionCommand(cmd: RpcCommand): cmd is SessionCommand {\n return \"sessionId\" in cmd;\n}\n\n/**\n * Type guard: true if response is a successful create_session response.\n */\nexport function isCreateSessionResponse(response: RpcResponse): response is RpcResponseBase & {\n command: \"create_session\";\n success: true;\n data: { sessionId: string; sessionInfo: SessionInfo };\n} {\n return response.success && response.command === \"create_session\";\n}\n\n/**\n * Type guard: true if response is a successful switch_session response.\n */\nexport function isSwitchSessionResponse(response: RpcResponse): response is RpcResponseBase & {\n command: \"switch_session\";\n success: true;\n data: { sessionInfo: SessionInfo };\n} {\n return response.success && response.command === \"switch_session\";\n}\n"],
5
+ "mappings": "AAiBO,SAAS,aAAa,KAAqC;AAChE,SAAO,IAAI;AACb;AAKO,SAAS,eAAe,KAAyB;AACtD,SAAO,IAAI;AACb;AAMO,SAAS,aAAa,KAAqC;AAChE,MAAI,eAAe,IAAK,QAAO,IAAI;AACnC,SAAO;AACT;AAKO,SAAS,oBAAoB,KAAuC;AACzE,SAAO,MAAM,QAAQ,IAAI,SAAS,IAC9B,IAAI,UAAU,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,IAC1E;AACN;AAKO,SAAS,2BAA2B,KAAqC;AAC9E,SAAO,OAAO,IAAI,qBAAqB,WAAW,IAAI,mBAAmB;AAC3E;AAKO,SAAS,yBAAyB,KAAqC;AAC5E,SAAO,OAAO,IAAI,mBAAmB,WAAW,IAAI,iBAAiB;AACvE;AASO,SAAS,iBAAiB,KAAwC;AACvE,SAAO,eAAe;AACxB;AAKO,SAAS,wBAAwB,UAItC;AACA,SAAO,SAAS,WAAW,SAAS,YAAY;AAClD;AAKO,SAAS,wBAAwB,UAItC;AACA,SAAO,SAAS,WAAW,SAAS,YAAY;AAClD;",
6
+ "names": []
7
+ }