@ebowwa/stack 0.1.1 → 0.1.2
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/dist/index.js +47 -27
- package/package.json +1 -1
- package/src/index.ts +60 -28
package/dist/index.js
CHANGED
|
@@ -52387,7 +52387,7 @@ ${taggedContent}`
|
|
|
52387
52387
|
}
|
|
52388
52388
|
function parseMemoryCommand(memory, channel, message) {
|
|
52389
52389
|
const trimmed = message.trim();
|
|
52390
|
-
const isMemoryCommand = trimmed.startsWith("/memory ") || trimmed.startsWith("!memory ");
|
|
52390
|
+
const isMemoryCommand = trimmed === "/memory" || trimmed === "!memory" || trimmed.startsWith("/memory ") || trimmed.startsWith("!memory ");
|
|
52391
52391
|
if (!isMemoryCommand) {
|
|
52392
52392
|
return { handled: false };
|
|
52393
52393
|
}
|
|
@@ -57408,8 +57408,7 @@ class Stack {
|
|
|
57408
57408
|
abortController = null;
|
|
57409
57409
|
constructor(config) {
|
|
57410
57410
|
this.config = {
|
|
57411
|
-
|
|
57412
|
-
telegram: config.telegram ?? {},
|
|
57411
|
+
...config,
|
|
57413
57412
|
api: config.api ?? { port: 8911 },
|
|
57414
57413
|
ralph: config.ralph ?? { worktreesDir: "/root/worktrees", repoUrl: "" },
|
|
57415
57414
|
ai: config.ai ?? { model: "GLM-4.7", temperature: 0.7, maxTokens: 4096 },
|
|
@@ -57418,27 +57417,37 @@ class Stack {
|
|
|
57418
57417
|
this.state = {
|
|
57419
57418
|
started: new Date,
|
|
57420
57419
|
channels: { ssh: false, telegram: false },
|
|
57421
|
-
api: { enabled: !!this.config.api },
|
|
57420
|
+
api: { enabled: !!this.config.api, port: this.config.api?.port },
|
|
57422
57421
|
ralphLoops: new Map
|
|
57423
57422
|
};
|
|
57423
|
+
const memoryChannels = {};
|
|
57424
|
+
const permissions = {};
|
|
57425
|
+
const enabledChannels = [];
|
|
57426
|
+
if (this.config.ssh) {
|
|
57427
|
+
memoryChannels.ssh = { memoryFile: `${this.config.ssh.chatDir}/memory.json`, maxMessages: 50 };
|
|
57428
|
+
enabledChannels.push("ssh");
|
|
57429
|
+
}
|
|
57430
|
+
if (this.config.telegram) {
|
|
57431
|
+
memoryChannels.telegram = { memoryFile: "/root/.telegram-memory.json", maxMessages: 50 };
|
|
57432
|
+
enabledChannels.push("telegram");
|
|
57433
|
+
}
|
|
57434
|
+
if (this.config.api) {
|
|
57435
|
+
memoryChannels.api = { memoryFile: "/root/.api-memory.json", maxMessages: 100 };
|
|
57436
|
+
enabledChannels.push("api");
|
|
57437
|
+
}
|
|
57438
|
+
for (const channel of enabledChannels) {
|
|
57439
|
+
permissions[channel] = { canRead: enabledChannels.filter((c) => c !== channel) };
|
|
57440
|
+
}
|
|
57424
57441
|
this.memory = createPermissionMemory({
|
|
57425
|
-
channels:
|
|
57426
|
-
|
|
57427
|
-
telegram: { memoryFile: "/root/.telegram-memory.json", maxMessages: 50 },
|
|
57428
|
-
api: { memoryFile: "/root/.api-memory.json", maxMessages: 100 }
|
|
57429
|
-
},
|
|
57430
|
-
permissions: {
|
|
57431
|
-
ssh: { canRead: ["telegram", "api"] },
|
|
57432
|
-
telegram: { canRead: ["ssh", "api"] },
|
|
57433
|
-
api: { canRead: ["ssh", "telegram"] }
|
|
57434
|
-
}
|
|
57442
|
+
channels: memoryChannels,
|
|
57443
|
+
permissions
|
|
57435
57444
|
});
|
|
57436
57445
|
this.router = createChannelRouter({
|
|
57437
57446
|
announcement: {
|
|
57438
57447
|
serverName: this.config.node.name,
|
|
57439
57448
|
hostname: this.config.node.hostname,
|
|
57440
57449
|
packageName: "@ebowwa/stack",
|
|
57441
|
-
version: "0.1.
|
|
57450
|
+
version: "0.1.1"
|
|
57442
57451
|
}
|
|
57443
57452
|
});
|
|
57444
57453
|
this.client = new GLMClient;
|
|
@@ -57621,10 +57630,15 @@ Prompt: ${prompt.slice(0, 100)}...`;
|
|
|
57621
57630
|
await this.router.start();
|
|
57622
57631
|
this.startAPI();
|
|
57623
57632
|
console.log("[Stack] Running!");
|
|
57624
|
-
|
|
57633
|
+
if (this.state.channels.ssh) {
|
|
57634
|
+
console.log(` - SSH: echo 'msg' > ${this.config.ssh.chatDir}/in`);
|
|
57635
|
+
}
|
|
57625
57636
|
if (this.state.channels.telegram) {
|
|
57626
57637
|
console.log(" - Telegram: enabled");
|
|
57627
57638
|
}
|
|
57639
|
+
if (this.state.api.enabled) {
|
|
57640
|
+
console.log(` - API: :${this.state.api.port}`);
|
|
57641
|
+
}
|
|
57628
57642
|
console.log(" - Commands: /ralph start|list|stop, /status, /memory <cmd>");
|
|
57629
57643
|
await new Promise(() => {});
|
|
57630
57644
|
}
|
|
@@ -57640,17 +57654,22 @@ Prompt: ${prompt.slice(0, 100)}...`;
|
|
|
57640
57654
|
}
|
|
57641
57655
|
}
|
|
57642
57656
|
async function main() {
|
|
57643
|
-
const
|
|
57644
|
-
|
|
57645
|
-
|
|
57646
|
-
|
|
57647
|
-
|
|
57648
|
-
|
|
57649
|
-
|
|
57650
|
-
|
|
57651
|
-
|
|
57657
|
+
const config = {
|
|
57658
|
+
...process.env.SSH_CHAT_DIR ? {
|
|
57659
|
+
ssh: {
|
|
57660
|
+
chatDir: process.env.SSH_CHAT_DIR,
|
|
57661
|
+
pollInterval: parseInt(process.env.SSH_POLL_INTERVAL || "500", 10)
|
|
57662
|
+
}
|
|
57663
|
+
} : {},
|
|
57664
|
+
...process.env.TELEGRAM_BOT_TOKEN ? {
|
|
57665
|
+
telegram: {
|
|
57666
|
+
botToken: process.env.TELEGRAM_BOT_TOKEN,
|
|
57667
|
+
allowedChats: process.env.TELEGRAM_CHAT_ID ? [parseInt(process.env.TELEGRAM_CHAT_ID, 10)] : undefined
|
|
57668
|
+
}
|
|
57669
|
+
} : {},
|
|
57652
57670
|
api: {
|
|
57653
|
-
port: parseInt(process.env.API_PORT || "8911", 10)
|
|
57671
|
+
port: parseInt(process.env.API_PORT || "8911", 10),
|
|
57672
|
+
host: process.env.API_HOST
|
|
57654
57673
|
},
|
|
57655
57674
|
ralph: {
|
|
57656
57675
|
worktreesDir: process.env.WORKTREES_DIR || "/root/worktrees",
|
|
@@ -57660,7 +57679,8 @@ async function main() {
|
|
|
57660
57679
|
name: process.env.NODE_NAME || "stack",
|
|
57661
57680
|
hostname: process.env.HOSTNAME || "localhost"
|
|
57662
57681
|
}
|
|
57663
|
-
}
|
|
57682
|
+
};
|
|
57683
|
+
const stack = new Stack(config);
|
|
57664
57684
|
process.on("SIGINT", async () => {
|
|
57665
57685
|
await stack.stop();
|
|
57666
57686
|
process.exit(0);
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -94,7 +94,7 @@ interface RalphLoopInfo {
|
|
|
94
94
|
// ============================================================
|
|
95
95
|
|
|
96
96
|
export class Stack {
|
|
97
|
-
private config:
|
|
97
|
+
private config: StackConfig;
|
|
98
98
|
private state: StackState;
|
|
99
99
|
private router: ReturnType<typeof createChannelRouter>;
|
|
100
100
|
private memory: ReturnType<typeof createPermissionMemory>;
|
|
@@ -104,34 +104,50 @@ export class Stack {
|
|
|
104
104
|
private abortController: AbortController | null = null;
|
|
105
105
|
|
|
106
106
|
constructor(config: StackConfig) {
|
|
107
|
+
// Only set defaults for non-channel config
|
|
107
108
|
this.config = {
|
|
108
|
-
|
|
109
|
-
telegram: config.telegram ?? {},
|
|
109
|
+
...config,
|
|
110
110
|
api: config.api ?? { port: 8911 },
|
|
111
111
|
ralph: config.ralph ?? { worktreesDir: "/root/worktrees", repoUrl: "" },
|
|
112
112
|
ai: config.ai ?? { model: "GLM-4.7", temperature: 0.7, maxTokens: 4096 },
|
|
113
113
|
node: config.node ?? { name: "stack", hostname: "localhost" },
|
|
114
|
+
// ssh and telegram remain undefined if not provided
|
|
114
115
|
};
|
|
115
116
|
|
|
116
117
|
this.state = {
|
|
117
118
|
started: new Date(),
|
|
118
119
|
channels: { ssh: false, telegram: false },
|
|
119
|
-
api: { enabled: !!this.config.api },
|
|
120
|
+
api: { enabled: !!this.config.api, port: this.config.api?.port },
|
|
120
121
|
ralphLoops: new Map(),
|
|
121
122
|
};
|
|
122
123
|
|
|
123
|
-
//
|
|
124
|
+
// Build memory channels dynamically based on enabled channels
|
|
125
|
+
const memoryChannels: Record<string, { memoryFile: string; maxMessages: number }> = {};
|
|
126
|
+
const permissions: Record<string, { canRead: string[] }> = {};
|
|
127
|
+
const enabledChannels: string[] = [];
|
|
128
|
+
|
|
129
|
+
if (this.config.ssh) {
|
|
130
|
+
memoryChannels.ssh = { memoryFile: `${this.config.ssh.chatDir}/memory.json`, maxMessages: 50 };
|
|
131
|
+
enabledChannels.push("ssh");
|
|
132
|
+
}
|
|
133
|
+
if (this.config.telegram) {
|
|
134
|
+
memoryChannels.telegram = { memoryFile: "/root/.telegram-memory.json", maxMessages: 50 };
|
|
135
|
+
enabledChannels.push("telegram");
|
|
136
|
+
}
|
|
137
|
+
if (this.config.api) {
|
|
138
|
+
memoryChannels.api = { memoryFile: "/root/.api-memory.json", maxMessages: 100 };
|
|
139
|
+
enabledChannels.push("api");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Set up cross-channel permissions for enabled channels
|
|
143
|
+
for (const channel of enabledChannels) {
|
|
144
|
+
permissions[channel] = { canRead: enabledChannels.filter(c => c !== channel) };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Initialize shared memory (empty if no channels)
|
|
124
148
|
this.memory = createPermissionMemory({
|
|
125
|
-
channels:
|
|
126
|
-
|
|
127
|
-
telegram: { memoryFile: "/root/.telegram-memory.json", maxMessages: 50 },
|
|
128
|
-
api: { memoryFile: "/root/.api-memory.json", maxMessages: 100 },
|
|
129
|
-
},
|
|
130
|
-
permissions: {
|
|
131
|
-
ssh: { canRead: ["telegram", "api"] },
|
|
132
|
-
telegram: { canRead: ["ssh", "api"] },
|
|
133
|
-
api: { canRead: ["ssh", "telegram"] },
|
|
134
|
-
},
|
|
149
|
+
channels: memoryChannels,
|
|
150
|
+
permissions,
|
|
135
151
|
});
|
|
136
152
|
|
|
137
153
|
// Initialize router
|
|
@@ -140,7 +156,7 @@ export class Stack {
|
|
|
140
156
|
serverName: this.config.node.name,
|
|
141
157
|
hostname: this.config.node.hostname,
|
|
142
158
|
packageName: "@ebowwa/stack",
|
|
143
|
-
version: "0.1.
|
|
159
|
+
version: "0.1.1",
|
|
144
160
|
},
|
|
145
161
|
});
|
|
146
162
|
|
|
@@ -376,7 +392,7 @@ export class Stack {
|
|
|
376
392
|
|
|
377
393
|
this.abortController = new AbortController();
|
|
378
394
|
|
|
379
|
-
// Register channels
|
|
395
|
+
// Register channels (only if configured)
|
|
380
396
|
await this.registerSSH();
|
|
381
397
|
await this.registerTelegram();
|
|
382
398
|
|
|
@@ -390,10 +406,15 @@ export class Stack {
|
|
|
390
406
|
this.startAPI();
|
|
391
407
|
|
|
392
408
|
console.log("[Stack] Running!");
|
|
393
|
-
|
|
409
|
+
if (this.state.channels.ssh) {
|
|
410
|
+
console.log(` - SSH: echo 'msg' > ${this.config.ssh!.chatDir}/in`);
|
|
411
|
+
}
|
|
394
412
|
if (this.state.channels.telegram) {
|
|
395
413
|
console.log(" - Telegram: enabled");
|
|
396
414
|
}
|
|
415
|
+
if (this.state.api.enabled) {
|
|
416
|
+
console.log(` - API: :${this.state.api.port}`);
|
|
417
|
+
}
|
|
397
418
|
console.log(" - Commands: /ralph start|list|stop, /status, /memory <cmd>");
|
|
398
419
|
|
|
399
420
|
// Keep running
|
|
@@ -420,17 +441,26 @@ export class Stack {
|
|
|
420
441
|
// ============================================================
|
|
421
442
|
|
|
422
443
|
async function main() {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
},
|
|
444
|
+
// Build config - only enable channels when explicitly configured
|
|
445
|
+
const config: StackConfig = {
|
|
446
|
+
// SSH only enabled if SSH_CHAT_DIR is set
|
|
447
|
+
...(process.env.SSH_CHAT_DIR ? {
|
|
448
|
+
ssh: {
|
|
449
|
+
chatDir: process.env.SSH_CHAT_DIR,
|
|
450
|
+
pollInterval: parseInt(process.env.SSH_POLL_INTERVAL || "500", 10),
|
|
451
|
+
}
|
|
452
|
+
} : {}),
|
|
453
|
+
// Telegram only enabled if bot token is set
|
|
454
|
+
...(process.env.TELEGRAM_BOT_TOKEN ? {
|
|
455
|
+
telegram: {
|
|
456
|
+
botToken: process.env.TELEGRAM_BOT_TOKEN,
|
|
457
|
+
allowedChats: process.env.TELEGRAM_CHAT_ID ? [parseInt(process.env.TELEGRAM_CHAT_ID, 10)] : undefined,
|
|
458
|
+
}
|
|
459
|
+
} : {}),
|
|
460
|
+
// API enabled by default
|
|
432
461
|
api: {
|
|
433
462
|
port: parseInt(process.env.API_PORT || "8911", 10),
|
|
463
|
+
host: process.env.API_HOST,
|
|
434
464
|
},
|
|
435
465
|
ralph: {
|
|
436
466
|
worktreesDir: process.env.WORKTREES_DIR || "/root/worktrees",
|
|
@@ -440,7 +470,9 @@ async function main() {
|
|
|
440
470
|
name: process.env.NODE_NAME || "stack",
|
|
441
471
|
hostname: process.env.HOSTNAME || "localhost",
|
|
442
472
|
},
|
|
443
|
-
}
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
const stack = new Stack(config);
|
|
444
476
|
|
|
445
477
|
// Handle shutdown
|
|
446
478
|
process.on("SIGINT", async () => {
|