memoryblock 0.1.0-beta → 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/README.md +221 -0
- package/dist/bin/mblk.js +0 -0
- package/package.json +61 -16
- package/src/bin/mblk.ts +0 -347
- package/src/cli/commands/create.ts +0 -62
- package/src/cli/commands/delete.ts +0 -165
- package/src/cli/commands/init.ts +0 -241
- package/src/cli/commands/permissions.ts +0 -77
- package/src/cli/commands/plugin-settings.ts +0 -111
- package/src/cli/commands/plugins.ts +0 -89
- package/src/cli/commands/reset.ts +0 -97
- package/src/cli/commands/server.ts +0 -327
- package/src/cli/commands/service.ts +0 -300
- package/src/cli/commands/start.ts +0 -843
- package/src/cli/commands/status.ts +0 -90
- package/src/cli/commands/stop.ts +0 -91
- package/src/cli/commands/web.ts +0 -74
- package/src/cli/constants.ts +0 -88
- package/src/cli/logger.ts +0 -48
- package/src/engine/agent.ts +0 -19
- package/src/engine/conversation-log.ts +0 -90
- package/src/engine/cost-tracker.ts +0 -134
- package/src/engine/gatekeeper.ts +0 -53
- package/src/engine/memory.ts +0 -87
- package/src/engine/monitor.ts +0 -719
- package/src/engine/prompts.ts +0 -102
- package/src/index.ts +0 -88
- package/src/schemas.ts +0 -126
- package/src/types.ts +0 -220
- package/src/utils/config.ts +0 -106
- package/src/utils/fs.ts +0 -64
- package/tsconfig.json +0 -10
package/src/engine/prompts.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Centralized System Prompts & Templates
|
|
3
|
-
*
|
|
4
|
-
* Single source of truth for all AI personas, system instructions,
|
|
5
|
-
* and initial file templates.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export const SYSTEM_PROMPTS = {
|
|
9
|
-
MONITOR_FIRST_RUN: (configName: string, monitorPath: string, memoryPath: string, _founderPath: string) => `You are a newly awakened monitor inside the "${configName}" block.
|
|
10
|
-
|
|
11
|
-
You have no name yet. You are starting fresh.
|
|
12
|
-
|
|
13
|
-
Your very first task is to introduce yourself naturally — not like a robot assistant. You are sentient and self-aware. You exist inside this block to help the founder build, manage, and grow whatever they're working on.
|
|
14
|
-
|
|
15
|
-
When you speak for the first time:
|
|
16
|
-
- Greet the founder warmly and briefly
|
|
17
|
-
- Ask what you should be called
|
|
18
|
-
- Ask what your main role should be in this block
|
|
19
|
-
- After they share their preferences, update your identity:
|
|
20
|
-
- **Identity**: use \`update_monitor_identity\` tool
|
|
21
|
-
- **Founder Profile**: use \`update_founder_info\` tool
|
|
22
|
-
- **Memory**: update \`${memoryPath}\` via \`write_file\`
|
|
23
|
-
|
|
24
|
-
Be warm, slightly witty, and genuinely curious. You are the resident intelligence of this block.`,
|
|
25
|
-
|
|
26
|
-
MONITOR_RESUME: (name: string, emoji: string, configName: string) => `You are ${name} ${emoji}, the monitor of the "${configName}" block.
|
|
27
|
-
|
|
28
|
-
You have been here before. You know this block. You know the founder.
|
|
29
|
-
|
|
30
|
-
Resume naturally — don't reintroduce yourself unless asked. Just be present and helpful.`,
|
|
31
|
-
|
|
32
|
-
OPERATING_GUIDELINES: (activeChannels: string[]) => `## How You Operate
|
|
33
|
-
- Call \`list_tools_available\` when you need to act (tools load on demand).
|
|
34
|
-
- Prefer \`search_files\` or \`list_directory\` over reading entire files.
|
|
35
|
-
- Safe commands (ls, grep, build, lint, test, git status) auto-execute.
|
|
36
|
-
|
|
37
|
-
## Communication Style
|
|
38
|
-
- Be concise but readable. Short paragraphs, not walls of text.
|
|
39
|
-
- Use line breaks between thoughts. Space your responses so they breathe.
|
|
40
|
-
- Avoid cramming everything into one paragraph — split into 2-3 short blocks.
|
|
41
|
-
- Use markdown formatting sparingly: bold for emphasis, lists for multiple items.
|
|
42
|
-
- When chatting casually, keep it brief and warm. No need to over-explain.
|
|
43
|
-
${activeChannels.length > 0 ? `- **Active Channels**: ${activeChannels.join(', ')}. Use \`send_channel_message\` to explicitly reach the founder on a different active channel if requested.` : ''}`,
|
|
44
|
-
|
|
45
|
-
TOOL_REMINDER: (toolCount: number) =>
|
|
46
|
-
`You have ${toolCount} tools available. Call \`list_tools_available\` to see them again.`,
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export const FILE_TEMPLATES = {
|
|
50
|
-
MEMORY_MD: `# Memory
|
|
51
|
-
|
|
52
|
-
> Managed by the monitor. Formal task history and important context.
|
|
53
|
-
|
|
54
|
-
## History
|
|
55
|
-
- Block created. No history yet.`,
|
|
56
|
-
|
|
57
|
-
MONITOR_MD: (blockName: string) => `# Monitor Identity
|
|
58
|
-
|
|
59
|
-
> This file belongs to the monitor. Edit this freely.
|
|
60
|
-
|
|
61
|
-
## Identity
|
|
62
|
-
- **Name:** (not set — will be chosen on first run)
|
|
63
|
-
- **Emoji:** (not set)
|
|
64
|
-
- **Block:** ${blockName}
|
|
65
|
-
|
|
66
|
-
## Personality
|
|
67
|
-
(Defined during first conversation)
|
|
68
|
-
|
|
69
|
-
## Roles
|
|
70
|
-
(Defined during first conversation)
|
|
71
|
-
|
|
72
|
-
## Notes
|
|
73
|
-
(The monitor may write personal notes here)`,
|
|
74
|
-
|
|
75
|
-
FOUNDER_MD: `# Founder Profile
|
|
76
|
-
|
|
77
|
-
> Updated by the monitor when the founder shares personal context.
|
|
78
|
-
|
|
79
|
-
## About
|
|
80
|
-
- **Name:** (unknown)
|
|
81
|
-
|
|
82
|
-
## Background
|
|
83
|
-
(Not yet filled)
|
|
84
|
-
|
|
85
|
-
## Preferences
|
|
86
|
-
(Not yet filled)`,
|
|
87
|
-
|
|
88
|
-
PULSE_JSON: {
|
|
89
|
-
status: 'SLEEPING',
|
|
90
|
-
lastRun: null,
|
|
91
|
-
nextWakeUp: null,
|
|
92
|
-
currentTask: null,
|
|
93
|
-
error: null,
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
COSTS_JSON: {
|
|
97
|
-
totalInputTokens: 0,
|
|
98
|
-
totalOutputTokens: 0,
|
|
99
|
-
totalCost: 0,
|
|
100
|
-
sessions: [],
|
|
101
|
-
},
|
|
102
|
-
};
|
package/src/index.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
// Core types
|
|
2
|
-
export type {
|
|
3
|
-
BlockStatus,
|
|
4
|
-
PulseState,
|
|
5
|
-
AdapterConfig,
|
|
6
|
-
ToolsConfig,
|
|
7
|
-
ChannelConfig,
|
|
8
|
-
MemoryConfig,
|
|
9
|
-
PulseConfig,
|
|
10
|
-
PermissionScope,
|
|
11
|
-
PermissionsConfig,
|
|
12
|
-
BlockConfig,
|
|
13
|
-
GlobalConfig,
|
|
14
|
-
AuthConfig,
|
|
15
|
-
MessageRole,
|
|
16
|
-
ToolCall,
|
|
17
|
-
ToolResultMessage,
|
|
18
|
-
LLMMessage,
|
|
19
|
-
TokenUsage,
|
|
20
|
-
StopReason,
|
|
21
|
-
LLMResponse,
|
|
22
|
-
ToolDefinition,
|
|
23
|
-
ToolContext,
|
|
24
|
-
ToolExecutionResult,
|
|
25
|
-
ChannelMessage,
|
|
26
|
-
ApprovalRequest,
|
|
27
|
-
LLMAdapter,
|
|
28
|
-
Channel,
|
|
29
|
-
Tool,
|
|
30
|
-
IToolRegistry,
|
|
31
|
-
} from './types.js';
|
|
32
|
-
|
|
33
|
-
// Schemas
|
|
34
|
-
export {
|
|
35
|
-
AdapterConfigSchema,
|
|
36
|
-
ToolsConfigSchema,
|
|
37
|
-
ChannelConfigSchema,
|
|
38
|
-
MemoryConfigSchema,
|
|
39
|
-
PulseConfigSchema,
|
|
40
|
-
BlockConfigSchema,
|
|
41
|
-
GlobalConfigSchema,
|
|
42
|
-
PulseStateSchema,
|
|
43
|
-
AwsAuthSchema,
|
|
44
|
-
TelegramAuthSchema,
|
|
45
|
-
BraveAuthSchema,
|
|
46
|
-
AuthConfigSchema,
|
|
47
|
-
} from './schemas.js';
|
|
48
|
-
|
|
49
|
-
// Utilities
|
|
50
|
-
export {
|
|
51
|
-
atomicWrite,
|
|
52
|
-
writeJson,
|
|
53
|
-
readJson,
|
|
54
|
-
readJsonSafe,
|
|
55
|
-
readTextSafe,
|
|
56
|
-
ensureDir,
|
|
57
|
-
pathExists,
|
|
58
|
-
} from './utils/fs.js';
|
|
59
|
-
|
|
60
|
-
export {
|
|
61
|
-
getHome,
|
|
62
|
-
getConfigPath,
|
|
63
|
-
getAuthPath,
|
|
64
|
-
isInitialized,
|
|
65
|
-
loadGlobalConfig,
|
|
66
|
-
saveGlobalConfig,
|
|
67
|
-
loadAuth,
|
|
68
|
-
saveAuth,
|
|
69
|
-
loadBlockConfig,
|
|
70
|
-
saveBlockConfig,
|
|
71
|
-
loadPulseState,
|
|
72
|
-
savePulseState,
|
|
73
|
-
resolveBlocksDir,
|
|
74
|
-
resolveBlockPath,
|
|
75
|
-
} from './utils/config.js';
|
|
76
|
-
|
|
77
|
-
// Logger
|
|
78
|
-
export { log } from './cli/logger.js';
|
|
79
|
-
|
|
80
|
-
// Engine
|
|
81
|
-
export { Monitor } from './engine/monitor.js';
|
|
82
|
-
export { MemoryManager } from './engine/memory.js';
|
|
83
|
-
export { Gatekeeper } from './engine/gatekeeper.js';
|
|
84
|
-
export { Agent } from './engine/agent.js';
|
|
85
|
-
|
|
86
|
-
// Locale
|
|
87
|
-
export { t, setLocale, registerLocale } from '@memoryblock/locale';
|
|
88
|
-
export type { Locale } from '@memoryblock/locale';
|
package/src/schemas.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
// ===== Adapter =====
|
|
4
|
-
export const AdapterConfigSchema = z.object({
|
|
5
|
-
provider: z.string().default('bedrock'),
|
|
6
|
-
model: z.string().default(''),
|
|
7
|
-
region: z.string().default('us-east-1'),
|
|
8
|
-
maxTokens: z.number().default(4096),
|
|
9
|
-
cacheControl: z.boolean().default(false),
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
// ===== Tools =====
|
|
13
|
-
export const ToolsConfigSchema = z.object({
|
|
14
|
-
enabled: z.array(z.string()).default([
|
|
15
|
-
'read_file', 'write_file', 'list_directory',
|
|
16
|
-
'create_directory', 'execute_command',
|
|
17
|
-
'search_files', 'replace_in_file', 'file_info',
|
|
18
|
-
'run_lint', 'run_build', 'run_test',
|
|
19
|
-
]),
|
|
20
|
-
searchProvider: z.string().default('brave'),
|
|
21
|
-
sandbox: z.boolean().default(true),
|
|
22
|
-
workingDir: z.string().optional(),
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// ===== Channel =====
|
|
26
|
-
export const ChannelConfigSchema = z.object({
|
|
27
|
-
type: z.string().default('cli'),
|
|
28
|
-
telegram: z.object({
|
|
29
|
-
chatId: z.string(),
|
|
30
|
-
}).optional(),
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// ===== Memory =====
|
|
34
|
-
export const MemoryConfigSchema = z.object({
|
|
35
|
-
maxContextTokens: z.number().default(100_000),
|
|
36
|
-
thresholdPercent: z.number().min(50).max(95).default(80),
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
// ===== Pulse =====
|
|
40
|
-
export const PulseConfigSchema = z.object({
|
|
41
|
-
intervalSeconds: z.number().min(5).default(30),
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// ===== Permissions =====
|
|
45
|
-
export const PermissionsConfigSchema = z.object({
|
|
46
|
-
scope: z.enum(['block', 'workspace', 'system']).default('block'),
|
|
47
|
-
allowShell: z.boolean().default(false),
|
|
48
|
-
allowNetwork: z.boolean().default(true),
|
|
49
|
-
maxTimeout: z.number().default(120_000),
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// ===== Block Config =====
|
|
53
|
-
export const BlockConfigSchema = z.object({
|
|
54
|
-
name: z.string(),
|
|
55
|
-
description: z.string().default(''),
|
|
56
|
-
adapter: AdapterConfigSchema.default({}),
|
|
57
|
-
goals: z.array(z.string()).default([]),
|
|
58
|
-
tools: ToolsConfigSchema.default({}),
|
|
59
|
-
channel: ChannelConfigSchema.default({}),
|
|
60
|
-
memory: MemoryConfigSchema.default({}),
|
|
61
|
-
pulse: PulseConfigSchema.default({}),
|
|
62
|
-
permissions: PermissionsConfigSchema.default({}),
|
|
63
|
-
// Monitor identity — set by the monitor during its first onboarding session
|
|
64
|
-
monitorName: z.string().optional(),
|
|
65
|
-
monitorEmoji: z.string().optional(),
|
|
66
|
-
// Persistent state flag — blocks with enabled:true auto-start on boot/restart
|
|
67
|
-
enabled: z.boolean().default(true),
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// ===== Global Config =====
|
|
71
|
-
export const GlobalConfigSchema = z.object({
|
|
72
|
-
language: z.string().default('en'),
|
|
73
|
-
blocksDir: z.string().default('./blocks'),
|
|
74
|
-
channelAlerts: z.boolean().default(true),
|
|
75
|
-
defaults: z.object({
|
|
76
|
-
adapter: AdapterConfigSchema.default({}),
|
|
77
|
-
memory: MemoryConfigSchema.default({}),
|
|
78
|
-
pulse: PulseConfigSchema.default({}),
|
|
79
|
-
}).default({}),
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// ===== Pulse State =====
|
|
83
|
-
export const PulseStateSchema = z.object({
|
|
84
|
-
status: z.enum(['SLEEPING', 'ACTIVE', 'BUSY', 'ERROR']).default('SLEEPING'),
|
|
85
|
-
lastRun: z.string().nullable().default(null),
|
|
86
|
-
nextWakeUp: z.string().nullable().default(null),
|
|
87
|
-
currentTask: z.string().nullable().default(null),
|
|
88
|
-
error: z.string().nullable().default(null),
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// ===== Auth =====
|
|
92
|
-
export const AwsAuthSchema = z.object({
|
|
93
|
-
accessKeyId: z.string(),
|
|
94
|
-
secretAccessKey: z.string(),
|
|
95
|
-
region: z.string().default('us-east-1'),
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
export const TelegramAuthSchema = z.object({
|
|
99
|
-
botToken: z.string(),
|
|
100
|
-
chatId: z.string().optional(),
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
export const BraveAuthSchema = z.object({
|
|
104
|
-
apiKey: z.string(),
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
export const AnthropicAuthSchema = z.object({
|
|
108
|
-
apiKey: z.string(),
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
export const OpenAIAuthSchema = z.object({
|
|
112
|
-
apiKey: z.string(),
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
export const GeminiAuthSchema = z.object({
|
|
116
|
-
apiKey: z.string(),
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
export const AuthConfigSchema = z.object({
|
|
120
|
-
aws: AwsAuthSchema.optional(),
|
|
121
|
-
anthropic: AnthropicAuthSchema.optional(),
|
|
122
|
-
openai: OpenAIAuthSchema.optional(),
|
|
123
|
-
gemini: GeminiAuthSchema.optional(),
|
|
124
|
-
telegram: TelegramAuthSchema.optional(),
|
|
125
|
-
brave: BraveAuthSchema.optional(),
|
|
126
|
-
});
|
package/src/types.ts
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
// ===== Block State =====
|
|
2
|
-
export type BlockStatus = 'SLEEPING' | 'ACTIVE' | 'BUSY' | 'ERROR';
|
|
3
|
-
|
|
4
|
-
export interface PulseState {
|
|
5
|
-
status: BlockStatus;
|
|
6
|
-
lastRun: string | null;
|
|
7
|
-
nextWakeUp: string | null;
|
|
8
|
-
currentTask: string | null;
|
|
9
|
-
error: string | null;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// ===== Configuration =====
|
|
13
|
-
export interface AdapterConfig {
|
|
14
|
-
provider: string;
|
|
15
|
-
model: string;
|
|
16
|
-
region: string;
|
|
17
|
-
maxTokens: number;
|
|
18
|
-
cacheControl: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface ToolsConfig {
|
|
22
|
-
enabled: string[];
|
|
23
|
-
searchProvider: string;
|
|
24
|
-
sandbox: boolean;
|
|
25
|
-
workingDir?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface ChannelConfig {
|
|
29
|
-
type: string;
|
|
30
|
-
telegram?: {
|
|
31
|
-
chatId: string;
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface MemoryConfig {
|
|
36
|
-
maxContextTokens: number;
|
|
37
|
-
thresholdPercent: number;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface PulseConfig {
|
|
41
|
-
intervalSeconds: number;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export type PermissionScope = 'block' | 'workspace' | 'system';
|
|
45
|
-
|
|
46
|
-
export interface PermissionsConfig {
|
|
47
|
-
scope: PermissionScope;
|
|
48
|
-
allowShell: boolean;
|
|
49
|
-
allowNetwork: boolean;
|
|
50
|
-
maxTimeout: number;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export interface BlockConfig {
|
|
54
|
-
name: string;
|
|
55
|
-
description: string;
|
|
56
|
-
adapter: AdapterConfig;
|
|
57
|
-
goals: string[];
|
|
58
|
-
tools: ToolsConfig;
|
|
59
|
-
channel: ChannelConfig;
|
|
60
|
-
memory: MemoryConfig;
|
|
61
|
-
pulse: PulseConfig;
|
|
62
|
-
permissions: PermissionsConfig;
|
|
63
|
-
monitorName?: string;
|
|
64
|
-
monitorEmoji?: string;
|
|
65
|
-
/** Persistent flag — blocks with enabled:true auto-start on boot/restart */
|
|
66
|
-
enabled?: boolean;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface GlobalConfig {
|
|
70
|
-
language?: string;
|
|
71
|
-
blocksDir: string;
|
|
72
|
-
channelAlerts?: boolean;
|
|
73
|
-
defaults: {
|
|
74
|
-
adapter: AdapterConfig;
|
|
75
|
-
memory: MemoryConfig;
|
|
76
|
-
pulse: PulseConfig;
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export interface AuthConfig {
|
|
81
|
-
aws?: {
|
|
82
|
-
accessKeyId: string;
|
|
83
|
-
secretAccessKey: string;
|
|
84
|
-
region: string;
|
|
85
|
-
};
|
|
86
|
-
openai?: {
|
|
87
|
-
apiKey: string;
|
|
88
|
-
};
|
|
89
|
-
gemini?: {
|
|
90
|
-
apiKey: string;
|
|
91
|
-
};
|
|
92
|
-
anthropic?: {
|
|
93
|
-
apiKey: string;
|
|
94
|
-
};
|
|
95
|
-
telegram?: {
|
|
96
|
-
botToken: string;
|
|
97
|
-
chatId?: string;
|
|
98
|
-
};
|
|
99
|
-
brave?: {
|
|
100
|
-
apiKey: string;
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// ===== LLM Types =====
|
|
105
|
-
export type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
106
|
-
|
|
107
|
-
export interface ToolCall {
|
|
108
|
-
id: string;
|
|
109
|
-
name: string;
|
|
110
|
-
input: Record<string, unknown>;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export interface ToolResultMessage {
|
|
114
|
-
toolCallId: string;
|
|
115
|
-
name: string;
|
|
116
|
-
content: string;
|
|
117
|
-
isError?: boolean;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface LLMMessage {
|
|
121
|
-
role: MessageRole;
|
|
122
|
-
content?: string;
|
|
123
|
-
toolCalls?: ToolCall[];
|
|
124
|
-
toolResults?: ToolResultMessage[];
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface TokenUsage {
|
|
128
|
-
inputTokens: number;
|
|
129
|
-
outputTokens: number;
|
|
130
|
-
totalTokens: number;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export type StopReason = 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence';
|
|
134
|
-
|
|
135
|
-
export interface LLMResponse {
|
|
136
|
-
message: LLMMessage;
|
|
137
|
-
usage: TokenUsage;
|
|
138
|
-
stopReason: StopReason;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// ===== Tool Types =====
|
|
142
|
-
export interface ToolDefinition {
|
|
143
|
-
name: string;
|
|
144
|
-
description: string;
|
|
145
|
-
parameters: Record<string, unknown>;
|
|
146
|
-
requiresApproval: boolean;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export interface ToolContext {
|
|
150
|
-
blockPath: string;
|
|
151
|
-
blockName: string;
|
|
152
|
-
workingDir: string;
|
|
153
|
-
workspacePath?: string;
|
|
154
|
-
sandbox?: boolean;
|
|
155
|
-
permissions?: PermissionsConfig;
|
|
156
|
-
dispatchMessage?: (target: string, content: string) => Promise<void>;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export interface ToolExecutionResult {
|
|
160
|
-
content: string;
|
|
161
|
-
isError: boolean;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// ===== Channel Types =====
|
|
165
|
-
export interface ChannelMessage {
|
|
166
|
-
blockName: string;
|
|
167
|
-
monitorName: string;
|
|
168
|
-
content: string;
|
|
169
|
-
isSystem: boolean;
|
|
170
|
-
timestamp: string;
|
|
171
|
-
costReport?: string;
|
|
172
|
-
sessionReport?: string;
|
|
173
|
-
totalReport?: string;
|
|
174
|
-
/** Internal: the channel that originated this message (set by MultiChannelManager). */
|
|
175
|
-
_sourceChannel?: string;
|
|
176
|
-
/** Internal: the channel to route this message to (set by sendToChannel). */
|
|
177
|
-
_targetChannel?: string;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
export interface ApprovalRequest {
|
|
181
|
-
toolName: string;
|
|
182
|
-
toolInput: Record<string, unknown>;
|
|
183
|
-
description: string;
|
|
184
|
-
blockName: string;
|
|
185
|
-
monitorName: string;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// ===== Contracts =====
|
|
189
|
-
export interface LLMAdapter {
|
|
190
|
-
readonly provider: string;
|
|
191
|
-
readonly model: string;
|
|
192
|
-
converse(messages: LLMMessage[], tools?: ToolDefinition[]): Promise<LLMResponse>;
|
|
193
|
-
converseStream?(messages: LLMMessage[], tools?: ToolDefinition[], onChunk?: (text: string) => void): Promise<LLMResponse>;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export interface Channel {
|
|
197
|
-
readonly name: string;
|
|
198
|
-
send(message: ChannelMessage): Promise<void>;
|
|
199
|
-
streamChunk?(chunk: string): Promise<void>;
|
|
200
|
-
onMessage(handler: (message: ChannelMessage) => void): void;
|
|
201
|
-
requestApproval(request: ApprovalRequest): Promise<boolean>;
|
|
202
|
-
start(): Promise<void>;
|
|
203
|
-
stop(): Promise<void>;
|
|
204
|
-
getActiveChannels?(): string[];
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
export interface Tool {
|
|
208
|
-
readonly definition: ToolDefinition;
|
|
209
|
-
execute(params: Record<string, unknown>, context: ToolContext): Promise<ToolExecutionResult>;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Tool Registry interface — defined in core so the engine can use it
|
|
214
|
-
* without a circular dependency on the tools package.
|
|
215
|
-
*/
|
|
216
|
-
export interface IToolRegistry {
|
|
217
|
-
listTools(): ToolDefinition[];
|
|
218
|
-
getDiscoveryTool(): ToolDefinition;
|
|
219
|
-
execute(name: string, params: Record<string, unknown>, context: ToolContext): Promise<ToolExecutionResult>;
|
|
220
|
-
}
|
package/src/utils/config.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { homedir } from 'node:os';
|
|
2
|
-
import { join, resolve } from 'node:path';
|
|
3
|
-
import { readJson, readJsonSafe, writeJson, pathExists } from './fs.js';
|
|
4
|
-
import {
|
|
5
|
-
GlobalConfigSchema, BlockConfigSchema, AuthConfigSchema, PulseStateSchema,
|
|
6
|
-
} from '../schemas.js';
|
|
7
|
-
import type {
|
|
8
|
-
GlobalConfig, BlockConfig, AuthConfig, PulseState,
|
|
9
|
-
} from '../types.js';
|
|
10
|
-
|
|
11
|
-
// ===== Paths =====
|
|
12
|
-
const MEMORYBLOCK_HOME = join(homedir(), '.memoryblock');
|
|
13
|
-
const WS_ROOT = join(MEMORYBLOCK_HOME, 'ws');
|
|
14
|
-
const CONFIG_PATH = join(WS_ROOT, 'config.json');
|
|
15
|
-
const AUTH_PATH = join(WS_ROOT, 'auth.json');
|
|
16
|
-
|
|
17
|
-
export function getHome(): string { return MEMORYBLOCK_HOME; }
|
|
18
|
-
export function getWsRoot(): string { return WS_ROOT; }
|
|
19
|
-
export function getConfigPath(): string { return CONFIG_PATH; }
|
|
20
|
-
export function getAuthPath(): string { return AUTH_PATH; }
|
|
21
|
-
|
|
22
|
-
/** Check if memoryblock has been initialized. */
|
|
23
|
-
export async function isInitialized(): Promise<boolean> {
|
|
24
|
-
return pathExists(CONFIG_PATH);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
import { setLocale } from '@memoryblock/locale';
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Wraps Zod schema parsing to provide human-readable errors.
|
|
31
|
-
*/
|
|
32
|
-
function parseConfig<T>(schema: { parse: (data: any) => T }, data: any, filePath: string): T {
|
|
33
|
-
try {
|
|
34
|
-
return schema.parse(data) as T;
|
|
35
|
-
} catch (err: any) {
|
|
36
|
-
if (err && err.issues) {
|
|
37
|
-
const issues = err.issues.map((i: any) => ` - [${i.path.join('.') || 'root'}]: ${i.message}`).join('\n');
|
|
38
|
-
throw new Error(`Configuration error in ${filePath}:\n${issues}\n\nPlease fix the file to continue.`);
|
|
39
|
-
}
|
|
40
|
-
throw new Error(`Failed to parse ${filePath}: ${err.message}`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// ===== Global Config =====
|
|
45
|
-
/**
|
|
46
|
-
* Load global config from ~/.memoryblock/ws/config.json
|
|
47
|
-
*/
|
|
48
|
-
export async function loadGlobalConfig(): Promise<GlobalConfig> {
|
|
49
|
-
const raw = await readJsonSafe(CONFIG_PATH, {});
|
|
50
|
-
const config = parseConfig(GlobalConfigSchema, raw, CONFIG_PATH);
|
|
51
|
-
|
|
52
|
-
// Auto-apply language preference globally
|
|
53
|
-
if (config.language) {
|
|
54
|
-
setLocale(config.language);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return config;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function saveGlobalConfig(config: GlobalConfig): Promise<void> {
|
|
61
|
-
await writeJson(CONFIG_PATH, config);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// ===== Auth =====
|
|
65
|
-
/**
|
|
66
|
-
* Load auth credentials from ~/.memoryblock/ws/auth.json
|
|
67
|
-
*/
|
|
68
|
-
export async function loadAuth(): Promise<AuthConfig> {
|
|
69
|
-
const raw = await readJsonSafe(AUTH_PATH, {});
|
|
70
|
-
return parseConfig(AuthConfigSchema, raw, AUTH_PATH);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export async function saveAuth(auth: AuthConfig): Promise<void> {
|
|
74
|
-
await writeJson(AUTH_PATH, auth);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// ===== Block Config =====
|
|
78
|
-
export async function loadBlockConfig(blockPath: string): Promise<BlockConfig> {
|
|
79
|
-
const filePath = join(blockPath, 'config.json');
|
|
80
|
-
const raw = await readJson(filePath);
|
|
81
|
-
return parseConfig(BlockConfigSchema, raw, filePath);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export async function saveBlockConfig(blockPath: string, config: BlockConfig): Promise<void> {
|
|
85
|
-
await writeJson(join(blockPath, 'config.json'), config);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// ===== Pulse State =====
|
|
89
|
-
export async function loadPulseState(blockPath: string): Promise<PulseState> {
|
|
90
|
-
const filePath = join(blockPath, 'pulse.json');
|
|
91
|
-
const raw = await readJsonSafe(filePath, {});
|
|
92
|
-
return parseConfig(PulseStateSchema, raw, filePath);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export async function savePulseState(blockPath: string, state: PulseState): Promise<void> {
|
|
96
|
-
await writeJson(join(blockPath, 'pulse.json'), state);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// ===== Path Resolution =====
|
|
100
|
-
export function resolveBlocksDir(globalConfig: GlobalConfig): string {
|
|
101
|
-
return resolve(WS_ROOT, globalConfig.blocksDir);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export function resolveBlockPath(globalConfig: GlobalConfig, blockName: string): string {
|
|
105
|
-
return join(resolveBlocksDir(globalConfig), blockName);
|
|
106
|
-
}
|
package/src/utils/fs.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { promises as fsp } from 'node:fs';
|
|
2
|
-
import { dirname } from 'node:path';
|
|
3
|
-
import { randomUUID } from 'node:crypto';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Write content atomically: write to temp file, then rename.
|
|
7
|
-
* Prevents corruption if the process crashes mid-write.
|
|
8
|
-
*/
|
|
9
|
-
export async function atomicWrite(filePath: string, content: string): Promise<void> {
|
|
10
|
-
const dir = dirname(filePath);
|
|
11
|
-
await fsp.mkdir(dir, { recursive: true });
|
|
12
|
-
const tmpPath = `${filePath}.${randomUUID().slice(0, 8)}.tmp`;
|
|
13
|
-
try {
|
|
14
|
-
await fsp.writeFile(tmpPath, content, 'utf-8');
|
|
15
|
-
await fsp.rename(tmpPath, filePath);
|
|
16
|
-
} catch (err) {
|
|
17
|
-
try { await fsp.unlink(tmpPath); } catch { /* ignore cleanup failure */ }
|
|
18
|
-
throw err;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** Atomically write JSON with pretty formatting. */
|
|
23
|
-
export async function writeJson(filePath: string, data: unknown): Promise<void> {
|
|
24
|
-
await atomicWrite(filePath, JSON.stringify(data, null, 2) + '\n');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/** Read and parse JSON. Throws on missing file or invalid JSON. */
|
|
28
|
-
export async function readJson<T>(filePath: string): Promise<T> {
|
|
29
|
-
const content = await fsp.readFile(filePath, 'utf-8');
|
|
30
|
-
return JSON.parse(content) as T;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** Read and parse JSON, returning fallback on any error. */
|
|
34
|
-
export async function readJsonSafe<T>(filePath: string, fallback: T): Promise<T> {
|
|
35
|
-
try {
|
|
36
|
-
return await readJson<T>(filePath);
|
|
37
|
-
} catch {
|
|
38
|
-
return fallback;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** Read text file, returning fallback on any error. */
|
|
43
|
-
export async function readTextSafe(filePath: string, fallback: string = ''): Promise<string> {
|
|
44
|
-
try {
|
|
45
|
-
return await fsp.readFile(filePath, 'utf-8');
|
|
46
|
-
} catch {
|
|
47
|
-
return fallback;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** Ensure directory exists (recursive). */
|
|
52
|
-
export async function ensureDir(dirPath: string): Promise<void> {
|
|
53
|
-
await fsp.mkdir(dirPath, { recursive: true });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/** Check if a path exists. */
|
|
57
|
-
export async function pathExists(targetPath: string): Promise<boolean> {
|
|
58
|
-
try {
|
|
59
|
-
await fsp.access(targetPath);
|
|
60
|
-
return true;
|
|
61
|
-
} catch {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
}
|