@kadi.build/core 0.0.1-alpha.8 → 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 (126) hide show
  1. package/README.md +362 -1305
  2. package/dist/client.d.ts +573 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +1673 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/errors.d.ts +107 -0
  7. package/dist/errors.d.ts.map +1 -0
  8. package/dist/errors.js +147 -0
  9. package/dist/errors.js.map +1 -0
  10. package/dist/index.d.ts +37 -14
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +40 -23
  13. package/dist/index.js.map +1 -1
  14. package/dist/lockfile.d.ts +190 -0
  15. package/dist/lockfile.d.ts.map +1 -0
  16. package/dist/lockfile.js +373 -0
  17. package/dist/lockfile.js.map +1 -0
  18. package/dist/transports/broker.d.ts +75 -0
  19. package/dist/transports/broker.d.ts.map +1 -0
  20. package/dist/transports/broker.js +383 -0
  21. package/dist/transports/broker.js.map +1 -0
  22. package/dist/transports/native.d.ts +39 -0
  23. package/dist/transports/native.d.ts.map +1 -0
  24. package/dist/transports/native.js +189 -0
  25. package/dist/transports/native.js.map +1 -0
  26. package/dist/transports/stdio.d.ts +46 -0
  27. package/dist/transports/stdio.d.ts.map +1 -0
  28. package/dist/transports/stdio.js +460 -0
  29. package/dist/transports/stdio.js.map +1 -0
  30. package/dist/types.d.ts +664 -0
  31. package/dist/types.d.ts.map +1 -0
  32. package/dist/types.js +16 -0
  33. package/dist/types.js.map +1 -0
  34. package/dist/zod.d.ts +34 -0
  35. package/dist/zod.d.ts.map +1 -0
  36. package/dist/zod.js +60 -0
  37. package/dist/zod.js.map +1 -0
  38. package/package.json +13 -28
  39. package/dist/KadiClient.d.ts +0 -432
  40. package/dist/KadiClient.d.ts.map +0 -1
  41. package/dist/KadiClient.js +0 -1506
  42. package/dist/KadiClient.js.map +0 -1
  43. package/dist/errors/error-codes.d.ts +0 -985
  44. package/dist/errors/error-codes.d.ts.map +0 -1
  45. package/dist/errors/error-codes.js +0 -638
  46. package/dist/errors/error-codes.js.map +0 -1
  47. package/dist/loadAbility.d.ts +0 -105
  48. package/dist/loadAbility.d.ts.map +0 -1
  49. package/dist/loadAbility.js +0 -370
  50. package/dist/loadAbility.js.map +0 -1
  51. package/dist/messages/BrokerMessages.d.ts +0 -84
  52. package/dist/messages/BrokerMessages.d.ts.map +0 -1
  53. package/dist/messages/BrokerMessages.js +0 -125
  54. package/dist/messages/BrokerMessages.js.map +0 -1
  55. package/dist/messages/MessageBuilder.d.ts +0 -83
  56. package/dist/messages/MessageBuilder.d.ts.map +0 -1
  57. package/dist/messages/MessageBuilder.js +0 -144
  58. package/dist/messages/MessageBuilder.js.map +0 -1
  59. package/dist/schemas/events.schemas.d.ts +0 -177
  60. package/dist/schemas/events.schemas.d.ts.map +0 -1
  61. package/dist/schemas/events.schemas.js +0 -265
  62. package/dist/schemas/events.schemas.js.map +0 -1
  63. package/dist/schemas/index.d.ts +0 -3
  64. package/dist/schemas/index.d.ts.map +0 -1
  65. package/dist/schemas/index.js +0 -4
  66. package/dist/schemas/index.js.map +0 -1
  67. package/dist/schemas/kadi.schemas.d.ts +0 -70
  68. package/dist/schemas/kadi.schemas.d.ts.map +0 -1
  69. package/dist/schemas/kadi.schemas.js +0 -120
  70. package/dist/schemas/kadi.schemas.js.map +0 -1
  71. package/dist/transports/BrokerTransport.d.ts +0 -102
  72. package/dist/transports/BrokerTransport.d.ts.map +0 -1
  73. package/dist/transports/BrokerTransport.js +0 -177
  74. package/dist/transports/BrokerTransport.js.map +0 -1
  75. package/dist/transports/NativeTransport.d.ts +0 -82
  76. package/dist/transports/NativeTransport.d.ts.map +0 -1
  77. package/dist/transports/NativeTransport.js +0 -263
  78. package/dist/transports/NativeTransport.js.map +0 -1
  79. package/dist/transports/StdioTransport.d.ts +0 -112
  80. package/dist/transports/StdioTransport.d.ts.map +0 -1
  81. package/dist/transports/StdioTransport.js +0 -450
  82. package/dist/transports/StdioTransport.js.map +0 -1
  83. package/dist/transports/Transport.d.ts +0 -93
  84. package/dist/transports/Transport.d.ts.map +0 -1
  85. package/dist/transports/Transport.js +0 -13
  86. package/dist/transports/Transport.js.map +0 -1
  87. package/dist/types/broker.d.ts +0 -31
  88. package/dist/types/broker.d.ts.map +0 -1
  89. package/dist/types/broker.js +0 -6
  90. package/dist/types/broker.js.map +0 -1
  91. package/dist/types/core.d.ts +0 -139
  92. package/dist/types/core.d.ts.map +0 -1
  93. package/dist/types/core.js +0 -26
  94. package/dist/types/core.js.map +0 -1
  95. package/dist/types/events.d.ts +0 -186
  96. package/dist/types/events.d.ts.map +0 -1
  97. package/dist/types/events.js +0 -16
  98. package/dist/types/events.js.map +0 -1
  99. package/dist/types/index.d.ts +0 -9
  100. package/dist/types/index.d.ts.map +0 -1
  101. package/dist/types/index.js +0 -13
  102. package/dist/types/index.js.map +0 -1
  103. package/dist/types/protocol.d.ts +0 -160
  104. package/dist/types/protocol.d.ts.map +0 -1
  105. package/dist/types/protocol.js +0 -5
  106. package/dist/types/protocol.js.map +0 -1
  107. package/dist/utils/agentUtils.d.ts +0 -187
  108. package/dist/utils/agentUtils.d.ts.map +0 -1
  109. package/dist/utils/agentUtils.js +0 -185
  110. package/dist/utils/agentUtils.js.map +0 -1
  111. package/dist/utils/commandUtils.d.ts +0 -45
  112. package/dist/utils/commandUtils.d.ts.map +0 -1
  113. package/dist/utils/commandUtils.js +0 -145
  114. package/dist/utils/commandUtils.js.map +0 -1
  115. package/dist/utils/configUtils.d.ts +0 -55
  116. package/dist/utils/configUtils.d.ts.map +0 -1
  117. package/dist/utils/configUtils.js +0 -100
  118. package/dist/utils/configUtils.js.map +0 -1
  119. package/dist/utils/logger.d.ts +0 -59
  120. package/dist/utils/logger.d.ts.map +0 -1
  121. package/dist/utils/logger.js +0 -122
  122. package/dist/utils/logger.js.map +0 -1
  123. package/dist/utils/pathUtils.d.ts +0 -48
  124. package/dist/utils/pathUtils.d.ts.map +0 -1
  125. package/dist/utils/pathUtils.js +0 -128
  126. package/dist/utils/pathUtils.js.map +0 -1
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Lock file resolution for kadi-core v0.1.0
3
+ *
4
+ * This module handles reading agent-lock.json and resolving ability paths.
5
+ * The lock file is generated by kadi-install and contains:
6
+ * - Exact versions of installed abilities
7
+ * - Paths where abilities are installed
8
+ * - Integrity hashes for verification
9
+ *
10
+ * Flow:
11
+ * 1. Find project root (where agent.json lives)
12
+ * 2. Read agent-lock.json from project root
13
+ * 3. Look up ability by name to get its installed path
14
+ */
15
+ import type { AgentLockFile, AbilityLockEntry, ResolvedScript } from './types.js';
16
+ /**
17
+ * Find the project root by walking up the directory tree.
18
+ * Looks for agent.json, which marks the root of a KADI project.
19
+ *
20
+ * @param startDir - Directory to start searching from (default: process.cwd())
21
+ * @returns Absolute path to the project root
22
+ * @throws KadiError if no agent.json is found
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const root = await findProjectRoot();
27
+ * // '/Users/kassi/my-project'
28
+ *
29
+ * const root = await findProjectRoot('/Users/kassi/my-project/src/deep/folder');
30
+ * // '/Users/kassi/my-project'
31
+ * ```
32
+ */
33
+ export declare function findProjectRoot(startDir?: string): Promise<string>;
34
+ /**
35
+ * Read and parse agent-lock.json from a project root.
36
+ *
37
+ * @param projectRoot - Absolute path to the project root
38
+ * @returns Parsed lock file contents
39
+ * @throws KadiError if lock file doesn't exist or is invalid
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const lockFile = await readLockFile('/Users/kassi/my-project');
44
+ * console.log(lockFile.abilities);
45
+ * // { 'calculator@1.0.0': { resolved: 'abilities/calculator@1.0.0', ... } }
46
+ * ```
47
+ */
48
+ export declare function readLockFile(projectRoot: string): Promise<AgentLockFile>;
49
+ /**
50
+ * Find an ability entry in the lock file by name.
51
+ * Keys in the lock file are "name@version", this function matches by name only.
52
+ *
53
+ * @param lockFile - The parsed lock file
54
+ * @param name - Ability name to find (without version)
55
+ * @returns The ability entry, or null if not found
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const entry = findAbilityEntry(lockFile, 'calculator');
60
+ * // Returns entry for 'calculator@1.0.0' (or whatever version is installed)
61
+ * ```
62
+ */
63
+ export declare function findAbilityEntry(lockFile: AgentLockFile, name: string): AbilityLockEntry | null;
64
+ /**
65
+ * Get all installed ability names from the lock file.
66
+ * Useful for error messages listing available abilities.
67
+ *
68
+ * @param lockFile - The parsed lock file
69
+ * @returns Array of ability names (without versions)
70
+ */
71
+ export declare function getInstalledAbilityNames(lockFile: AgentLockFile): string[];
72
+ /**
73
+ * Resolve the absolute path to an installed ability.
74
+ * This is the main function used by loadNative() and loadStdio().
75
+ *
76
+ * Flow:
77
+ * 1. Find project root (if not provided)
78
+ * 2. Read agent-lock.json
79
+ * 3. Look up ability by name
80
+ * 4. Return absolute path to the ability
81
+ *
82
+ * @param name - Ability name to resolve
83
+ * @param projectRoot - Project root (will be auto-detected if not provided)
84
+ * @returns Absolute path to the ability directory
85
+ * @throws KadiError if ability not found
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * const path = await resolveAbilityPath('calculator');
90
+ * // '/Users/kassi/my-project/abilities/calculator@1.0.0'
91
+ * ```
92
+ */
93
+ export declare function resolveAbilityPath(name: string, projectRoot?: string): Promise<string>;
94
+ /**
95
+ * Get full ability entry with resolved path.
96
+ * Returns more information than resolveAbilityPath() for cases where
97
+ * you need the version, type, or other metadata.
98
+ *
99
+ * @param name - Ability name to resolve
100
+ * @param projectRoot - Project root (will be auto-detected if not provided)
101
+ * @returns Ability entry with absolute path added
102
+ */
103
+ export declare function resolveAbilityEntry(name: string, projectRoot?: string): Promise<AbilityLockEntry & {
104
+ absolutePath: string;
105
+ }>;
106
+ /**
107
+ * Parsed script command ready for spawning a child process.
108
+ */
109
+ interface ParsedScript {
110
+ /** The command to execute (e.g., 'python3', 'node') */
111
+ command: string;
112
+ /** Arguments to pass to the command */
113
+ args: string[];
114
+ }
115
+ /**
116
+ * Parse a script string into command and arguments.
117
+ *
118
+ * This is a simple parser that splits on whitespace.
119
+ * For most use cases (e.g., "python3 main.py --debug"), this works fine.
120
+ *
121
+ * Note: Does not handle quoted arguments with spaces (e.g., "node 'my file.js'").
122
+ * For complex cases, users should use explicit command/args.
123
+ *
124
+ * @param script - Script string from agent.json (e.g., "python3 main.py --verbose")
125
+ * @returns Parsed command and arguments
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * parseScriptCommand('python3 main.py --debug')
130
+ * // → { command: 'python3', args: ['main.py', '--debug'] }
131
+ *
132
+ * parseScriptCommand('node dist/server.js')
133
+ * // → { command: 'node', args: ['dist/server.js'] }
134
+ * ```
135
+ */
136
+ export declare function parseScriptCommand(script: string): ParsedScript;
137
+ /**
138
+ * Minimal agent.json structure for script resolution.
139
+ * We only need the scripts section.
140
+ */
141
+ interface AbilityAgentJson {
142
+ name?: string;
143
+ scripts?: Record<string, string>;
144
+ }
145
+ /**
146
+ * Read an ability's agent.json file.
147
+ *
148
+ * @param abilityPath - Absolute path to the ability directory
149
+ * @returns Parsed agent.json contents
150
+ * @throws KadiError if agent.json doesn't exist or is invalid
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * const agentJson = await readAbilityAgentJson('/path/to/ability');
155
+ * console.log(agentJson.scripts?.start);
156
+ * // → "python3 main.py"
157
+ * ```
158
+ */
159
+ export declare function readAbilityAgentJson(abilityPath: string): Promise<AbilityAgentJson>;
160
+ /**
161
+ * Resolve a script command for an ability.
162
+ *
163
+ * This is the main function used by loadStdio() when in script resolution mode.
164
+ *
165
+ * Flow:
166
+ * 1. Resolve ability path from agent-lock.json
167
+ * 2. Read ability's agent.json
168
+ * 3. Get the requested script (default: 'start')
169
+ * 4. Parse the script into command and args
170
+ * 5. Resolve paths relative to ability directory
171
+ *
172
+ * @param name - Ability name to resolve
173
+ * @param scriptName - Which script to use (default: 'start')
174
+ * @param projectRoot - Project root (auto-detected if not provided)
175
+ * @returns Command, args, and working directory for spawning the process
176
+ *
177
+ * @example
178
+ * ```typescript
179
+ * // Uses scripts.start by default
180
+ * const { command, args, cwd } = await resolveAbilityScript('image-processor');
181
+ * // → { command: 'python3', args: ['main.py'], cwd: '/path/to/ability' }
182
+ *
183
+ * // Use a specific script
184
+ * const { command, args, cwd } = await resolveAbilityScript('image-processor', 'dev');
185
+ * // → { command: 'python3', args: ['main.py', '--debug'], cwd: '/path/to/ability' }
186
+ * ```
187
+ */
188
+ export declare function resolveAbilityScript(name: string, scriptName?: string, projectRoot?: string): Promise<ResolvedScript>;
189
+ export {};
190
+ //# sourceMappingURL=lockfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockfile.d.ts","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOlF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BvF;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA+B9E;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAE,MAAM,GACX,gBAAgB,GAAG,IAAI,CAsBzB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,EAAE,CAW1E;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CA6BjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,gBAAgB,GAAG;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAyBtD;AAMD;;GAEG;AACH,UAAU,YAAY;IACpB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAEhB,uCAAuC;IACvC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAoC/D;AAED;;;GAGG;AACH,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6BzF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,MAAgB,EAC5B,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,CAAC,CAiDzB"}
@@ -0,0 +1,373 @@
1
+ /**
2
+ * Lock file resolution for kadi-core v0.1.0
3
+ *
4
+ * This module handles reading agent-lock.json and resolving ability paths.
5
+ * The lock file is generated by kadi-install and contains:
6
+ * - Exact versions of installed abilities
7
+ * - Paths where abilities are installed
8
+ * - Integrity hashes for verification
9
+ *
10
+ * Flow:
11
+ * 1. Find project root (where agent.json lives)
12
+ * 2. Read agent-lock.json from project root
13
+ * 3. Look up ability by name to get its installed path
14
+ */
15
+ import { readFile } from 'fs/promises';
16
+ import { join, dirname } from 'path';
17
+ import { KadiError } from './errors.js';
18
+ // ═══════════════════════════════════════════════════════════════════════
19
+ // PROJECT ROOT DISCOVERY
20
+ // ═══════════════════════════════════════════════════════════════════════
21
+ /**
22
+ * Find the project root by walking up the directory tree.
23
+ * Looks for agent.json, which marks the root of a KADI project.
24
+ *
25
+ * @param startDir - Directory to start searching from (default: process.cwd())
26
+ * @returns Absolute path to the project root
27
+ * @throws KadiError if no agent.json is found
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const root = await findProjectRoot();
32
+ * // '/Users/kassi/my-project'
33
+ *
34
+ * const root = await findProjectRoot('/Users/kassi/my-project/src/deep/folder');
35
+ * // '/Users/kassi/my-project'
36
+ * ```
37
+ */
38
+ export async function findProjectRoot(startDir = process.cwd()) {
39
+ let current = startDir;
40
+ // Walk up the directory tree looking for agent.json
41
+ while (current !== dirname(current)) {
42
+ const agentJsonPath = join(current, 'agent.json');
43
+ try {
44
+ // Try to read agent.json - if it exists, this is the project root
45
+ await readFile(agentJsonPath);
46
+ return current;
47
+ }
48
+ catch {
49
+ // File doesn't exist, try parent directory
50
+ current = dirname(current);
51
+ }
52
+ }
53
+ // Reached filesystem root without finding agent.json
54
+ throw new KadiError('Could not find project root', 'PROJECT_ROOT_NOT_FOUND', {
55
+ searched: startDir,
56
+ hint: 'Make sure you are in a KADI project directory with an agent.json file',
57
+ });
58
+ }
59
+ // ═══════════════════════════════════════════════════════════════════════
60
+ // LOCK FILE READING
61
+ // ═══════════════════════════════════════════════════════════════════════
62
+ /**
63
+ * Read and parse agent-lock.json from a project root.
64
+ *
65
+ * @param projectRoot - Absolute path to the project root
66
+ * @returns Parsed lock file contents
67
+ * @throws KadiError if lock file doesn't exist or is invalid
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const lockFile = await readLockFile('/Users/kassi/my-project');
72
+ * console.log(lockFile.abilities);
73
+ * // { 'calculator@1.0.0': { resolved: 'abilities/calculator@1.0.0', ... } }
74
+ * ```
75
+ */
76
+ export async function readLockFile(projectRoot) {
77
+ const lockPath = join(projectRoot, 'agent-lock.json');
78
+ let content;
79
+ try {
80
+ content = await readFile(lockPath, 'utf-8');
81
+ }
82
+ catch (error) {
83
+ throw new KadiError('agent-lock.json not found', 'LOCKFILE_NOT_FOUND', {
84
+ searched: lockPath,
85
+ hint: 'Run `kadi install` to generate the lock file',
86
+ alternative: 'Or specify an explicit path when loading abilities',
87
+ });
88
+ }
89
+ try {
90
+ return JSON.parse(content);
91
+ }
92
+ catch (error) {
93
+ throw new KadiError('Failed to parse agent-lock.json', 'LOCKFILE_PARSE_ERROR', {
94
+ path: lockPath,
95
+ reason: error instanceof Error ? error.message : 'Invalid JSON',
96
+ hint: 'The lock file may be corrupted. Try running `kadi install` again',
97
+ });
98
+ }
99
+ }
100
+ // ═══════════════════════════════════════════════════════════════════════
101
+ // ABILITY LOOKUP
102
+ // ═══════════════════════════════════════════════════════════════════════
103
+ /**
104
+ * Find an ability entry in the lock file by name.
105
+ * Keys in the lock file are "name@version", this function matches by name only.
106
+ *
107
+ * @param lockFile - The parsed lock file
108
+ * @param name - Ability name to find (without version)
109
+ * @returns The ability entry, or null if not found
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const entry = findAbilityEntry(lockFile, 'calculator');
114
+ * // Returns entry for 'calculator@1.0.0' (or whatever version is installed)
115
+ * ```
116
+ */
117
+ export function findAbilityEntry(lockFile, name) {
118
+ // Lock file keys are "name@version", we need to match by name only
119
+ for (const [key, entry] of Object.entries(lockFile.abilities)) {
120
+ // Find the last @ to split name from version
121
+ // (handles scoped packages like @kadi.build/ability@1.0.0)
122
+ const lastAtIndex = key.lastIndexOf('@');
123
+ if (lastAtIndex === -1) {
124
+ // No @ in key - shouldn't happen, but check anyway
125
+ if (key === name) {
126
+ return entry;
127
+ }
128
+ continue;
129
+ }
130
+ const abilityName = key.substring(0, lastAtIndex);
131
+ if (abilityName === name) {
132
+ return entry;
133
+ }
134
+ }
135
+ return null;
136
+ }
137
+ /**
138
+ * Get all installed ability names from the lock file.
139
+ * Useful for error messages listing available abilities.
140
+ *
141
+ * @param lockFile - The parsed lock file
142
+ * @returns Array of ability names (without versions)
143
+ */
144
+ export function getInstalledAbilityNames(lockFile) {
145
+ const names = [];
146
+ for (const key of Object.keys(lockFile.abilities)) {
147
+ const lastAtIndex = key.lastIndexOf('@');
148
+ if (lastAtIndex !== -1) {
149
+ names.push(key.substring(0, lastAtIndex));
150
+ }
151
+ }
152
+ return names;
153
+ }
154
+ // ═══════════════════════════════════════════════════════════════════════
155
+ // PATH RESOLUTION
156
+ // ═══════════════════════════════════════════════════════════════════════
157
+ /**
158
+ * Resolve the absolute path to an installed ability.
159
+ * This is the main function used by loadNative() and loadStdio().
160
+ *
161
+ * Flow:
162
+ * 1. Find project root (if not provided)
163
+ * 2. Read agent-lock.json
164
+ * 3. Look up ability by name
165
+ * 4. Return absolute path to the ability
166
+ *
167
+ * @param name - Ability name to resolve
168
+ * @param projectRoot - Project root (will be auto-detected if not provided)
169
+ * @returns Absolute path to the ability directory
170
+ * @throws KadiError if ability not found
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * const path = await resolveAbilityPath('calculator');
175
+ * // '/Users/kassi/my-project/abilities/calculator@1.0.0'
176
+ * ```
177
+ */
178
+ export async function resolveAbilityPath(name, projectRoot) {
179
+ // Find project root if not provided
180
+ const root = projectRoot ?? await findProjectRoot();
181
+ // Read lock file
182
+ const lockFile = await readLockFile(root);
183
+ // Find ability entry
184
+ const entry = findAbilityEntry(lockFile, name);
185
+ if (!entry) {
186
+ // Build helpful error message with available abilities
187
+ const available = getInstalledAbilityNames(lockFile);
188
+ throw new KadiError(`Ability "${name}" not found in agent-lock.json`, 'ABILITY_NOT_FOUND', {
189
+ abilityName: name,
190
+ searched: join(root, 'agent-lock.json'),
191
+ available: available.length > 0 ? available : undefined,
192
+ hint: `Run \`kadi install ${name}\` to install it`,
193
+ alternative: 'Or specify an explicit path: { path: "./path/to/ability" }',
194
+ });
195
+ }
196
+ // Build absolute path from project root + relative path in lock file
197
+ return join(root, entry.resolved);
198
+ }
199
+ /**
200
+ * Get full ability entry with resolved path.
201
+ * Returns more information than resolveAbilityPath() for cases where
202
+ * you need the version, type, or other metadata.
203
+ *
204
+ * @param name - Ability name to resolve
205
+ * @param projectRoot - Project root (will be auto-detected if not provided)
206
+ * @returns Ability entry with absolute path added
207
+ */
208
+ export async function resolveAbilityEntry(name, projectRoot) {
209
+ const root = projectRoot ?? await findProjectRoot();
210
+ const lockFile = await readLockFile(root);
211
+ const entry = findAbilityEntry(lockFile, name);
212
+ if (!entry) {
213
+ const available = getInstalledAbilityNames(lockFile);
214
+ throw new KadiError(`Ability "${name}" not found in agent-lock.json`, 'ABILITY_NOT_FOUND', {
215
+ abilityName: name,
216
+ searched: join(root, 'agent-lock.json'),
217
+ available: available.length > 0 ? available : undefined,
218
+ hint: `Run \`kadi install ${name}\` to install it`,
219
+ alternative: 'Or specify an explicit path: { path: "./path/to/ability" }',
220
+ });
221
+ }
222
+ return {
223
+ ...entry,
224
+ absolutePath: join(root, entry.resolved),
225
+ };
226
+ }
227
+ /**
228
+ * Parse a script string into command and arguments.
229
+ *
230
+ * This is a simple parser that splits on whitespace.
231
+ * For most use cases (e.g., "python3 main.py --debug"), this works fine.
232
+ *
233
+ * Note: Does not handle quoted arguments with spaces (e.g., "node 'my file.js'").
234
+ * For complex cases, users should use explicit command/args.
235
+ *
236
+ * @param script - Script string from agent.json (e.g., "python3 main.py --verbose")
237
+ * @returns Parsed command and arguments
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * parseScriptCommand('python3 main.py --debug')
242
+ * // → { command: 'python3', args: ['main.py', '--debug'] }
243
+ *
244
+ * parseScriptCommand('node dist/server.js')
245
+ * // → { command: 'node', args: ['dist/server.js'] }
246
+ * ```
247
+ */
248
+ export function parseScriptCommand(script) {
249
+ // Check for quotes — we can't handle these properly with simple split
250
+ // Users with complex commands should use explicit command/args
251
+ if (script.includes("'") || script.includes('"')) {
252
+ throw new KadiError('Script contains quotes which are not supported', 'INVALID_CONFIG', {
253
+ script,
254
+ hint: 'Scripts with quoted arguments cannot be parsed. Provide command and args separately.',
255
+ example: '{ command: "node", args: ["my file.js"] }',
256
+ });
257
+ }
258
+ // Trim and split on whitespace
259
+ const parts = script.trim().split(/\s+/);
260
+ // Extract command (first element)
261
+ const command = parts[0];
262
+ if (!command) {
263
+ throw new KadiError('Script is empty', 'INVALID_CONFIG', {
264
+ script,
265
+ hint: 'The script should contain a command (e.g., "python3 main.py")',
266
+ });
267
+ }
268
+ return {
269
+ command,
270
+ args: parts.slice(1),
271
+ };
272
+ }
273
+ /**
274
+ * Read an ability's agent.json file.
275
+ *
276
+ * @param abilityPath - Absolute path to the ability directory
277
+ * @returns Parsed agent.json contents
278
+ * @throws KadiError if agent.json doesn't exist or is invalid
279
+ *
280
+ * @example
281
+ * ```typescript
282
+ * const agentJson = await readAbilityAgentJson('/path/to/ability');
283
+ * console.log(agentJson.scripts?.start);
284
+ * // → "python3 main.py"
285
+ * ```
286
+ */
287
+ export async function readAbilityAgentJson(abilityPath) {
288
+ const agentJsonPath = join(abilityPath, 'agent.json');
289
+ let content;
290
+ try {
291
+ content = await readFile(agentJsonPath, 'utf-8');
292
+ }
293
+ catch (error) {
294
+ throw new KadiError(`Ability is missing agent.json`, 'ABILITY_LOAD_FAILED', {
295
+ path: agentJsonPath,
296
+ hint: 'The ability directory must contain an agent.json file with a scripts section',
297
+ });
298
+ }
299
+ try {
300
+ return JSON.parse(content);
301
+ }
302
+ catch (error) {
303
+ throw new KadiError(`Failed to parse ability's agent.json`, 'ABILITY_LOAD_FAILED', {
304
+ path: agentJsonPath,
305
+ reason: error instanceof Error ? error.message : 'Invalid JSON',
306
+ });
307
+ }
308
+ }
309
+ /**
310
+ * Resolve a script command for an ability.
311
+ *
312
+ * This is the main function used by loadStdio() when in script resolution mode.
313
+ *
314
+ * Flow:
315
+ * 1. Resolve ability path from agent-lock.json
316
+ * 2. Read ability's agent.json
317
+ * 3. Get the requested script (default: 'start')
318
+ * 4. Parse the script into command and args
319
+ * 5. Resolve paths relative to ability directory
320
+ *
321
+ * @param name - Ability name to resolve
322
+ * @param scriptName - Which script to use (default: 'start')
323
+ * @param projectRoot - Project root (auto-detected if not provided)
324
+ * @returns Command, args, and working directory for spawning the process
325
+ *
326
+ * @example
327
+ * ```typescript
328
+ * // Uses scripts.start by default
329
+ * const { command, args, cwd } = await resolveAbilityScript('image-processor');
330
+ * // → { command: 'python3', args: ['main.py'], cwd: '/path/to/ability' }
331
+ *
332
+ * // Use a specific script
333
+ * const { command, args, cwd } = await resolveAbilityScript('image-processor', 'dev');
334
+ * // → { command: 'python3', args: ['main.py', '--debug'], cwd: '/path/to/ability' }
335
+ * ```
336
+ */
337
+ export async function resolveAbilityScript(name, scriptName = 'start', projectRoot) {
338
+ // Step 1: Resolve ability path from agent-lock.json
339
+ const abilityPath = await resolveAbilityPath(name, projectRoot);
340
+ // Step 2: Read ability's agent.json
341
+ const agentJson = await readAbilityAgentJson(abilityPath);
342
+ // Step 3: Get the requested script
343
+ const scripts = agentJson.scripts;
344
+ if (!scripts) {
345
+ throw new KadiError(`Ability "${name}" has no scripts section in agent.json`, 'INVALID_CONFIG', {
346
+ abilityName: name,
347
+ agentJsonPath: join(abilityPath, 'agent.json'),
348
+ hint: 'Add a "scripts" section with a "start" script to agent.json',
349
+ example: '{ "scripts": { "start": "python3 main.py" } }',
350
+ });
351
+ }
352
+ const script = scripts[scriptName];
353
+ if (!script) {
354
+ // Build helpful error with available scripts
355
+ const availableScripts = Object.keys(scripts).filter(k => scripts[k]); // Filter out empty scripts
356
+ throw new KadiError(`Script "${scriptName}" not found in ability "${name}"`, 'INVALID_CONFIG', {
357
+ abilityName: name,
358
+ requestedScript: scriptName,
359
+ availableScripts: availableScripts.length > 0 ? availableScripts : undefined,
360
+ hint: availableScripts.length > 0
361
+ ? `Available scripts: ${availableScripts.join(', ')}`
362
+ : 'Add scripts to the ability\'s agent.json',
363
+ });
364
+ }
365
+ // Step 4: Parse the script into command and args
366
+ const parsed = parseScriptCommand(script);
367
+ // Step 5: Return with ability path as working directory
368
+ return {
369
+ ...parsed,
370
+ cwd: abilityPath,
371
+ };
372
+ }
373
+ //# sourceMappingURL=lockfile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,0EAA0E;AAC1E,yBAAyB;AACzB,0EAA0E;AAE1E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IACpE,IAAI,OAAO,GAAG,QAAQ,CAAC;IAEvB,oDAAoD;IACpD,OAAO,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAElD,IAAI,CAAC;YACH,kEAAkE;YAClE,MAAM,QAAQ,CAAC,aAAa,CAAC,CAAC;YAC9B,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,MAAM,CAAC;YACP,2CAA2C;YAC3C,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,MAAM,IAAI,SAAS,CACjB,6BAA6B,EAC7B,wBAAwB,EACxB;QACE,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,uEAAuE;KAC9E,CACF,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,oBAAoB;AACpB,0EAA0E;AAE1E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAmB;IACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;IAEtD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,SAAS,CACjB,2BAA2B,EAC3B,oBAAoB,EACpB;YACE,QAAQ,EAAE,QAAQ;YAClB,IAAI,EAAE,8CAA8C;YACpD,WAAW,EAAE,oDAAoD;SAClE,CACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAkB,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,SAAS,CACjB,iCAAiC,EACjC,sBAAsB,EACtB;YACE,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc;YAC/D,IAAI,EAAE,kEAAkE;SACzE,CACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,iBAAiB;AACjB,0EAA0E;AAE1E;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAAuB,EACvB,IAAY;IAEZ,mEAAmE;IACnE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9D,6CAA6C;QAC7C,2DAA2D;QAC3D,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAEzC,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,mDAAmD;YACnD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gBACjB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QAClD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAuB;IAC9D,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAClD,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0EAA0E;AAC1E,kBAAkB;AAClB,0EAA0E;AAE1E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY,EACZ,WAAoB;IAEpB,oCAAoC;IACpC,MAAM,IAAI,GAAG,WAAW,IAAI,MAAM,eAAe,EAAE,CAAC;IAEpD,iBAAiB;IACjB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IAE1C,qBAAqB;IACrB,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAE/C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,uDAAuD;QACvD,MAAM,SAAS,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;QAErD,MAAM,IAAI,SAAS,CACjB,YAAY,IAAI,gCAAgC,EAChD,mBAAmB,EACnB;YACE,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC;YACvC,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACvD,IAAI,EAAE,sBAAsB,IAAI,kBAAkB;YAClD,WAAW,EAAE,4DAA4D;SAC1E,CACF,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAY,EACZ,WAAoB;IAEpB,MAAM,IAAI,GAAG,WAAW,IAAI,MAAM,eAAe,EAAE,CAAC;IACpD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAE/C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,SAAS,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;QAErD,MAAM,IAAI,SAAS,CACjB,YAAY,IAAI,gCAAgC,EAChD,mBAAmB,EACnB;YACE,WAAW,EAAE,IAAI;YACjB,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC;YACvC,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACvD,IAAI,EAAE,sBAAsB,IAAI,kBAAkB;YAClD,WAAW,EAAE,4DAA4D;SAC1E,CACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,GAAG,KAAK;QACR,YAAY,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC;KACzC,CAAC;AACJ,CAAC;AAiBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,sEAAsE;IACtE,+DAA+D;IAC/D,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,SAAS,CACjB,gDAAgD,EAChD,gBAAgB,EAChB;YACE,MAAM;YACN,IAAI,EAAE,sFAAsF;YAC5F,OAAO,EAAE,2CAA2C;SACrD,CACF,CAAC;IACJ,CAAC;IAED,+BAA+B;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAEzC,kCAAkC;IAClC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEzB,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,SAAS,CACjB,iBAAiB,EACjB,gBAAgB,EAChB;YACE,MAAM;YACN,IAAI,EAAE,+DAA+D;SACtE,CACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO;QACP,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;KACrB,CAAC;AACJ,CAAC;AAWD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,WAAmB;IAC5D,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IAEtD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,SAAS,CACjB,+BAA+B,EAC/B,qBAAqB,EACrB;YACE,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,8EAA8E;SACrF,CACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAqB,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,SAAS,CACjB,sCAAsC,EACtC,qBAAqB,EACrB;YACE,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc;SAChE,CACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAY,EACZ,aAAqB,OAAO,EAC5B,WAAoB;IAEpB,oDAAoD;IACpD,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAEhE,oCAAoC;IACpC,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAE1D,mCAAmC;IACnC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;IAClC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,SAAS,CACjB,YAAY,IAAI,wCAAwC,EACxD,gBAAgB,EAChB;YACE,WAAW,EAAE,IAAI;YACjB,aAAa,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC;YAC9C,IAAI,EAAE,6DAA6D;YACnE,OAAO,EAAE,+CAA+C;SACzD,CACF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,6CAA6C;QAC7C,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B;QAElG,MAAM,IAAI,SAAS,CACjB,WAAW,UAAU,2BAA2B,IAAI,GAAG,EACvD,gBAAgB,EAChB;YACE,WAAW,EAAE,IAAI;YACjB,eAAe,EAAE,UAAU;YAC3B,gBAAgB,EAAE,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS;YAC5E,IAAI,EAAE,gBAAgB,CAAC,MAAM,GAAG,CAAC;gBAC/B,CAAC,CAAC,sBAAsB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACrD,CAAC,CAAC,0CAA0C;SAC/C,CACF,CAAC;IACJ,CAAC;IAED,iDAAiD;IACjD,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE1C,wDAAwD;IACxD,OAAO;QACL,GAAG,MAAM;QACT,GAAG,EAAE,WAAW;KACjB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Broker transport for kadi-core v0.1.0
3
+ *
4
+ * Loads abilities that run on REMOTE agents connected to a broker.
5
+ * Communication happens via WebSocket using JSON-RPC.
6
+ *
7
+ * Protocol flow for invoking a remote tool:
8
+ * 1. Client sends kadi.ability.request → broker returns { status: 'pending', requestId }
9
+ * 2. Broker forwards request to provider agent
10
+ * 3. Provider executes tool and sends result back to broker
11
+ * 4. Broker sends kadi.ability.response notification with the actual result
12
+ *
13
+ * This transport doesn't manage the broker connection itself.
14
+ * It receives a BrokerState from KadiClient and uses it for communication.
15
+ *
16
+ * ═══════════════════════════════════════════════════════════════════════════════
17
+ * WORKAROUND NOTE: Ability Discovery
18
+ * ═══════════════════════════════════════════════════════════════════════════════
19
+ *
20
+ * The current broker is TOOL-CENTRIC (tracks tools, not abilities). There's no
21
+ * direct API to ask "What tools does agent X provide?"
22
+ *
23
+ * CURRENT WORKAROUND:
24
+ * 1. Call kadi.ability.list with includeProviders: true (fetches ALL tools)
25
+ * 2. Filter tools where provider.displayName matches the ability name
26
+ * 3. Use the provider's agentId for routing via _kadi hints
27
+ *
28
+ * FUTURE: When the broker implements kadi.agent.discover (see design doc at
29
+ * kadi-broker/docs/design/ABILITY_CENTRIC_DISCOVERY.md), replace the
30
+ * discoverAbilityWorkaround() function with a direct API call.
31
+ * ═══════════════════════════════════════════════════════════════════════════════
32
+ */
33
+ import type { LoadedAbility, BrokerState } from '../types.js';
34
+ /**
35
+ * Options for creating a broker transport.
36
+ */
37
+ export interface BrokerTransportOptions {
38
+ /** The broker connection to use */
39
+ broker: BrokerState;
40
+ /** Timeout for requests in milliseconds (default: 30000) */
41
+ requestTimeout?: number;
42
+ /** Networks to filter by when discovering (default: all) */
43
+ networks?: string[];
44
+ }
45
+ /**
46
+ * Load a remote ability via broker.
47
+ *
48
+ * This discovers an agent providing the ability and returns a LoadedAbility
49
+ * interface that invokes tools via the broker, consistently routing to that
50
+ * specific agent.
51
+ *
52
+ * @param abilityName - Name of the ability to load (matches agent's displayName)
53
+ * @param options - Broker connection and options
54
+ * @returns LoadedAbility that can invoke tools remotely
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * // The broker state comes from KadiClient
59
+ * const brokerState = client.getBrokerState('production');
60
+ *
61
+ * // Load a remote ability
62
+ * const analyzer = await loadBrokerTransport('text-analyzer', {
63
+ * broker: brokerState,
64
+ * requestTimeout: 60000,
65
+ * });
66
+ *
67
+ * // Invoke tools on the remote agent
68
+ * const result = await analyzer.invoke('analyze', { text: 'hello' });
69
+ *
70
+ * // All invocations go to the same agent (consistent routing)
71
+ * const result2 = await analyzer.invoke('summarize', { text: 'world' });
72
+ * ```
73
+ */
74
+ export declare function loadBrokerTransport(abilityName: string, options: BrokerTransportOptions): Promise<LoadedAbility>;
75
+ //# sourceMappingURL=broker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../src/transports/broker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EACV,aAAa,EAEb,WAAW,EAGZ,MAAM,aAAa,CAAC;AAoDrB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,mCAAmC;IACnC,MAAM,EAAE,WAAW,CAAC;IAEpB,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAkUD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,aAAa,CAAC,CAoGxB"}