@kadi.build/core 0.0.1-alpha.2 → 0.0.1-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1145 -216
- package/examples/example-abilities/echo-js/README.md +131 -0
- package/examples/example-abilities/echo-js/agent.json +63 -0
- package/examples/example-abilities/echo-js/package.json +24 -0
- package/examples/example-abilities/echo-js/service.js +43 -0
- package/examples/example-abilities/hash-go/agent.json +53 -0
- package/examples/example-abilities/hash-go/cmd/hash_ability/main.go +340 -0
- package/examples/example-abilities/hash-go/go.mod +3 -0
- package/examples/example-agent/abilities/echo-js/0.0.1/README.md +131 -0
- package/examples/example-agent/abilities/echo-js/0.0.1/agent.json +63 -0
- package/examples/example-agent/abilities/echo-js/0.0.1/package-lock.json +93 -0
- package/examples/example-agent/abilities/echo-js/0.0.1/package.json +24 -0
- package/examples/example-agent/abilities/echo-js/0.0.1/service.js +41 -0
- package/examples/example-agent/abilities/hash-go/0.0.1/agent.json +53 -0
- package/examples/example-agent/abilities/hash-go/0.0.1/bin/hash_ability +0 -0
- package/examples/example-agent/abilities/hash-go/0.0.1/cmd/hash_ability/main.go +340 -0
- package/examples/example-agent/abilities/hash-go/0.0.1/go.mod +3 -0
- package/examples/example-agent/agent.json +39 -0
- package/examples/example-agent/index.js +102 -0
- package/examples/example-agent/package-lock.json +93 -0
- package/examples/example-agent/package.json +17 -0
- package/package.json +4 -2
- package/src/KadiAbility.js +478 -0
- package/src/index.js +65 -0
- package/src/loadAbility.js +1086 -0
- package/src/servers/BaseRpcServer.js +404 -0
- package/src/servers/BrokerRpcServer.js +776 -0
- package/src/servers/StdioRpcServer.js +360 -0
- package/src/transport/BrokerMessageBuilder.js +377 -0
- package/src/transport/IpcMessageBuilder.js +1229 -0
- package/src/utils/agentUtils.js +137 -0
- package/src/utils/commandUtils.js +64 -0
- package/src/utils/configUtils.js +72 -0
- package/src/utils/logger.js +161 -0
- package/src/utils/pathUtils.js +86 -0
- package/broker.js +0 -214
- package/index.js +0 -382
- package/ipc.js +0 -220
- package/ipcInterfaces/pythonAbilityIPC.py +0 -177
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
// Define the paths (these were missing from your agentUtils.js)
|
|
9
|
+
const rootDir = process.cwd();
|
|
10
|
+
const abilitiesDir = path.join(rootDir, 'abilities');
|
|
11
|
+
const projectAgentPath = path.join(rootDir, 'agent.json');
|
|
12
|
+
const kadiCoreAgentPath = path.join(__dirname, '..', 'agent.json');
|
|
13
|
+
|
|
14
|
+
// You'll need to get these from pathUtils or define them here
|
|
15
|
+
// For now, I'll import them from pathUtils
|
|
16
|
+
import { kadiAgentPath, kadiExecDir, kadiRootDir } from './pathUtils.js';
|
|
17
|
+
|
|
18
|
+
//Gets the agent.json for the ability, so dependencies can be installed
|
|
19
|
+
export function getAbilityJSON(abilityName, abilityVersion) {
|
|
20
|
+
//Get the agent.json for the ability
|
|
21
|
+
let abilityPath = path.join(
|
|
22
|
+
rootDir,
|
|
23
|
+
'abilities',
|
|
24
|
+
abilityName,
|
|
25
|
+
abilityVersion,
|
|
26
|
+
'agent.json'
|
|
27
|
+
);
|
|
28
|
+
let abilityJSON = fs.readFileSync(abilityPath, 'utf8');
|
|
29
|
+
abilityJSON = JSON.parse(abilityJSON);
|
|
30
|
+
return abilityJSON;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//Gets the file path for the ability agent.json
|
|
34
|
+
export function getAbilityJSONPath(abilityName, abilityVersion) {
|
|
35
|
+
return path.join(
|
|
36
|
+
rootDir,
|
|
37
|
+
'abilities',
|
|
38
|
+
abilityName,
|
|
39
|
+
abilityVersion,
|
|
40
|
+
'agent.json'
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//Gets the abilities directory
|
|
45
|
+
export function getAbilitiesDir() {
|
|
46
|
+
return abilitiesDir;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//Gets the agent.json for the ability, so dependencies can be installed
|
|
50
|
+
export function getProjectJSON() {
|
|
51
|
+
//Get the agent.json for kadi
|
|
52
|
+
let projectJSON = fs.readFileSync(projectAgentPath, 'utf8');
|
|
53
|
+
projectJSON = JSON.parse(projectJSON);
|
|
54
|
+
return projectJSON;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
//Get the file path for the project agent.json
|
|
58
|
+
export function getProjectJSONPath() {
|
|
59
|
+
return projectAgentPath;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
//Get Kadi Core agent.json
|
|
63
|
+
export function getKadiCoreJSON() {
|
|
64
|
+
//Get the agent.json for kadi
|
|
65
|
+
let kadiCoreJSON = fs.readFileSync(kadiCoreAgentPath, 'utf8');
|
|
66
|
+
kadiCoreJSON = JSON.parse(kadiCoreJSON);
|
|
67
|
+
return kadiCoreJSON;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//Get the file path for the KADI Core Agent.json
|
|
71
|
+
export function getKadiCoreJSONPath() {
|
|
72
|
+
return kadiCoreAgentPath;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//Gets the agent.json for KADI system
|
|
76
|
+
export function getKadiJSON() {
|
|
77
|
+
//Get the agent.json for kadi
|
|
78
|
+
let kadiJSON = fs.readFileSync(kadiAgentPath, 'utf8');
|
|
79
|
+
kadiJSON = JSON.parse(kadiJSON);
|
|
80
|
+
return kadiJSON;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
//Gets the file path for the KADI Agent.json
|
|
84
|
+
export function getKadiJSONPath() {
|
|
85
|
+
return kadiAgentPath;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//Get the exec path of the KADI system
|
|
89
|
+
export function getKadiExecPath() {
|
|
90
|
+
return kadiExecDir;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
//Get the Install directory of KADI system
|
|
94
|
+
export function getKadiInstallPath() {
|
|
95
|
+
return kadiRootDir;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
//Save agent.json file
|
|
99
|
+
export async function saveAgentJSON(agentJSON, agentJSONPath) {
|
|
100
|
+
// Convert the JSON object to a string with pretty-print formatting
|
|
101
|
+
const jsonString = JSON.stringify(agentJSON, null, 2);
|
|
102
|
+
|
|
103
|
+
// Write the JSON string to the specified file
|
|
104
|
+
fs.writeFile(agentJSONPath, jsonString, 'utf8', (err) => {
|
|
105
|
+
if (err) {
|
|
106
|
+
console.error('Error saving JSON to file:', err);
|
|
107
|
+
}
|
|
108
|
+
// else {
|
|
109
|
+
// console.log('JSON saved successfully to', filePath);
|
|
110
|
+
// }
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function getAbilityVersionFromArray(abilities, name) {
|
|
115
|
+
// Handle both array and object formats for backward compatibility
|
|
116
|
+
if (Array.isArray(abilities)) {
|
|
117
|
+
// Old format: abilities is an array of objects with name/version
|
|
118
|
+
const ability = abilities.find((ability) => ability.name === name);
|
|
119
|
+
if (ability) {
|
|
120
|
+
return ability.version;
|
|
121
|
+
}
|
|
122
|
+
} else if (abilities && typeof abilities === 'object') {
|
|
123
|
+
// New format: abilities is an object with name as key and version as value
|
|
124
|
+
if (name in abilities) {
|
|
125
|
+
return abilities[name];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Get the API URL from the agent.json
|
|
132
|
+
let kadijson = getKadiJSON();
|
|
133
|
+
|
|
134
|
+
// Define the API URL (Adjust according to your API)
|
|
135
|
+
export const KADI_API_URL = kadijson.api;
|
|
136
|
+
export const SEARCH_API_URL = kadijson.api + '/search';
|
|
137
|
+
export const GET_API_URL = kadijson.api + '/get';
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { exec, spawn } from 'child_process';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
// Import rootDir from pathUtils
|
|
5
|
+
import { rootDir } from './pathUtils.js';
|
|
6
|
+
|
|
7
|
+
//Runs a command line string, used for abilities init functions
|
|
8
|
+
export async function runExecCommand(name, version, command) {
|
|
9
|
+
let execDirectory;
|
|
10
|
+
if (name === '' || version === '') {
|
|
11
|
+
execDirectory = path.join(rootDir);
|
|
12
|
+
} else {
|
|
13
|
+
execDirectory = path.join(rootDir, 'abilities', name, version);
|
|
14
|
+
}
|
|
15
|
+
console.log('execDirectory: ', execDirectory);
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
exec(
|
|
18
|
+
command,
|
|
19
|
+
{ cwd: execDirectory, maxBuffer: 1024 * 1024 },
|
|
20
|
+
(error, stdout, stderr) => {
|
|
21
|
+
if (error) {
|
|
22
|
+
console.error(`exec error: ${error}`);
|
|
23
|
+
reject(error); // Reject the promise on error
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (stderr.trim()) {
|
|
27
|
+
console.error(stderr);
|
|
28
|
+
}
|
|
29
|
+
resolve(stdout.trim()); // Resolve the promise when exec completes successfully
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function runSpawnCommand(name, version, command) {
|
|
36
|
+
let execDirectory;
|
|
37
|
+
if (name === '' || version === '') {
|
|
38
|
+
execDirectory = path.join(rootDir);
|
|
39
|
+
} else {
|
|
40
|
+
execDirectory = path.join(rootDir, 'abilities', name, version);
|
|
41
|
+
}
|
|
42
|
+
console.log('execDirectory: ', execDirectory);
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
const child = spawn(command, {
|
|
45
|
+
cwd: execDirectory,
|
|
46
|
+
stdio: 'inherit', // This pipes the child process's stdio to the parent
|
|
47
|
+
shell: true // This ensures that the command is run within a shell
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
child.on('error', (error) => {
|
|
51
|
+
console.error(`Error: ${error}`);
|
|
52
|
+
reject(error);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
child.on('close', (code) => {
|
|
56
|
+
if (code !== 0) {
|
|
57
|
+
console.error(`Process exited with code: ${code}`);
|
|
58
|
+
reject(new Error(`Process exited with code: ${code}`));
|
|
59
|
+
} else {
|
|
60
|
+
resolve();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { getKadiJSON } from './agentUtils.js';
|
|
2
|
+
|
|
3
|
+
// Get the API URL from the agent.json
|
|
4
|
+
let kadijson = getKadiJSON();
|
|
5
|
+
|
|
6
|
+
// Export all broker URLs
|
|
7
|
+
const brokers = {};
|
|
8
|
+
if (kadijson.brokers && typeof kadijson.brokers === 'object') {
|
|
9
|
+
for (const [name, url] of Object.entries(kadijson.brokers)) {
|
|
10
|
+
const brokerUrl = new URL(url);
|
|
11
|
+
brokers[name] =
|
|
12
|
+
`${brokerUrl.hostname}:${brokerUrl.port}${brokerUrl.pathname}`;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const KADI_BROKERS = brokers;
|
|
17
|
+
|
|
18
|
+
// Get default broker (first one defined)
|
|
19
|
+
const defaultBrokerName = kadijson.brokers
|
|
20
|
+
? Object.keys(kadijson.brokers)[0]
|
|
21
|
+
: null;
|
|
22
|
+
export const KADI_BROKER_URL = brokers[defaultBrokerName]; // Backward compatibility
|
|
23
|
+
|
|
24
|
+
// Utility functions
|
|
25
|
+
export function getBrokerUrl(brokerName) {
|
|
26
|
+
return brokers[brokerName] || null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getBrokerNames() {
|
|
30
|
+
return Object.keys(brokers);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getDefaultBrokerName() {
|
|
34
|
+
return defaultBrokerName;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Active broker selection
|
|
38
|
+
let activeBrokerName = defaultBrokerName;
|
|
39
|
+
|
|
40
|
+
export function setActiveBroker(brokerName) {
|
|
41
|
+
if (brokers[brokerName]) {
|
|
42
|
+
activeBrokerName = brokerName;
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function getActiveBrokerName() {
|
|
49
|
+
return activeBrokerName;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function getActiveBrokerUrl() {
|
|
53
|
+
return brokers[activeBrokerName];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Function to find the version of an ability by name
|
|
57
|
+
export function findAbilityVersionByName(abilities, name) {
|
|
58
|
+
// Handle both array and object formats for backward compatibility
|
|
59
|
+
if (Array.isArray(abilities)) {
|
|
60
|
+
// Old format: abilities is an array of objects with name/version
|
|
61
|
+
const ability = abilities.find((ability) => ability.name === name);
|
|
62
|
+
if (ability) {
|
|
63
|
+
return ability.version;
|
|
64
|
+
}
|
|
65
|
+
} else if (abilities && typeof abilities === 'object') {
|
|
66
|
+
// New format: abilities is an object with name as key and version as value
|
|
67
|
+
if (name in abilities) {
|
|
68
|
+
return abilities[name];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return 'No ability found with the specified name.';
|
|
72
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// src/utils/logger.js
|
|
2
|
+
import debug from 'debug';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Create namespaced debug loggers for KADI core library
|
|
7
|
+
*
|
|
8
|
+
* Namespace structure:
|
|
9
|
+
* kadi:core:component:subcomponent
|
|
10
|
+
*/
|
|
11
|
+
export const loggers = {
|
|
12
|
+
// General core functionality
|
|
13
|
+
core: debug('kadi:core'),
|
|
14
|
+
|
|
15
|
+
// Ability-related loggers
|
|
16
|
+
ability: debug('kadi:core:ability'),
|
|
17
|
+
abilityLoader: debug('kadi:core:abilityLoader'),
|
|
18
|
+
|
|
19
|
+
// Server loggers
|
|
20
|
+
serverBase: debug('kadi:core:server:base'),
|
|
21
|
+
serverStdio: debug('kadi:core:server:stdio'),
|
|
22
|
+
serverBroker: debug('kadi:core:server:broker'),
|
|
23
|
+
|
|
24
|
+
// Transport loggers
|
|
25
|
+
transportStdio: debug('kadi:core:transport:stdio'),
|
|
26
|
+
transportBroker: debug('kadi:core:transport:broker'),
|
|
27
|
+
transportIpc: debug('kadi:core:transport:ipc'),
|
|
28
|
+
|
|
29
|
+
// Legacy namespaces for backward compatibility
|
|
30
|
+
loader: debug('kadi:core:abilityLoader'),
|
|
31
|
+
transport: debug('kadi:core:transport'),
|
|
32
|
+
broker: debug('kadi:broker'),
|
|
33
|
+
stdio: debug('kadi:stdio'),
|
|
34
|
+
server: debug('kadi:core:server')
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Create a logger for a specific namespace with color support
|
|
39
|
+
* @param {string} namespace - The namespace key from loggers object
|
|
40
|
+
* @returns {Object} Enhanced logger with colored methods
|
|
41
|
+
*/
|
|
42
|
+
export function createLogger(namespace) {
|
|
43
|
+
// Get the base debug instance - support both new and legacy namespaces
|
|
44
|
+
const baseLogger = loggers[namespace] || debug(`kadi:core:${namespace}`);
|
|
45
|
+
|
|
46
|
+
// Return enhanced logger with colored methods
|
|
47
|
+
return {
|
|
48
|
+
// Original debug function
|
|
49
|
+
debug: baseLogger,
|
|
50
|
+
|
|
51
|
+
// Colored log methods
|
|
52
|
+
log: (...args) => baseLogger(...args),
|
|
53
|
+
info: (msg, ...args) => baseLogger(chalk.blue('ℹ ' + msg), ...args),
|
|
54
|
+
success: (msg, ...args) => baseLogger(chalk.green('✓ ' + msg), ...args),
|
|
55
|
+
warn: (msg, ...args) => baseLogger(chalk.yellow('⚠ ' + msg), ...args),
|
|
56
|
+
error: (msg, ...args) => baseLogger(chalk.red('✗ ' + msg), ...args),
|
|
57
|
+
trace: (msg, ...args) => baseLogger(chalk.gray('→ ' + msg), ...args),
|
|
58
|
+
|
|
59
|
+
// Special formatting
|
|
60
|
+
highlight: (msg, ...args) => baseLogger(chalk.cyan(msg), ...args),
|
|
61
|
+
dim: (msg, ...args) => baseLogger(chalk.dim(msg), ...args),
|
|
62
|
+
bold: (msg, ...args) => baseLogger(chalk.bold(msg), ...args),
|
|
63
|
+
|
|
64
|
+
// Method-specific formatting
|
|
65
|
+
methodCall: (method, ...args) =>
|
|
66
|
+
baseLogger(chalk.magenta(`[${method}]`), ...args),
|
|
67
|
+
lifecycle: (event, ...args) =>
|
|
68
|
+
baseLogger(chalk.yellow(`◯ ${event}`), ...args),
|
|
69
|
+
request: (id, method, ...args) =>
|
|
70
|
+
baseLogger(chalk.cyan(`→ [${id}] ${method}`), ...args),
|
|
71
|
+
response: (id, status, ...args) => {
|
|
72
|
+
const color = status === 'success' ? chalk.green : chalk.red;
|
|
73
|
+
baseLogger(color(`← [${id}] ${status}`), ...args);
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// Check if enabled
|
|
77
|
+
enabled: baseLogger.enabled,
|
|
78
|
+
namespace: baseLogger.namespace
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Create a logger for a specific component
|
|
84
|
+
* Maps component names to their appropriate namespace
|
|
85
|
+
*
|
|
86
|
+
* @param {string} component - Component name (e.g., 'KadiAbility', 'StdioRpcServer')
|
|
87
|
+
* @returns {Object} Enhanced logger
|
|
88
|
+
*/
|
|
89
|
+
export function createComponentLogger(component) {
|
|
90
|
+
const componentMap = {
|
|
91
|
+
KadiAbility: 'ability',
|
|
92
|
+
loadAbility: 'abilityLoader',
|
|
93
|
+
BaseRpcServer: 'serverBase',
|
|
94
|
+
StdioRpcServer: 'serverStdio',
|
|
95
|
+
BrokerRpcServer: 'serverBroker',
|
|
96
|
+
StdioTransport: 'transportStdio',
|
|
97
|
+
BrokerTransport: 'transportBroker',
|
|
98
|
+
IpcServer: 'transportIpc',
|
|
99
|
+
StdioFrameReader: 'transportStdio',
|
|
100
|
+
StdioFrameWriter: 'transportStdio',
|
|
101
|
+
BrokerMessageBuilder: 'transportBroker'
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const namespace = componentMap[component] || 'core';
|
|
105
|
+
return createLogger(namespace);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Utility to check if debug is enabled for a namespace
|
|
110
|
+
* Useful for expensive operations that should only run when debugging
|
|
111
|
+
*
|
|
112
|
+
* @param {string} namespace
|
|
113
|
+
* @returns {boolean}
|
|
114
|
+
*/
|
|
115
|
+
export function isDebugEnabled(namespace) {
|
|
116
|
+
const logger = loggers[namespace] || createLogger(namespace);
|
|
117
|
+
return logger.enabled;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Format an object for debug output
|
|
122
|
+
* @param {any} obj - Object to format
|
|
123
|
+
* @param {string} label - Optional label
|
|
124
|
+
* @returns {string}
|
|
125
|
+
*/
|
|
126
|
+
export function formatObject(obj, label = '') {
|
|
127
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
128
|
+
return label ? `${label}: ${obj}` : String(obj);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
const json = JSON.stringify(obj, null, 2);
|
|
133
|
+
return label ? `${label}:\n${json}` : json;
|
|
134
|
+
} catch (err) {
|
|
135
|
+
return label
|
|
136
|
+
? `${label}: [Circular or non-serializable object]`
|
|
137
|
+
: '[Circular object]';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Create a child logger with additional context
|
|
143
|
+
* Useful for adding request IDs or session context
|
|
144
|
+
*
|
|
145
|
+
* @param {debug.Debugger} parentLogger
|
|
146
|
+
* @param {string} context
|
|
147
|
+
* @returns {debug.Debugger}
|
|
148
|
+
*/
|
|
149
|
+
export function createChildLogger(parentLogger, context) {
|
|
150
|
+
const namespace = parentLogger.namespace;
|
|
151
|
+
return debug(`${namespace}:${context}`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export default {
|
|
155
|
+
loggers,
|
|
156
|
+
createLogger,
|
|
157
|
+
createComponentLogger,
|
|
158
|
+
isDebugEnabled,
|
|
159
|
+
formatObject,
|
|
160
|
+
createChildLogger
|
|
161
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
|
|
9
|
+
export function resolveKadiExecPath() {
|
|
10
|
+
const command = process.platform === 'win32' ? 'where kadi' : 'which kadi';
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const kadiPath = execSync(command, { encoding: 'utf8' }).trim();
|
|
14
|
+
if (kadiPath) {
|
|
15
|
+
return kadiPath;
|
|
16
|
+
} else {
|
|
17
|
+
throw new Error('Kadi CLI tool not found in the system PATH');
|
|
18
|
+
}
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error('Error resolving Kadi path:', error);
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function resolveKadiInstallPath() {
|
|
26
|
+
/* 1 - production / normal install -------------------------------- */
|
|
27
|
+
try {
|
|
28
|
+
if (typeof import.meta.resolve === 'function') {
|
|
29
|
+
const p = import.meta.resolve('@kadi.build/cli/package.json');
|
|
30
|
+
if (p) return path.dirname(new URL(p).pathname);
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
/* ignore – fall through */
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* 2 - legacy strategy – follow the kadi executable --------------- */
|
|
37
|
+
try {
|
|
38
|
+
const cmd = process.platform === 'win32' ? 'where kadi' : 'which kadi';
|
|
39
|
+
const kadiBinaryPath = execSync(cmd, { encoding: 'utf8' }).trim();
|
|
40
|
+
if (!kadiBinaryPath) {
|
|
41
|
+
throw new Error('Kadi CLI tool not found in the system PATH');
|
|
42
|
+
}
|
|
43
|
+
const realKadiBinaryPath = fs.realpathSync(kadiBinaryPath); // resolve symlink
|
|
44
|
+
let kadiDir = path.dirname(realKadiBinaryPath); // start alongside the binary
|
|
45
|
+
|
|
46
|
+
const kadiPackageJsonPath = path.join(kadiDir, 'package.json');
|
|
47
|
+
if (fs.existsSync(kadiPackageJsonPath)) {
|
|
48
|
+
const kadiPackageJson = JSON.parse(
|
|
49
|
+
fs.readFileSync(kadiPackageJsonPath, 'utf8')
|
|
50
|
+
);
|
|
51
|
+
if (
|
|
52
|
+
kadiPackageJson.name === '@kadi.build/cli' ||
|
|
53
|
+
(kadiPackageJson.bin && kadiPackageJson.bin.kadi)
|
|
54
|
+
) {
|
|
55
|
+
return kadiDir;
|
|
56
|
+
} else {
|
|
57
|
+
throw new Error(
|
|
58
|
+
'Package.json found, but it is not for @kadi.build/cli'
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
throw new Error(
|
|
63
|
+
'@kadi.build/cli package.json not found in the resolved path.'
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
} catch {
|
|
67
|
+
/* ignore – fall through */
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* 3 - give up ----------------------------------------------------- */
|
|
71
|
+
throw new Error(
|
|
72
|
+
'Could not locate @kadi.build/cli installation. ' +
|
|
73
|
+
'Make sure the CLI is installed (`npm i -g @kadi.build/cli`) ' +
|
|
74
|
+
'or run commands from inside the CLI repository during development.'
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Export the resolved paths
|
|
79
|
+
export const kadiExecDir = resolveKadiExecPath();
|
|
80
|
+
export const kadiRootDir = resolveKadiInstallPath();
|
|
81
|
+
export const kadiAgentPath = path.join(kadiRootDir, 'agent.json');
|
|
82
|
+
|
|
83
|
+
export const rootDir = process.cwd();
|
|
84
|
+
export const abilitiesDir = path.join(rootDir, 'abilities');
|
|
85
|
+
export const projectAgentPath = path.join(rootDir, 'agent.json');
|
|
86
|
+
export const kadiCoreAgentPath = path.join(__dirname, '..', 'agent.json');
|