claude-flow-novice 2.15.4 → 2.15.5

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.
@@ -1,100 +1,118 @@
1
- import * as fs from "fs/promises";
2
- import * as path from "path";
3
- import Ajv from "ajv";
4
- import * as lodash from "lodash";
5
- let ConfigManager = class ConfigManager {
6
- static _instance = null;
7
- configPath;
8
- schemaPath;
9
- ajv;
10
- constructor(){
11
- this.configPath = path.join(process.env.HOME || "", ".claude-flow-config.json");
12
- this.schemaPath = path.join(__dirname, "../../.claude/skills/config-management/config.json");
13
- this.ajv = new Ajv();
14
- }
15
- static getInstance() {
16
- if (!ConfigManager._instance) {
17
- ConfigManager._instance = new ConfigManager();
18
- }
19
- return ConfigManager._instance;
20
- }
21
- async readConfig() {
22
- try {
23
- const configContent = await fs.readFile(this.configPath, "utf-8");
24
- return JSON.parse(configContent);
25
- } catch (error) {
26
- // If config doesn't exist, create from schema
27
- return this.resetToDefaults();
28
- }
29
- }
30
- async writeConfig(config) {
31
- const schemaContent = await fs.readFile(this.schemaPath, "utf-8");
32
- const schema = JSON.parse(schemaContent);
33
- const validate = this.ajv.compile(schema);
34
- if (!validate(config)) {
35
- throw new Error("Invalid configuration: " + this.ajv.errorsText(validate.errors));
36
- }
37
- await fs.writeFile(this.configPath, JSON.stringify(config, null, 2), "utf-8");
1
+ "use strict";
2
+ var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
3
+ function adopt(value) {
4
+ return value instanceof P ? value : new P(function(resolve) {
5
+ resolve(value);
6
+ });
38
7
  }
39
- async getValue(keyPath) {
40
- const config = await this.readConfig();
41
- const value = lodash.get(config, keyPath);
42
- if (value === undefined) {
43
- // Check if it's a custom key path not in the schema
44
- const customConfig = await this.readCustomConfig();
45
- return lodash.get(customConfig, keyPath);
8
+ return new (P || (P = Promise))(function(resolve, reject) {
9
+ function fulfilled(value) {
10
+ try {
11
+ step(generator.next(value));
12
+ } catch (e) {
13
+ reject(e);
14
+ }
46
15
  }
47
- return value;
48
- }
49
- async readCustomConfig() {
50
- try {
51
- const customConfigPath = path.join(process.env.HOME || "", ".claude-flow-custom-config.json");
52
- const customConfigContent = await fs.readFile(customConfigPath, "utf-8");
53
- return JSON.parse(customConfigContent);
54
- } catch (error) {
55
- // If custom config doesn't exist or can't be read, return empty object
56
- return {};
16
+ function rejected(value) {
17
+ try {
18
+ step(generator["throw"](value));
19
+ } catch (e) {
20
+ reject(e);
21
+ }
57
22
  }
58
- }
59
- async set(key, value) {
60
- const config = await this.readConfig();
61
- // Type assertion to handle full object
62
- if (typeof value === "object" && value !== null) {
63
- config[key] = value;
64
- } else {
65
- throw new Error("Invalid configuration value");
23
+ function step(result) {
24
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
66
25
  }
67
- await this.writeConfig(config);
68
- }
69
- async getAll() {
70
- return this.readConfig();
71
- }
72
- async resetToDefaults() {
73
- const schemaContent = await fs.readFile(this.schemaPath, "utf-8");
74
- const schema = JSON.parse(schemaContent);
75
- // Extract default values from the schema
76
- const defaultConfig = {
77
- redis: {
78
- host: schema.properties.redis.properties.host.default,
79
- port: schema.properties.redis.properties.port.default
80
- },
81
- agent: {
82
- default_strategy: schema.properties.agent.properties.default_strategy.default,
83
- max_concurrent_agents: schema.properties.agent.properties.max_concurrent_agents.default,
84
- log_level: schema.properties.agent.properties.log_level.default
85
- },
86
- security: {
87
- enabled: schema.properties.security.properties.enabled.default,
88
- max_retry_attempts: schema.properties.security.properties.max_retry_attempts.default
89
- }
26
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
27
+ });
28
+ };
29
+ var __generator = this && this.__generator || function(thisArg, body) {
30
+ var _ = {
31
+ label: 0,
32
+ sent: function() {
33
+ if (t[0] & 1) throw t[1];
34
+ return t[1];
35
+ },
36
+ trys: [],
37
+ ops: []
38
+ }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
39
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
40
+ return this;
41
+ }), g;
42
+ function verb(n) {
43
+ return function(v) {
44
+ return step([
45
+ n,
46
+ v
47
+ ]);
90
48
  };
91
- await this.writeConfig(defaultConfig);
92
- return defaultConfig;
93
49
  }
94
- };
95
- export default ConfigManager;
96
-
97
- //# sourceMappingURL=config-manager.js.mapop[1] : void 0,
50
+ function step(op) {
51
+ if (f) throw new TypeError("Generator is already executing.");
52
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
53
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
54
+ if (y = 0, t) op = [
55
+ op[0] & 2,
56
+ t.value
57
+ ];
58
+ switch(op[0]){
59
+ case 0:
60
+ case 1:
61
+ t = op;
62
+ break;
63
+ case 4:
64
+ _.label++;
65
+ return {
66
+ value: op[1],
67
+ done: false
68
+ };
69
+ case 5:
70
+ _.label++;
71
+ y = op[1];
72
+ op = [
73
+ 0
74
+ ];
75
+ continue;
76
+ case 7:
77
+ op = _.ops.pop();
78
+ _.trys.pop();
79
+ continue;
80
+ default:
81
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
82
+ _ = 0;
83
+ continue;
84
+ }
85
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
86
+ _.label = op[1];
87
+ break;
88
+ }
89
+ if (op[0] === 6 && _.label < t[1]) {
90
+ _.label = t[1];
91
+ t = op;
92
+ break;
93
+ }
94
+ if (t && _.label < t[2]) {
95
+ _.label = t[2];
96
+ _.ops.push(op);
97
+ break;
98
+ }
99
+ if (t[2]) _.ops.pop();
100
+ _.trys.pop();
101
+ continue;
102
+ }
103
+ op = body.call(thisArg, _);
104
+ } catch (e) {
105
+ op = [
106
+ 6,
107
+ e
108
+ ];
109
+ y = 0;
110
+ } finally{
111
+ f = t = 0;
112
+ }
113
+ if (op[0] & 5) throw op[1];
114
+ return {
115
+ value: op[0] ? op[1] : void 0,
98
116
  done: true
99
117
  };
100
118
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/config-manager.ts"],"sourcesContent":["import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport Ajv from \"ajv\";\nimport * as lodash from \"lodash\";\n\ninterface ConfigSchema {\n redis: {\n host: string;\n port: number;\n password?: string;\n };\n agent: {\n default_strategy: string;\n max_concurrent_agents: number;\n log_level: \"debug\" | \"info\" | \"warn\" | \"error\";\n };\n security: {\n enabled: boolean;\n max_retry_attempts: number;\n };\n}\n\nclass ConfigManager {\n private static _instance: ConfigManager | null = null;\n private configPath: string;\n private schemaPath: string;\n private ajv: Ajv;\n\n private constructor() {\n this.configPath = path.join(\n process.env.HOME || \"\",\n \".claude-flow-config.json\",\n );\n this.schemaPath = path.join(\n __dirname,\n \"../../.claude/skills/config-management/config.json\",\n );\n this.ajv = new Ajv();\n }\n\n public static getInstance(): ConfigManager {\n if (!ConfigManager._instance) {\n ConfigManager._instance = new ConfigManager();\n }\n return ConfigManager._instance;\n }\n\n private async readConfig(): Promise<ConfigSchema> {\n try {\n const configContent = await fs.readFile(this.configPath, \"utf-8\");\n return JSON.parse(configContent) as ConfigSchema;\n } catch (error) {\n // If config doesn't exist, create from schema\n return this.resetToDefaults();\n }\n }\n\n private async writeConfig(config: ConfigSchema): Promise<void> {\n const schemaContent = await fs.readFile(this.schemaPath, \"utf-8\");\n const schema = JSON.parse(schemaContent);\n\n const validate = this.ajv.compile(schema);\n if (!validate(config)) {\n throw new Error(\n \"Invalid configuration: \" + this.ajv.errorsText(validate.errors),\n );\n }\n\n await fs.writeFile(\n this.configPath,\n JSON.stringify(config, null, 2),\n \"utf-8\",\n );\n }\n\n public async getValue(keyPath: string): Promise<any> {\n const config = await this.readConfig();\n const value = lodash.get(config, keyPath);\n\n if (value === undefined) {\n // Check if it's a custom key path not in the schema\n const customConfig = await this.readCustomConfig();\n return lodash.get(customConfig, keyPath);\n }\n\n return value;\n }\n\n private async readCustomConfig(): Promise<Record<string, any>> {\n try {\n const customConfigPath = path.join(\n process.env.HOME || \"\",\n \".claude-flow-custom-config.json\",\n );\n const customConfigContent = await fs.readFile(customConfigPath, \"utf-8\");\n return JSON.parse(customConfigContent);\n } catch (error) {\n // If custom config doesn't exist or can't be read, return empty object\n return {};\n }\n }\n\n public async set(key: keyof ConfigSchema, value: ConfigSchema[keyof ConfigSchema]): Promise<void> {\n const config = await this.readConfig();\n\n // Type assertion to handle full object\n if (typeof value === \"object\" && value !== null) {\n config[key] = value;\n } else {\n throw new Error(\"Invalid configuration value\");\n }\n\n await this.writeConfig(config);\n }\n\n public async getAll(): Promise<ConfigSchema> {\n return this.readConfig();\n }\n\n public async resetToDefaults(): Promise<ConfigSchema> {\n const schemaContent = await fs.readFile(this.schemaPath, \"utf-8\");\n const schema = JSON.parse(schemaContent);\n\n // Extract default values from the schema\n const defaultConfig: ConfigSchema = {\n redis: {\n host: schema.properties.redis.properties.host.default,\n port: schema.properties.redis.properties.port.default,\n },\n agent: {\n default_strategy:\n schema.properties.agent.properties.default_strategy.default,\n max_concurrent_agents:\n schema.properties.agent.properties.max_concurrent_agents.default,\n log_level: schema.properties.agent.properties.log_level.default,\n },\n security: {\n enabled: schema.properties.security.properties.enabled.default,\n max_retry_attempts:\n schema.properties.security.properties.max_retry_attempts.default,\n },\n };\n\n await this.writeConfig(defaultConfig);\n return defaultConfig;\n }\n}\n\nexport default ConfigManager;"],"names":["fs","path","Ajv","lodash","ConfigManager","_instance","configPath","schemaPath","ajv","join","process","env","HOME","__dirname","getInstance","readConfig","configContent","readFile","JSON","parse","error","resetToDefaults","writeConfig","config","schemaContent","schema","validate","compile","Error","errorsText","errors","writeFile","stringify","getValue","keyPath","value","get","undefined","customConfig","readCustomConfig","customConfigPath","customConfigContent","set","key","getAll","defaultConfig","redis","host","properties","default","port","agent","default_strategy","max_concurrent_agents","log_level","security","enabled","max_retry_attempts"],"mappings":"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"} config = _a.sent();\n // Type assertion to handle both full object and nested key\n if (typeof value === \"object\" && value !== null) {\n config[key] = value;\n }\n else {\n throw new Error(\"Invalid configuration value\");\n }\n return [4 /*yield*/, this.writeConfig(config)];\n case 2:\n _a.sent();\n return [2 /*return*/];\n }\n });\n });\n };\n ConfigManager.prototype.getAll = function () {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n return [2 /*return*/, this.readConfig()];\n });\n });\n };\n ConfigManager.prototype.resetToDefaults = function () {\n return __awaiter(this, void 0, void 0, function () {\n var schemaContent, schema, defaultConfig;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, fs.readFile(this.schemaPath, \"utf-8\")];\n case 1:\n schemaContent = _a.sent();\n schema = JSON.parse(schemaContent);\n defaultConfig = {\n redis: {\n host: schema.properties.redis.properties.host.default,\n port: schema.properties.redis.properties.port.default,\n },\n agent: {\n default_strategy: schema.properties.agent.properties.default_strategy.default,\n max_concurrent_agents: schema.properties.agent.properties.max_concurrent_agents.default,\n log_level: schema.properties.agent.properties.log_level.default,\n },\n security: {\n enabled: schema.properties.security.properties.enabled.default,\n max_retry_attempts: schema.properties.security.properties.max_retry_attempts.default,\n },\n };\n return [4 /*yield*/, this.writeConfig(defaultConfig)];\n case 2:\n _a.sent();\n return [2 /*return*/, defaultConfig];\n }\n });\n });\n };\n return ConfigManager;\n}());\nexports.default = ConfigManager;\n"],"names":["__awaiter","thisArg","_arguments","P","generator","adopt","value","resolve","Promise","reject","fulfilled","step","next","e","rejected","result","done","then","apply","__generator","body","_","label","sent","t","trys","ops","f","y","g","Object","create","Iterator","prototype","verb","Symbol","iterator","n","v","op","TypeError","call","pop","length","push","defineProperty","exports","fs","require","path","ajv_1","get_1","ConfigManager","configPath","join","process","env","HOME","schemaPath","__dirname","ajv","default","getInstance","instance","readConfig","configContent","error_1","_a","readFile","JSON","parse","resetToDefaults","writeConfig","config","schemaContent","schema","validate","compile","Error","errorsText","errors","writeFile","stringify","getValue","keyPath","customConfig","undefined","readCustomConfig","customConfigPath","customConfigContent","error_2","set","key","getAll","defaultConfig","redis","host","properties","port","agent","default_strategy","max_concurrent_agents","log_level","security","enabled","max_retry_attempts"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/cli/config-manager.js"],"sourcesContent":["\"use strict\";\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __generator = (this && this.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype);\n return g.next = verb(0), g[\"throw\"] = verb(1), g[\"return\"] = verb(2), typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar fs = require(\"fs/promises\");\nvar path = require(\"path\");\nvar ajv_1 = require(\"ajv\");\nvar get_1 = require(\"lodash/get\");\nvar ConfigManager = /** @class */ (function () {\n function ConfigManager() {\n this.configPath = path.join(process.env.HOME || \"\", \".claude-flow-config.json\");\n this.schemaPath = path.join(__dirname, \"../../.claude/skills/config-management/config.json\");\n this.ajv = new ajv_1.default();\n }\n ConfigManager.getInstance = function () {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager();\n }\n return ConfigManager.instance;\n };\n ConfigManager.prototype.readConfig = function () {\n return __awaiter(this, void 0, void 0, function () {\n var configContent, error_1;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n _a.trys.push([0, 2, , 3]);\n return [4 /*yield*/, fs.readFile(this.configPath, \"utf-8\")];\n case 1:\n configContent = _a.sent();\n return [2 /*return*/, JSON.parse(configContent)];\n case 2:\n error_1 = _a.sent();\n // If config doesn't exist, create from schema\n return [2 /*return*/, this.resetToDefaults()];\n case 3: return [2 /*return*/];\n }\n });\n });\n };\n ConfigManager.prototype.writeConfig = function (config) {\n return __awaiter(this, void 0, void 0, function () {\n var schemaContent, schema, validate;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, fs.readFile(this.schemaPath, \"utf-8\")];\n case 1:\n schemaContent = _a.sent();\n schema = JSON.parse(schemaContent);\n validate = this.ajv.compile(schema);\n if (!validate(config)) {\n throw new Error(\"Invalid configuration: \" + this.ajv.errorsText(validate.errors));\n }\n return [4 /*yield*/, fs.writeFile(this.configPath, JSON.stringify(config, null, 2), \"utf-8\")];\n case 2:\n _a.sent();\n return [2 /*return*/];\n }\n });\n });\n };\n ConfigManager.prototype.getValue = function (keyPath) {\n return __awaiter(this, void 0, void 0, function () {\n var config, value, customConfig;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this.readConfig()];\n case 1:\n config = _a.sent();\n value = (0, get_1.default)(config, keyPath);\n if (!(value === undefined)) return [3 /*break*/, 3];\n return [4 /*yield*/, this.readCustomConfig()];\n case 2:\n customConfig = _a.sent();\n return [2 /*return*/, (0, get_1.default)(customConfig, keyPath)];\n case 3: return [2 /*return*/, value];\n }\n });\n });\n };\n ConfigManager.prototype.readCustomConfig = function () {\n return __awaiter(this, void 0, void 0, function () {\n var customConfigPath, customConfigContent, error_2;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0:\n _a.trys.push([0, 2, , 3]);\n customConfigPath = path.join(process.env.HOME || \"\", \".claude-flow-custom-config.json\");\n return [4 /*yield*/, fs.readFile(customConfigPath, \"utf-8\")];\n case 1:\n customConfigContent = _a.sent();\n return [2 /*return*/, JSON.parse(customConfigContent)];\n case 2:\n error_2 = _a.sent();\n // If custom config doesn't exist or can't be read, return empty object\n return [2 /*return*/, {}];\n case 3: return [2 /*return*/];\n }\n });\n });\n };\n ConfigManager.prototype.set = function (key, value) {\n return __awaiter(this, void 0, void 0, function () {\n var config;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, this.readConfig()];\n case 1:\n config = _a.sent();\n // Type assertion to handle both full object and nested key\n if (typeof value === \"object\" && value !== null) {\n config[key] = value;\n }\n else {\n throw new Error(\"Invalid configuration value\");\n }\n return [4 /*yield*/, this.writeConfig(config)];\n case 2:\n _a.sent();\n return [2 /*return*/];\n }\n });\n });\n };\n ConfigManager.prototype.getAll = function () {\n return __awaiter(this, void 0, void 0, function () {\n return __generator(this, function (_a) {\n return [2 /*return*/, this.readConfig()];\n });\n });\n };\n ConfigManager.prototype.resetToDefaults = function () {\n return __awaiter(this, void 0, void 0, function () {\n var schemaContent, schema, defaultConfig;\n return __generator(this, function (_a) {\n switch (_a.label) {\n case 0: return [4 /*yield*/, fs.readFile(this.schemaPath, \"utf-8\")];\n case 1:\n schemaContent = _a.sent();\n schema = JSON.parse(schemaContent);\n defaultConfig = {\n redis: {\n host: schema.properties.redis.properties.host.default,\n port: schema.properties.redis.properties.port.default,\n },\n agent: {\n default_strategy: schema.properties.agent.properties.default_strategy.default,\n max_concurrent_agents: schema.properties.agent.properties.max_concurrent_agents.default,\n log_level: schema.properties.agent.properties.log_level.default,\n },\n security: {\n enabled: schema.properties.security.properties.enabled.default,\n max_retry_attempts: schema.properties.security.properties.max_retry_attempts.default,\n },\n };\n return [4 /*yield*/, this.writeConfig(defaultConfig)];\n case 2:\n _a.sent();\n return [2 /*return*/, defaultConfig];\n }\n });\n });\n };\n return ConfigManager;\n}());\nexports.default = ConfigManager;\n"],"names":["__awaiter","thisArg","_arguments","P","generator","adopt","value","resolve","Promise","reject","fulfilled","step","next","e","rejected","result","done","then","apply","__generator","body","_","label","sent","t","trys","ops","f","y","g","Object","create","Iterator","prototype","verb","Symbol","iterator","n","v","op","TypeError","call","pop","length","push","defineProperty","exports","fs","require","path","ajv_1","get_1","ConfigManager","configPath","join","process","env","HOME","schemaPath","__dirname","ajv","default","getInstance","instance","readConfig","configContent","error_1","_a","readFile","JSON","parse","resetToDefaults","writeConfig","config","schemaContent","schema","validate","compile","Error","errorsText","errors","writeFile","stringify","getValue","keyPath","customConfig","undefined","readCustomConfig","customConfigPath","customConfigContent","error_2","set","key","getAll","defaultConfig","redis","host","properties","port","agent","default_strategy","max_concurrent_agents","log_level","security","enabled","max_retry_attempts"],"mappings":"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"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Conversation Fork Cleanup Utilities
3
+ *
4
+ * Provides memory leak prevention for Task Mode by:
5
+ * 1. Setting TTL on message lists (24h default)
6
+ * 2. Cleaning up completed task messages
7
+ * 3. Limiting message history size
8
+ * 4. Auto-cleanup of orphaned forks
9
+ */ import { execSync } from 'child_process';
10
+ const redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';
11
+ const redisPort = process.env.CFN_REDIS_PORT || '6379';
12
+ const DEFAULT_OPTIONS = {
13
+ messageTTL: 86400,
14
+ maxMessagesPerAgent: 100,
15
+ autoCleanupForks: true
16
+ };
17
+ /**
18
+ * Set TTL on message list to prevent indefinite accumulation
19
+ */ export function setMessageListTTL(taskId, agentId, ttlSeconds = DEFAULT_OPTIONS.messageTTL) {
20
+ const key = `swarm:${taskId}:${agentId}:messages`;
21
+ try {
22
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} expire "${key}" ${ttlSeconds}`, {
23
+ encoding: 'utf8'
24
+ });
25
+ console.log(`[conversation-cleanup] Set TTL ${ttlSeconds}s on ${key}`);
26
+ } catch (error) {
27
+ console.error(`[conversation-cleanup] Failed to set TTL:`, error);
28
+ }
29
+ }
30
+ /**
31
+ * Trim message list to max size (FIFO - keep recent messages)
32
+ */ export function trimMessageList(taskId, agentId, maxMessages = DEFAULT_OPTIONS.maxMessagesPerAgent) {
33
+ const key = `swarm:${taskId}:${agentId}:messages`;
34
+ try {
35
+ // Keep only the last N messages (0 = oldest, -N = keep last N)
36
+ const start = -maxMessages;
37
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} ltrim "${key}" ${start} -1`, {
38
+ encoding: 'utf8'
39
+ });
40
+ console.log(`[conversation-cleanup] Trimmed ${key} to ${maxMessages} messages`);
41
+ } catch (error) {
42
+ console.error(`[conversation-cleanup] Failed to trim messages:`, error);
43
+ }
44
+ }
45
+ /**
46
+ * Clean up all messages and forks for a completed task
47
+ */ export function cleanupTaskMessages(taskId, agentId) {
48
+ try {
49
+ // Delete main message list
50
+ const messagesKey = `swarm:${taskId}:${agentId}:messages`;
51
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} del "${messagesKey}"`, {
52
+ encoding: 'utf8'
53
+ });
54
+ // Delete all fork message lists
55
+ const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;
56
+ const forkKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys "${forkPattern}"`, {
57
+ encoding: 'utf8'
58
+ }).trim().split('\n').filter((k)=>k);
59
+ if (forkKeys.length > 0) {
60
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${forkKeys.join(' ')}`, {
61
+ encoding: 'utf8'
62
+ });
63
+ }
64
+ // Delete all fork metadata
65
+ const forkMetaPattern = `swarm:${taskId}:${agentId}:fork:*:meta`;
66
+ const metaKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys "${forkMetaPattern}"`, {
67
+ encoding: 'utf8'
68
+ }).trim().split('\n').filter((k)=>k);
69
+ if (metaKeys.length > 0) {
70
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${metaKeys.join(' ')}`, {
71
+ encoding: 'utf8'
72
+ });
73
+ }
74
+ // Delete current fork pointer
75
+ const currentForkKey = `swarm:${taskId}:${agentId}:current-fork`;
76
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} del "${currentForkKey}"`, {
77
+ encoding: 'utf8'
78
+ });
79
+ console.log(`[conversation-cleanup] Cleaned up task ${taskId} agent ${agentId}`);
80
+ console.log(`[conversation-cleanup] Removed: 1 message list, ${forkKeys.length} fork snapshots, ${metaKeys.length} fork metadata`);
81
+ } catch (error) {
82
+ console.error(`[conversation-cleanup] Failed to cleanup task messages:`, error);
83
+ }
84
+ }
85
+ /**
86
+ * Clean up orphaned forks (metadata expired but messages remain)
87
+ */ export function cleanupOrphanedForks(taskId, agentId) {
88
+ try {
89
+ // Find all fork message keys
90
+ const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;
91
+ const forkMessageKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys "${forkPattern}"`, {
92
+ encoding: 'utf8'
93
+ }).trim().split('\n').filter((k)=>k);
94
+ if (forkMessageKeys.length === 0) {
95
+ return;
96
+ }
97
+ const orphanedKeys = [];
98
+ for (const messageKey of forkMessageKeys){
99
+ // Extract fork ID from key: swarm:task:agent:fork:FORK_ID:messages
100
+ const parts = messageKey.split(':');
101
+ const forkId = parts[parts.length - 2];
102
+ // Check if metadata exists
103
+ const metaKey = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;
104
+ const metaExists = execSync(`redis-cli -h ${redisHost} -p ${redisPort} exists "${metaKey}"`, {
105
+ encoding: 'utf8'
106
+ }).trim();
107
+ if (metaExists === '0') {
108
+ // Metadata expired but messages remain = orphaned
109
+ orphanedKeys.push(messageKey);
110
+ }
111
+ }
112
+ if (orphanedKeys.length > 0) {
113
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${orphanedKeys.join(' ')}`, {
114
+ encoding: 'utf8'
115
+ });
116
+ console.log(`[conversation-cleanup] Removed ${orphanedKeys.length} orphaned fork snapshots`);
117
+ }
118
+ } catch (error) {
119
+ console.error(`[conversation-cleanup] Failed to cleanup orphaned forks:`, error);
120
+ }
121
+ }
122
+ /**
123
+ * Get memory usage statistics for a task
124
+ */ export function getTaskMemoryStats(taskId, agentId) {
125
+ try {
126
+ // Count messages in main list
127
+ const messagesKey = `swarm:${taskId}:${agentId}:messages`;
128
+ const messageCount = parseInt(execSync(`redis-cli -h ${redisHost} -p ${redisPort} llen "${messagesKey}"`, {
129
+ encoding: 'utf8'
130
+ }).trim(), 10);
131
+ // Count forks
132
+ const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;
133
+ const forkKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys "${forkPattern}"`, {
134
+ encoding: 'utf8'
135
+ }).trim().split('\n').filter((k)=>k);
136
+ // Estimate size (average message ~5KB)
137
+ const estimatedSizeKB = messageCount * 5;
138
+ return {
139
+ messageCount,
140
+ forkCount: forkKeys.length,
141
+ estimatedSizeKB
142
+ };
143
+ } catch (error) {
144
+ console.error(`[conversation-cleanup] Failed to get memory stats:`, error);
145
+ return {
146
+ messageCount: 0,
147
+ forkCount: 0,
148
+ estimatedSizeKB: 0
149
+ };
150
+ }
151
+ }
152
+ /**
153
+ * Configure automatic cleanup options for a task
154
+ */ export function configureAutoCleanup(taskId, agentId, options = {}) {
155
+ const config = {
156
+ ...DEFAULT_OPTIONS,
157
+ ...options
158
+ };
159
+ // Set TTL on message list
160
+ setMessageListTTL(taskId, agentId, config.messageTTL);
161
+ // Trim to max size
162
+ trimMessageList(taskId, agentId, config.maxMessagesPerAgent);
163
+ // Cleanup orphaned forks
164
+ if (config.autoCleanupForks) {
165
+ cleanupOrphanedForks(taskId, agentId);
166
+ }
167
+ console.log(`[conversation-cleanup] Auto-cleanup configured for ${taskId}/${agentId}`);
168
+ console.log(`[conversation-cleanup] - TTL: ${config.messageTTL}s`);
169
+ console.log(`[conversation-cleanup] - Max messages: ${config.maxMessagesPerAgent}`);
170
+ console.log(`[conversation-cleanup] - Auto-cleanup forks: ${config.autoCleanupForks}`);
171
+ }
172
+ /**
173
+ * Emergency cleanup - remove all conversation data for all tasks
174
+ * USE WITH CAUTION: This will delete ALL conversation history
175
+ */ export function emergencyCleanupAll() {
176
+ try {
177
+ const patterns = [
178
+ 'swarm:*:*:messages',
179
+ 'swarm:*:*:fork:*:messages',
180
+ 'swarm:*:*:fork:*:meta',
181
+ 'swarm:*:*:current-fork'
182
+ ];
183
+ let totalDeleted = 0;
184
+ for (const pattern of patterns){
185
+ const keys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys "${pattern}"`, {
186
+ encoding: 'utf8'
187
+ }).trim().split('\n').filter((k)=>k);
188
+ if (keys.length > 0) {
189
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${keys.join(' ')}`, {
190
+ encoding: 'utf8'
191
+ });
192
+ totalDeleted += keys.length;
193
+ }
194
+ }
195
+ console.log(`[conversation-cleanup] EMERGENCY CLEANUP: Deleted ${totalDeleted} conversation keys`);
196
+ } catch (error) {
197
+ console.error(`[conversation-cleanup] Failed emergency cleanup:`, error);
198
+ }
199
+ }
200
+
201
+ //# sourceMappingURL=conversation-fork-cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/conversation-fork-cleanup.ts"],"sourcesContent":["/**\r\n * Conversation Fork Cleanup Utilities\r\n *\r\n * Provides memory leak prevention for Task Mode by:\r\n * 1. Setting TTL on message lists (24h default)\r\n * 2. Cleaning up completed task messages\r\n * 3. Limiting message history size\r\n * 4. Auto-cleanup of orphaned forks\r\n */\r\n\r\nimport { execSync } from 'child_process';\r\n\r\nconst redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';\r\nconst redisPort = process.env.CFN_REDIS_PORT || '6379';\r\n\r\nexport interface CleanupOptions {\r\n messageTTL?: number; // TTL for message lists (seconds, default: 86400 = 24h)\r\n maxMessagesPerAgent?: number; // Max messages to keep per agent (default: 100)\r\n autoCleanupForks?: boolean; // Auto-cleanup orphaned forks (default: true)\r\n}\r\n\r\nconst DEFAULT_OPTIONS: Required<CleanupOptions> = {\r\n messageTTL: 86400, // 24 hours\r\n maxMessagesPerAgent: 100, // 100 messages = ~50 iterations\r\n autoCleanupForks: true,\r\n};\r\n\r\n/**\r\n * Set TTL on message list to prevent indefinite accumulation\r\n */\r\nexport function setMessageListTTL(\r\n taskId: string,\r\n agentId: string,\r\n ttlSeconds: number = DEFAULT_OPTIONS.messageTTL\r\n): void {\r\n const key = `swarm:${taskId}:${agentId}:messages`;\r\n\r\n try {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} expire \"${key}\" ${ttlSeconds}`, {\r\n encoding: 'utf8'\r\n });\r\n console.log(`[conversation-cleanup] Set TTL ${ttlSeconds}s on ${key}`);\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed to set TTL:`, error);\r\n }\r\n}\r\n\r\n/**\r\n * Trim message list to max size (FIFO - keep recent messages)\r\n */\r\nexport function trimMessageList(\r\n taskId: string,\r\n agentId: string,\r\n maxMessages: number = DEFAULT_OPTIONS.maxMessagesPerAgent\r\n): void {\r\n const key = `swarm:${taskId}:${agentId}:messages`;\r\n\r\n try {\r\n // Keep only the last N messages (0 = oldest, -N = keep last N)\r\n const start = -maxMessages;\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} ltrim \"${key}\" ${start} -1`, {\r\n encoding: 'utf8'\r\n });\r\n console.log(`[conversation-cleanup] Trimmed ${key} to ${maxMessages} messages`);\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed to trim messages:`, error);\r\n }\r\n}\r\n\r\n/**\r\n * Clean up all messages and forks for a completed task\r\n */\r\nexport function cleanupTaskMessages(taskId: string, agentId: string): void {\r\n try {\r\n // Delete main message list\r\n const messagesKey = `swarm:${taskId}:${agentId}:messages`;\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del \"${messagesKey}\"`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n // Delete all fork message lists\r\n const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;\r\n const forkKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${forkPattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n if (forkKeys.length > 0) {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${forkKeys.join(' ')}`, {\r\n encoding: 'utf8'\r\n });\r\n }\r\n\r\n // Delete all fork metadata\r\n const forkMetaPattern = `swarm:${taskId}:${agentId}:fork:*:meta`;\r\n const metaKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${forkMetaPattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n if (metaKeys.length > 0) {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${metaKeys.join(' ')}`, {\r\n encoding: 'utf8'\r\n });\r\n }\r\n\r\n // Delete current fork pointer\r\n const currentForkKey = `swarm:${taskId}:${agentId}:current-fork`;\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del \"${currentForkKey}\"`, {\r\n encoding: 'utf8'\r\n });\r\n\r\n console.log(`[conversation-cleanup] Cleaned up task ${taskId} agent ${agentId}`);\r\n console.log(`[conversation-cleanup] Removed: 1 message list, ${forkKeys.length} fork snapshots, ${metaKeys.length} fork metadata`);\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed to cleanup task messages:`, error);\r\n }\r\n}\r\n\r\n/**\r\n * Clean up orphaned forks (metadata expired but messages remain)\r\n */\r\nexport function cleanupOrphanedForks(taskId: string, agentId: string): void {\r\n try {\r\n // Find all fork message keys\r\n const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;\r\n const forkMessageKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${forkPattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n if (forkMessageKeys.length === 0) {\r\n return;\r\n }\r\n\r\n const orphanedKeys: string[] = [];\r\n\r\n for (const messageKey of forkMessageKeys) {\r\n // Extract fork ID from key: swarm:task:agent:fork:FORK_ID:messages\r\n const parts = messageKey.split(':');\r\n const forkId = parts[parts.length - 2];\r\n\r\n // Check if metadata exists\r\n const metaKey = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;\r\n const metaExists = execSync(`redis-cli -h ${redisHost} -p ${redisPort} exists \"${metaKey}\"`, {\r\n encoding: 'utf8'\r\n }).trim();\r\n\r\n if (metaExists === '0') {\r\n // Metadata expired but messages remain = orphaned\r\n orphanedKeys.push(messageKey);\r\n }\r\n }\r\n\r\n if (orphanedKeys.length > 0) {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${orphanedKeys.join(' ')}`, {\r\n encoding: 'utf8'\r\n });\r\n console.log(`[conversation-cleanup] Removed ${orphanedKeys.length} orphaned fork snapshots`);\r\n }\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed to cleanup orphaned forks:`, error);\r\n }\r\n}\r\n\r\n/**\r\n * Get memory usage statistics for a task\r\n */\r\nexport function getTaskMemoryStats(taskId: string, agentId: string): {\r\n messageCount: number;\r\n forkCount: number;\r\n estimatedSizeKB: number;\r\n} {\r\n try {\r\n // Count messages in main list\r\n const messagesKey = `swarm:${taskId}:${agentId}:messages`;\r\n const messageCount = parseInt(execSync(`redis-cli -h ${redisHost} -p ${redisPort} llen \"${messagesKey}\"`, {\r\n encoding: 'utf8'\r\n }).trim(), 10);\r\n\r\n // Count forks\r\n const forkPattern = `swarm:${taskId}:${agentId}:fork:*:messages`;\r\n const forkKeys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${forkPattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n // Estimate size (average message ~5KB)\r\n const estimatedSizeKB = messageCount * 5;\r\n\r\n return {\r\n messageCount,\r\n forkCount: forkKeys.length,\r\n estimatedSizeKB,\r\n };\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed to get memory stats:`, error);\r\n return {\r\n messageCount: 0,\r\n forkCount: 0,\r\n estimatedSizeKB: 0,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Configure automatic cleanup options for a task\r\n */\r\nexport function configureAutoCleanup(\r\n taskId: string,\r\n agentId: string,\r\n options: CleanupOptions = {}\r\n): void {\r\n const config = { ...DEFAULT_OPTIONS, ...options };\r\n\r\n // Set TTL on message list\r\n setMessageListTTL(taskId, agentId, config.messageTTL);\r\n\r\n // Trim to max size\r\n trimMessageList(taskId, agentId, config.maxMessagesPerAgent);\r\n\r\n // Cleanup orphaned forks\r\n if (config.autoCleanupForks) {\r\n cleanupOrphanedForks(taskId, agentId);\r\n }\r\n\r\n console.log(`[conversation-cleanup] Auto-cleanup configured for ${taskId}/${agentId}`);\r\n console.log(`[conversation-cleanup] - TTL: ${config.messageTTL}s`);\r\n console.log(`[conversation-cleanup] - Max messages: ${config.maxMessagesPerAgent}`);\r\n console.log(`[conversation-cleanup] - Auto-cleanup forks: ${config.autoCleanupForks}`);\r\n}\r\n\r\n/**\r\n * Emergency cleanup - remove all conversation data for all tasks\r\n * USE WITH CAUTION: This will delete ALL conversation history\r\n */\r\nexport function emergencyCleanupAll(): void {\r\n try {\r\n const patterns = [\r\n 'swarm:*:*:messages',\r\n 'swarm:*:*:fork:*:messages',\r\n 'swarm:*:*:fork:*:meta',\r\n 'swarm:*:*:current-fork',\r\n ];\r\n\r\n let totalDeleted = 0;\r\n\r\n for (const pattern of patterns) {\r\n const keys = execSync(`redis-cli -h ${redisHost} -p ${redisPort} keys \"${pattern}\"`, {\r\n encoding: 'utf8'\r\n }).trim().split('\\n').filter(k => k);\r\n\r\n if (keys.length > 0) {\r\n execSync(`redis-cli -h ${redisHost} -p ${redisPort} del ${keys.join(' ')}`, {\r\n encoding: 'utf8'\r\n });\r\n totalDeleted += keys.length;\r\n }\r\n }\r\n\r\n console.log(`[conversation-cleanup] EMERGENCY CLEANUP: Deleted ${totalDeleted} conversation keys`);\r\n } catch (error) {\r\n console.error(`[conversation-cleanup] Failed emergency cleanup:`, error);\r\n }\r\n}\r\n"],"names":["execSync","redisHost","process","env","CFN_REDIS_HOST","redisPort","CFN_REDIS_PORT","DEFAULT_OPTIONS","messageTTL","maxMessagesPerAgent","autoCleanupForks","setMessageListTTL","taskId","agentId","ttlSeconds","key","encoding","console","log","error","trimMessageList","maxMessages","start","cleanupTaskMessages","messagesKey","forkPattern","forkKeys","trim","split","filter","k","length","join","forkMetaPattern","metaKeys","currentForkKey","cleanupOrphanedForks","forkMessageKeys","orphanedKeys","messageKey","parts","forkId","metaKey","metaExists","push","getTaskMemoryStats","messageCount","parseInt","estimatedSizeKB","forkCount","configureAutoCleanup","options","config","emergencyCleanupAll","patterns","totalDeleted","pattern","keys"],"mappings":"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"}
@@ -12,6 +12,7 @@ const redisHost = process.env.CFN_REDIS_HOST || 'cfn-redis';
12
12
  const redisPort = process.env.CFN_REDIS_PORT || '6379';
13
13
  /**
14
14
  * Store a message in conversation history
15
+ * MEMORY LEAK FIX: Now sets TTL on message list to prevent indefinite accumulation
15
16
  */ export async function storeMessage(taskId, agentId, message) {
16
17
  const key = `swarm:${taskId}:${agentId}:messages`;
17
18
  const messageJson = JSON.stringify(message);
@@ -19,6 +20,12 @@ const redisPort = process.env.CFN_REDIS_PORT || '6379';
19
20
  execSync(`redis-cli -h ${redisHost} -p ${redisPort} rpush "${key}" '${messageJson.replace(/'/g, "'\\''")}'`, {
20
21
  encoding: 'utf8'
21
22
  });
23
+ // MEMORY LEAK FIX: Set TTL on message list (24h default)
24
+ // This prevents messages from accumulating indefinitely across multiple tasks
25
+ const messageTTL = parseInt(process.env.CFN_MESSAGE_TTL || '86400', 10); // 24 hours
26
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} expire "${key}" ${messageTTL}`, {
27
+ encoding: 'utf8'
28
+ });
22
29
  } catch (error) {
23
30
  console.error(`[conversation-fork] Failed to store message:`, error);
24
31
  throw error;
@@ -46,6 +53,7 @@ const redisPort = process.env.CFN_REDIS_PORT || '6379';
46
53
  /**
47
54
  * Create a fork from current conversation state
48
55
  * Copies all messages up to current iteration
56
+ * MEMORY LEAK FIX: Now sets TTL on fork message list matching metadata TTL
49
57
  */ export async function createFork(taskId, agentId, currentIteration) {
50
58
  // Generate unique fork ID
51
59
  const forkId = `fork-${currentIteration}-${randomBytes(4).toString('hex')}`;
@@ -57,12 +65,17 @@ const redisPort = process.env.CFN_REDIS_PORT || '6379';
57
65
  }
58
66
  // Store fork snapshot
59
67
  const forkKey = `swarm:${taskId}:${agentId}:fork:${forkId}:messages`;
68
+ const forkTTL = parseInt(process.env.CFN_FORK_TTL || '86400', 10); // 24 hours
60
69
  for (const message of forkMessages){
61
70
  const messageJson = JSON.stringify(message);
62
71
  execSync(`redis-cli -h ${redisHost} -p ${redisPort} rpush "${forkKey}" '${messageJson.replace(/'/g, "'\\''")}'`, {
63
72
  encoding: 'utf8'
64
73
  });
65
74
  }
75
+ // MEMORY LEAK FIX: Set TTL on fork messages (was missing before)
76
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} expire "${forkKey}" ${forkTTL}`, {
77
+ encoding: 'utf8'
78
+ });
66
79
  // Store fork metadata
67
80
  const metadata = {
68
81
  forkId,
@@ -73,15 +86,15 @@ const redisPort = process.env.CFN_REDIS_PORT || '6379';
73
86
  messageCount: forkMessages.length
74
87
  };
75
88
  const metaKey = `swarm:${taskId}:${agentId}:fork:${forkId}:meta`;
76
- execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex "${metaKey}" 86400 '${JSON.stringify(metadata)}'`, {
89
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex "${metaKey}" ${forkTTL} '${JSON.stringify(metadata)}'`, {
77
90
  encoding: 'utf8'
78
91
  });
79
92
  // Set as current fork
80
93
  const currentForkKey = `swarm:${taskId}:${agentId}:current-fork`;
81
- execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex "${currentForkKey}" 86400 "${forkId}"`, {
94
+ execSync(`redis-cli -h ${redisHost} -p ${redisPort} setex "${currentForkKey}" ${forkTTL} "${forkId}"`, {
82
95
  encoding: 'utf8'
83
96
  });
84
- console.log(`[conversation-fork] Created fork ${forkId} with ${forkMessages.length} messages`);
97
+ console.log(`[conversation-fork] Created fork ${forkId} with ${forkMessages.length} messages (TTL: ${forkTTL}s)`);
85
98
  return forkId;
86
99
  }
87
100
  /**