comisai 1.0.18 → 1.0.22
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/cli-entry.js +0 -0
- package/node_modules/@comis/agent/dist/context-engine/context-engine.js +43 -2
- package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +51 -0
- package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +110 -0
- package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.d.ts +54 -0
- package/node_modules/@comis/agent/dist/context-engine/signature-surrogate-guard.js +145 -0
- package/node_modules/@comis/agent/dist/context-engine/types-core.d.ts +17 -0
- package/node_modules/@comis/agent/dist/executor/error-classifier.d.ts +11 -1
- package/node_modules/@comis/agent/dist/executor/error-classifier.js +13 -0
- package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.d.ts +1 -0
- package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.js +55 -0
- package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +106 -5
- package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +1 -0
- package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +1 -4
- package/node_modules/@comis/agent/dist/executor/replay-drift-detector.d.ts +85 -0
- package/node_modules/@comis/agent/dist/executor/replay-drift-detector.js +92 -0
- package/node_modules/@comis/agent/dist/executor/signature-block-scrubber.d.ts +34 -0
- package/node_modules/@comis/agent/dist/executor/signature-block-scrubber.js +69 -0
- package/node_modules/@comis/agent/dist/executor/signed-replay-detector.d.ts +39 -0
- package/node_modules/@comis/agent/dist/executor/signed-replay-detector.js +72 -0
- package/node_modules/@comis/agent/package.json +1 -1
- package/node_modules/@comis/channels/package.json +1 -1
- package/node_modules/@comis/cli/dist/cli.js +0 -0
- package/node_modules/@comis/cli/dist/wizard/steps/12-finish.d.ts +4 -5
- package/node_modules/@comis/cli/dist/wizard/steps/12-finish.js +99 -40
- package/node_modules/@comis/cli/package.json +1 -1
- package/node_modules/@comis/core/dist/config/git-manager.js +10 -4
- package/node_modules/@comis/core/dist/config/index.d.ts +1 -0
- package/node_modules/@comis/core/dist/config/index.js +2 -0
- package/node_modules/@comis/core/dist/config/managed-sections.d.ts +67 -0
- package/node_modules/@comis/core/dist/config/managed-sections.js +124 -0
- package/node_modules/@comis/core/dist/config/schema-agent.d.ts +28 -10
- package/node_modules/@comis/core/dist/config/schema-agent.js +6 -0
- package/node_modules/@comis/core/dist/config/schema-gateway.d.ts +2 -2
- package/node_modules/@comis/core/dist/config/schema.d.ts +65 -64
- package/node_modules/@comis/core/dist/event-bus/events-messaging.d.ts +16 -0
- package/node_modules/@comis/core/dist/exports/config.d.ts +1 -1
- package/node_modules/@comis/core/dist/exports/config.js +1 -1
- package/node_modules/@comis/core/package.json +1 -1
- package/node_modules/@comis/daemon/bundled-skills/skill-creator/scripts/init-skill.py +0 -0
- package/node_modules/@comis/daemon/bundled-skills/skill-creator/scripts/validate-skill.py +0 -0
- package/node_modules/@comis/daemon/dist/daemon.js +0 -0
- package/node_modules/@comis/daemon/dist/rpc/config-handlers.js +20 -7
- package/node_modules/@comis/daemon/dist/rpc/session-handlers.js +27 -1
- package/node_modules/@comis/daemon/package.json +1 -1
- package/node_modules/@comis/gateway/package.json +1 -1
- package/node_modules/@comis/infra/package.json +1 -1
- package/node_modules/@comis/memory/package.json +1 -1
- package/node_modules/@comis/scheduler/package.json +1 -1
- package/node_modules/@comis/shared/package.json +1 -1
- package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +23 -8
- package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.d.ts +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +18 -14
- package/node_modules/@comis/skills/dist/builtin/platform/unified-session-tool.js +1 -1
- package/node_modules/@comis/skills/package.json +1 -1
- package/node_modules/@comis/web/package.json +1 -1
- package/package.json +24 -26
- package/node_modules/@comis/agent/dist/provider/response/strip-minimax-xml.d.ts +0 -9
- package/node_modules/@comis/agent/dist/provider/response/strip-minimax-xml.js +0 -17
- package/node_modules/@comis/agent/dist/provider/response/strip-model-tokens.d.ts +0 -13
- package/node_modules/@comis/agent/dist/provider/response/strip-model-tokens.js +0 -19
- package/node_modules/@comis/agent/dist/provider/response/strip-tool-text.d.ts +0 -11
- package/node_modules/@comis/agent/dist/provider/response/strip-tool-text.js +0 -32
- package/node_modules/@comis/agent/dist/safety/follow-through-detector.d.ts +0 -46
- package/node_modules/@comis/agent/dist/safety/follow-through-detector.js +0 -76
- package/node_modules/@comis/agent/dist/safety/post-compaction-safety.d.ts +0 -30
- package/node_modules/@comis/agent/dist/safety/post-compaction-safety.js +0 -51
- package/node_modules/@comis/agent/dist/safety/schema-normalizer.d.ts +0 -37
- package/node_modules/@comis/agent/dist/safety/schema-normalizer.js +0 -137
- package/node_modules/@comis/agent/dist/safety/schema-pruning.d.ts +0 -50
- package/node_modules/@comis/agent/dist/safety/schema-pruning.js +0 -112
- package/node_modules/@comis/agent/dist/safety/tool-image-sanitizer.d.ts +0 -43
- package/node_modules/@comis/agent/dist/safety/tool-image-sanitizer.js +0 -96
- package/node_modules/@comis/agent/dist/safety/tool-sanitizer.d.ts +0 -44
- package/node_modules/@comis/agent/dist/safety/tool-sanitizer.js +0 -94
- package/node_modules/@comis/channels/dist/shared/thinking-tag-filter.d.ts +0 -28
- package/node_modules/@comis/channels/dist/shared/thinking-tag-filter.js +0 -206
- package/node_modules/@comis/cli/dist/wizard/config-writer.d.ts +0 -25
- package/node_modules/@comis/cli/dist/wizard/config-writer.js +0 -144
- package/node_modules/@comis/cli/dist/wizard/flow-types.d.ts +0 -48
- package/node_modules/@comis/cli/dist/wizard/flow-types.js +0 -70
- package/node_modules/@comis/cli/dist/wizard/manual-flow.d.ts +0 -21
- package/node_modules/@comis/cli/dist/wizard/manual-flow.js +0 -345
- package/node_modules/@comis/cli/dist/wizard/quickstart-flow.d.ts +0 -21
- package/node_modules/@comis/cli/dist/wizard/quickstart-flow.js +0 -116
- package/node_modules/@comis/core/dist/config/schema-agent-model.d.ts +0 -135
- package/node_modules/@comis/core/dist/config/schema-agent-model.js +0 -114
- package/node_modules/@comis/core/dist/config/schema-agent-session.d.ts +0 -177
- package/node_modules/@comis/core/dist/config/schema-agent-session.js +0 -116
- package/node_modules/@comis/core/dist/config/schema-context-engine.d.ts +0 -92
- package/node_modules/@comis/core/dist/config/schema-context-engine.js +0 -92
- package/node_modules/@comis/core/dist/config/schema-context-guard.d.ts +0 -34
- package/node_modules/@comis/core/dist/config/schema-context-guard.js +0 -32
- package/node_modules/@comis/core/dist/config/schema-delivery-mirror.d.ts +0 -27
- package/node_modules/@comis/core/dist/config/schema-delivery-mirror.js +0 -26
- package/node_modules/@comis/core/dist/config/schema-delivery-queue.d.ts +0 -31
- package/node_modules/@comis/core/dist/config/schema-delivery-queue.js +0 -30
- package/node_modules/@comis/core/dist/config/schema-delivery-timing.d.ts +0 -41
- package/node_modules/@comis/core/dist/config/schema-delivery-timing.js +0 -31
- package/node_modules/@comis/core/dist/config/schema-monitoring.d.ts +0 -105
- package/node_modules/@comis/core/dist/config/schema-monitoring.js +0 -67
- package/node_modules/@comis/core/dist/ports/media-ports.d.ts +0 -278
- package/node_modules/@comis/core/dist/ports/media-ports.js +0 -1
- package/node_modules/@comis/core/dist/security/input-guard.d.ts +0 -46
- package/node_modules/@comis/core/dist/security/input-guard.js +0 -166
- package/node_modules/@comis/core/dist/security/scoped-secret-manager.d.ts +0 -38
- package/node_modules/@comis/core/dist/security/scoped-secret-manager.js +0 -94
- package/node_modules/@comis/daemon/dist/observability/delivery-context.d.ts +0 -37
- package/node_modules/@comis/daemon/dist/observability/delivery-context.js +0 -1
- package/node_modules/@comis/daemon/dist/observability/log-level-manager.d.ts +0 -23
- package/node_modules/@comis/daemon/dist/observability/log-level-manager.js +0 -34
- package/node_modules/@comis/daemon/dist/observability/log-transport.d.ts +0 -44
- package/node_modules/@comis/daemon/dist/observability/log-transport.js +0 -74
- package/node_modules/@comis/daemon/dist/observability/obs-write-buffer.d.ts +0 -53
- package/node_modules/@comis/daemon/dist/observability/obs-write-buffer.js +0 -68
- package/node_modules/@comis/daemon/dist/observability/types.d.ts +0 -6
- package/node_modules/@comis/daemon/dist/observability/types.js +0 -1
- package/node_modules/@comis/daemon/dist/wiring/seed-bundled-skills.d.ts +0 -41
- package/node_modules/@comis/daemon/dist/wiring/seed-bundled-skills.js +0 -84
- package/node_modules/@comis/daemon/dist/wiring/setup-delivery-mirror.d.ts +0 -24
- package/node_modules/@comis/daemon/dist/wiring/setup-delivery-mirror.js +0 -88
- package/node_modules/@comis/daemon/dist/wiring/setup-delivery-queue.d.ts +0 -31
- package/node_modules/@comis/daemon/dist/wiring/setup-delivery-queue.js +0 -132
- package/node_modules/@comis/daemon/dist/wiring/setup-monitoring.d.ts +0 -38
- package/node_modules/@comis/daemon/dist/wiring/setup-monitoring.js +0 -100
- package/node_modules/@comis/daemon/dist/wiring/setup-rpc-bridge.d.ts +0 -34
- package/node_modules/@comis/daemon/dist/wiring/setup-rpc-bridge.js +0 -52
- package/node_modules/@comis/daemon/dist/wiring/setup-task-extraction.d.ts +0 -41
- package/node_modules/@comis/daemon/dist/wiring/setup-task-extraction.js +0 -86
- package/node_modules/@comis/memory/dist/embedding-cache.d.ts +0 -36
- package/node_modules/@comis/memory/dist/embedding-cache.js +0 -94
- package/node_modules/@comis/skills/dist/bridge/tool-output-schemas.d.ts +0 -17
- package/node_modules/@comis/skills/dist/bridge/tool-output-schemas.js +0 -125
- package/node_modules/@comis/skills/dist/bridge/tool-parallelism-metadata.d.ts +0 -14
- package/node_modules/@comis/skills/dist/bridge/tool-parallelism-metadata.js +0 -92
- package/node_modules/@comis/skills/dist/bridge/tool-result-caps.d.ts +0 -14
- package/node_modules/@comis/skills/dist/bridge/tool-result-caps.js +0 -36
- package/node_modules/@comis/skills/dist/bridge/tool-search-hints.d.ts +0 -15
- package/node_modules/@comis/skills/dist/bridge/tool-search-hints.js +0 -68
- package/node_modules/@comis/skills/dist/bridge/tool-validators.d.ts +0 -11
- package/node_modules/@comis/skills/dist/bridge/tool-validators.js +0 -105
- package/node_modules/@comis/skills/dist/builtin/file/find-sort-wrapper.d.ts +0 -22
- package/node_modules/@comis/skills/dist/builtin/file/find-sort-wrapper.js +0 -95
- package/node_modules/@comis/skills/dist/builtin/file/grep-output-mode-wrapper.d.ts +0 -24
- package/node_modules/@comis/skills/dist/builtin/file/grep-output-mode-wrapper.js +0 -167
- package/node_modules/@comis/skills/dist/builtin/task-plan-tool.d.ts +0 -25
- package/node_modules/@comis/skills/dist/builtin/task-plan-tool.js +0 -67
- package/node_modules/@comis/skills/dist/integrations/mcp-tool-bridge.d.ts +0 -75
- package/node_modules/@comis/skills/dist/integrations/mcp-tool-bridge.js +0 -235
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type ComisLogger } from "@comis/infra";
|
|
2
|
-
/**
|
|
3
|
-
* Log level manager: per-module child loggers with runtime level control.
|
|
4
|
-
*
|
|
5
|
-
* Modules obtain their logger via getLogger(module), which returns a cached
|
|
6
|
-
* Pino child logger. Levels can be changed at runtime per-module or globally
|
|
7
|
-
* via the daemon.setLogLevel RPC (OBS-04).
|
|
8
|
-
*/
|
|
9
|
-
export interface LogLevelManager {
|
|
10
|
-
/** Get or create a child logger for a named module. Cached on first call. */
|
|
11
|
-
getLogger(module: string): ComisLogger;
|
|
12
|
-
/** Change the log level for a specific module's logger. */
|
|
13
|
-
setLevel(module: string, level: string): void;
|
|
14
|
-
/** Change the root logger's level (affects all modules that haven't been individually overridden). */
|
|
15
|
-
setGlobalLevel(level: string): void;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Create a log level manager that maintains a registry of per-module child loggers.
|
|
19
|
-
*
|
|
20
|
-
* @param rootLogger - The root Pino logger from which child loggers are derived
|
|
21
|
-
* @returns A LogLevelManager instance
|
|
22
|
-
*/
|
|
23
|
-
export declare function createLogLevelManager(rootLogger: ComisLogger): LogLevelManager;
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { isValidLogLevel } from "@comis/infra";
|
|
2
|
-
/**
|
|
3
|
-
* Create a log level manager that maintains a registry of per-module child loggers.
|
|
4
|
-
*
|
|
5
|
-
* @param rootLogger - The root Pino logger from which child loggers are derived
|
|
6
|
-
* @returns A LogLevelManager instance
|
|
7
|
-
*/
|
|
8
|
-
export function createLogLevelManager(rootLogger) {
|
|
9
|
-
const loggers = new Map();
|
|
10
|
-
const manager = {
|
|
11
|
-
getLogger(module) {
|
|
12
|
-
let logger = loggers.get(module);
|
|
13
|
-
if (!logger) {
|
|
14
|
-
logger = rootLogger.child({ module });
|
|
15
|
-
loggers.set(module, logger);
|
|
16
|
-
}
|
|
17
|
-
return logger;
|
|
18
|
-
},
|
|
19
|
-
setLevel(module, level) {
|
|
20
|
-
if (!isValidLogLevel(level))
|
|
21
|
-
return; // CRED-05: silently reject invalid levels
|
|
22
|
-
const logger = loggers.get(module);
|
|
23
|
-
if (logger) {
|
|
24
|
-
logger.level = level;
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
setGlobalLevel(level) {
|
|
28
|
-
if (!isValidLogLevel(level))
|
|
29
|
-
return; // CRED-05: silently reject invalid levels
|
|
30
|
-
rootLogger.level = level;
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
return manager;
|
|
34
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Log transport factory: constructs pino multi-target transport config
|
|
3
|
-
* for simultaneous file rotation (pino-roll) and stdout output.
|
|
4
|
-
*
|
|
5
|
-
* INFRA-02: File rotation transport.
|
|
6
|
-
* INFRA-03: Dual file + stdout output.
|
|
7
|
-
* INFRA-04: removeOtherLogFiles cleanup.
|
|
8
|
-
*
|
|
9
|
-
* @module
|
|
10
|
-
*/
|
|
11
|
-
import type { LoggingConfig } from "@comis/core";
|
|
12
|
-
import type pino from "pino";
|
|
13
|
-
/**
|
|
14
|
-
* Expand leading tilde to os.homedir().
|
|
15
|
-
* pino-roll does NOT expand tildes, so this must be called before
|
|
16
|
-
* passing filePath to the transport.
|
|
17
|
-
*/
|
|
18
|
-
export declare function expandTilde(filePath: string): string;
|
|
19
|
-
/**
|
|
20
|
-
* Detect whether the process is running under pm2.
|
|
21
|
-
*
|
|
22
|
-
* pm2 sets the `PM2_HOME` environment variable for all managed processes.
|
|
23
|
-
* When running under pm2, stdout is already captured to pm2's own log files
|
|
24
|
-
* (`~/.pm2/logs/`), so the pino-roll file transport would be a byte-for-byte
|
|
25
|
-
* duplicate.
|
|
26
|
-
*/
|
|
27
|
-
export declare function isPm2Managed(): boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Create a pino multi-target transport config from LoggingConfig.
|
|
30
|
-
*
|
|
31
|
-
* LI-1: PM2-aware transport selection.
|
|
32
|
-
* - File transport (pino-roll): always active -- canonical log location.
|
|
33
|
-
* - Stdout: skipped under pm2 (PM2_HOME set) to avoid byte-for-byte
|
|
34
|
-
* duplication with pm2's own log capture in ~/.pm2/logs/.
|
|
35
|
-
*
|
|
36
|
-
* Note: node-llama-cpp native module warnings write directly to stderr and
|
|
37
|
-
* cannot be captured by Pino transports. This is a known limitation.
|
|
38
|
-
*
|
|
39
|
-
* @param config - Logging config from DaemonConfigSchema.logging
|
|
40
|
-
* @param level - Log level to apply to each target (Pino multi-transport
|
|
41
|
-
* targets default to "info" unless explicitly set)
|
|
42
|
-
* @returns Transport config to pass as LoggerOptions.transport
|
|
43
|
-
*/
|
|
44
|
-
export declare function createFileTransport(config: LoggingConfig, level?: string): pino.TransportMultiOptions;
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Log transport factory: constructs pino multi-target transport config
|
|
3
|
-
* for simultaneous file rotation (pino-roll) and stdout output.
|
|
4
|
-
*
|
|
5
|
-
* INFRA-02: File rotation transport.
|
|
6
|
-
* INFRA-03: Dual file + stdout output.
|
|
7
|
-
* INFRA-04: removeOtherLogFiles cleanup.
|
|
8
|
-
*
|
|
9
|
-
* @module
|
|
10
|
-
*/
|
|
11
|
-
import os from "node:os";
|
|
12
|
-
/**
|
|
13
|
-
* Expand leading tilde to os.homedir().
|
|
14
|
-
* pino-roll does NOT expand tildes, so this must be called before
|
|
15
|
-
* passing filePath to the transport.
|
|
16
|
-
*/
|
|
17
|
-
export function expandTilde(filePath) {
|
|
18
|
-
return filePath.replace(/^~(?=\/|$)/, os.homedir());
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Detect whether the process is running under pm2.
|
|
22
|
-
*
|
|
23
|
-
* pm2 sets the `PM2_HOME` environment variable for all managed processes.
|
|
24
|
-
* When running under pm2, stdout is already captured to pm2's own log files
|
|
25
|
-
* (`~/.pm2/logs/`), so the pino-roll file transport would be a byte-for-byte
|
|
26
|
-
* duplicate.
|
|
27
|
-
*/
|
|
28
|
-
export function isPm2Managed() {
|
|
29
|
-
return typeof process.env.PM2_HOME === "string" && process.env.PM2_HOME.length > 0;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Create a pino multi-target transport config from LoggingConfig.
|
|
33
|
-
*
|
|
34
|
-
* LI-1: PM2-aware transport selection.
|
|
35
|
-
* - File transport (pino-roll): always active -- canonical log location.
|
|
36
|
-
* - Stdout: skipped under pm2 (PM2_HOME set) to avoid byte-for-byte
|
|
37
|
-
* duplication with pm2's own log capture in ~/.pm2/logs/.
|
|
38
|
-
*
|
|
39
|
-
* Note: node-llama-cpp native module warnings write directly to stderr and
|
|
40
|
-
* cannot be captured by Pino transports. This is a known limitation.
|
|
41
|
-
*
|
|
42
|
-
* @param config - Logging config from DaemonConfigSchema.logging
|
|
43
|
-
* @param level - Log level to apply to each target (Pino multi-transport
|
|
44
|
-
* targets default to "info" unless explicitly set)
|
|
45
|
-
* @returns Transport config to pass as LoggerOptions.transport
|
|
46
|
-
*/
|
|
47
|
-
export function createFileTransport(config, level) {
|
|
48
|
-
const expandedPath = expandTilde(config.filePath);
|
|
49
|
-
const pm2Detected = isPm2Managed();
|
|
50
|
-
const targets = [];
|
|
51
|
-
// File transport: always active -- ~/.comis/logs/ is the canonical log location
|
|
52
|
-
targets.push({
|
|
53
|
-
target: "pino-roll",
|
|
54
|
-
options: {
|
|
55
|
-
file: expandedPath,
|
|
56
|
-
size: config.maxSize,
|
|
57
|
-
mkdir: true,
|
|
58
|
-
limit: {
|
|
59
|
-
count: config.maxFiles,
|
|
60
|
-
removeOtherLogFiles: true,
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
...(level ? { level } : {}),
|
|
64
|
-
});
|
|
65
|
-
// Stdout: skip under pm2 (pm2 captures stdout to ~/.pm2/logs/, so it would be a duplicate)
|
|
66
|
-
if (!pm2Detected) {
|
|
67
|
-
targets.push({
|
|
68
|
-
target: "pino/file",
|
|
69
|
-
options: { destination: 1 }, // stdout
|
|
70
|
-
...(level ? { level } : {}),
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
return { targets };
|
|
74
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic batched write buffer for observability persistence.
|
|
3
|
-
*
|
|
4
|
-
* Sits between event bus listeners and ObservabilityStore: listeners push items
|
|
5
|
-
* into the buffer; the buffer flushes batches to SQLite periodically or when
|
|
6
|
-
* the buffer reaches its size threshold.
|
|
7
|
-
*
|
|
8
|
-
* Design:
|
|
9
|
-
* - Plain array (not ring buffer) per research recommendation
|
|
10
|
-
* - Dual trigger: size threshold (default 50) OR timer interval (default 500ms)
|
|
11
|
-
* - Timer uses unref() so it does not prevent Node.js process exit
|
|
12
|
-
* - drain() provides synchronous final flush for clean shutdown
|
|
13
|
-
* - flushFn is synchronous (better-sqlite3 db.transaction() is sync)
|
|
14
|
-
*
|
|
15
|
-
* @module obs-write-buffer
|
|
16
|
-
*/
|
|
17
|
-
/** Public interface for the write buffer. */
|
|
18
|
-
export interface ObsWriteBuffer<T> {
|
|
19
|
-
/** Add an item to the buffer. Triggers flush if buffer hits maxSize. */
|
|
20
|
-
push(item: T): void;
|
|
21
|
-
/** Flush current buffer contents to the flush callback. No-op if empty. */
|
|
22
|
-
flush(): void;
|
|
23
|
-
/** Synchronous final flush for shutdown: flushes remaining items and clears the interval timer. */
|
|
24
|
-
drain(): void;
|
|
25
|
-
/** Number of items currently buffered. */
|
|
26
|
-
readonly pending: number;
|
|
27
|
-
}
|
|
28
|
-
/** Options for creating a write buffer. */
|
|
29
|
-
export interface ObsWriteBufferOptions<T> {
|
|
30
|
-
/** Callback invoked with a batch of items when flushing. Must be synchronous (better-sqlite3 is sync). */
|
|
31
|
-
flushFn: (items: T[]) => void;
|
|
32
|
-
/** Maximum buffer size before triggering a flush. Default: 50. */
|
|
33
|
-
maxSize?: number;
|
|
34
|
-
/** Interval in ms between automatic flushes. Default: 500. */
|
|
35
|
-
intervalMs?: number;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Create a generic batched write buffer.
|
|
39
|
-
*
|
|
40
|
-
* Usage:
|
|
41
|
-
* ```ts
|
|
42
|
-
* const buf = createObsWriteBuffer<TokenUsageRow>({
|
|
43
|
-
* flushFn: (items) => store.insertTokenUsageBatch(items),
|
|
44
|
-
* maxSize: 50,
|
|
45
|
-
* intervalMs: 500,
|
|
46
|
-
* });
|
|
47
|
-
*
|
|
48
|
-
* eventBus.on("token:usage", (entry) => buf.push(toRow(entry)));
|
|
49
|
-
* // On shutdown:
|
|
50
|
-
* buf.drain();
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
export declare function createObsWriteBuffer<T>(opts: ObsWriteBufferOptions<T>): ObsWriteBuffer<T>;
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generic batched write buffer for observability persistence.
|
|
3
|
-
*
|
|
4
|
-
* Sits between event bus listeners and ObservabilityStore: listeners push items
|
|
5
|
-
* into the buffer; the buffer flushes batches to SQLite periodically or when
|
|
6
|
-
* the buffer reaches its size threshold.
|
|
7
|
-
*
|
|
8
|
-
* Design:
|
|
9
|
-
* - Plain array (not ring buffer) per research recommendation
|
|
10
|
-
* - Dual trigger: size threshold (default 50) OR timer interval (default 500ms)
|
|
11
|
-
* - Timer uses unref() so it does not prevent Node.js process exit
|
|
12
|
-
* - drain() provides synchronous final flush for clean shutdown
|
|
13
|
-
* - flushFn is synchronous (better-sqlite3 db.transaction() is sync)
|
|
14
|
-
*
|
|
15
|
-
* @module obs-write-buffer
|
|
16
|
-
*/
|
|
17
|
-
/**
|
|
18
|
-
* Create a generic batched write buffer.
|
|
19
|
-
*
|
|
20
|
-
* Usage:
|
|
21
|
-
* ```ts
|
|
22
|
-
* const buf = createObsWriteBuffer<TokenUsageRow>({
|
|
23
|
-
* flushFn: (items) => store.insertTokenUsageBatch(items),
|
|
24
|
-
* maxSize: 50,
|
|
25
|
-
* intervalMs: 500,
|
|
26
|
-
* });
|
|
27
|
-
*
|
|
28
|
-
* eventBus.on("token:usage", (entry) => buf.push(toRow(entry)));
|
|
29
|
-
* // On shutdown:
|
|
30
|
-
* buf.drain();
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export function createObsWriteBuffer(opts) {
|
|
34
|
-
const { flushFn, maxSize = 50, intervalMs = 500 } = opts;
|
|
35
|
-
let buffer = [];
|
|
36
|
-
// Start periodic flush timer. unref() ensures it does not keep the process alive.
|
|
37
|
-
const timer = setInterval(() => {
|
|
38
|
-
flush();
|
|
39
|
-
}, intervalMs);
|
|
40
|
-
timer.unref();
|
|
41
|
-
function flush() {
|
|
42
|
-
if (buffer.length === 0)
|
|
43
|
-
return;
|
|
44
|
-
// Swap-before-call: if flushFn throws, the batch is in the local variable,
|
|
45
|
-
// not lost back in the buffer. The caller of flushFn can decide recovery.
|
|
46
|
-
const batch = buffer;
|
|
47
|
-
buffer = [];
|
|
48
|
-
flushFn(batch);
|
|
49
|
-
}
|
|
50
|
-
function push(item) {
|
|
51
|
-
buffer.push(item);
|
|
52
|
-
if (buffer.length >= maxSize) {
|
|
53
|
-
flush();
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
function drain() {
|
|
57
|
-
clearInterval(timer);
|
|
58
|
-
flush();
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
push,
|
|
62
|
-
flush,
|
|
63
|
-
drain,
|
|
64
|
-
get pending() {
|
|
65
|
-
return buffer.length;
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Idempotent seeding of bundled skills from the repo's skills/ directory
|
|
3
|
-
* into the user data directory (~/.comis/skills/).
|
|
4
|
-
*
|
|
5
|
-
* On first startup, copies each skill directory that does not already exist
|
|
6
|
-
* in the target. Existing user skills are never overwritten.
|
|
7
|
-
*
|
|
8
|
-
* @module
|
|
9
|
-
*/
|
|
10
|
-
/** Minimal Pino-compatible logger for seeding diagnostics. */
|
|
11
|
-
interface SeedLogger {
|
|
12
|
-
info(obj: Record<string, unknown>, msg: string): void;
|
|
13
|
-
debug(obj: Record<string, unknown>, msg: string): void;
|
|
14
|
-
}
|
|
15
|
-
/** Result of a seeding operation. */
|
|
16
|
-
export interface SeedResult {
|
|
17
|
-
/** Skill directory names that were newly copied into targetDir. */
|
|
18
|
-
seeded: string[];
|
|
19
|
-
/** Skill directory names that already existed in targetDir and were skipped. */
|
|
20
|
-
skipped: string[];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Seed bundled skills from sourceDir into targetDir (idempotent).
|
|
24
|
-
*
|
|
25
|
-
* For each subdirectory in sourceDir, checks whether a same-named directory
|
|
26
|
-
* already exists in targetDir. If not, copies the entire directory tree
|
|
27
|
-
* recursively. Existing skill directories are never overwritten.
|
|
28
|
-
*
|
|
29
|
-
* @param opts.sourceDir - Absolute path to the repo's skills/ directory.
|
|
30
|
-
* If omitted, resolves from __dirname (../../../../skills).
|
|
31
|
-
* @param opts.targetDir - Absolute path to the user data skills directory
|
|
32
|
-
* (e.g., ~/.comis/skills/).
|
|
33
|
-
* @param opts.logger - Optional structured logger for diagnostics.
|
|
34
|
-
* @returns SeedResult with seeded and skipped skill names.
|
|
35
|
-
*/
|
|
36
|
-
export declare function seedBundledSkills(opts: {
|
|
37
|
-
sourceDir?: string;
|
|
38
|
-
targetDir: string;
|
|
39
|
-
logger?: SeedLogger;
|
|
40
|
-
}): SeedResult;
|
|
41
|
-
export {};
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Idempotent seeding of bundled skills from the repo's skills/ directory
|
|
3
|
-
* into the user data directory (~/.comis/skills/).
|
|
4
|
-
*
|
|
5
|
-
* On first startup, copies each skill directory that does not already exist
|
|
6
|
-
* in the target. Existing user skills are never overwritten.
|
|
7
|
-
*
|
|
8
|
-
* @module
|
|
9
|
-
*/
|
|
10
|
-
import { existsSync, mkdirSync, readdirSync, cpSync, statSync } from "node:fs";
|
|
11
|
-
import { resolve } from "node:path";
|
|
12
|
-
import { fileURLToPath } from "node:url";
|
|
13
|
-
/**
|
|
14
|
-
* Seed bundled skills from sourceDir into targetDir (idempotent).
|
|
15
|
-
*
|
|
16
|
-
* For each subdirectory in sourceDir, checks whether a same-named directory
|
|
17
|
-
* already exists in targetDir. If not, copies the entire directory tree
|
|
18
|
-
* recursively. Existing skill directories are never overwritten.
|
|
19
|
-
*
|
|
20
|
-
* @param opts.sourceDir - Absolute path to the repo's skills/ directory.
|
|
21
|
-
* If omitted, resolves from __dirname (../../../../skills).
|
|
22
|
-
* @param opts.targetDir - Absolute path to the user data skills directory
|
|
23
|
-
* (e.g., ~/.comis/skills/).
|
|
24
|
-
* @param opts.logger - Optional structured logger for diagnostics.
|
|
25
|
-
* @returns SeedResult with seeded and skipped skill names.
|
|
26
|
-
*/
|
|
27
|
-
export function seedBundledSkills(opts) {
|
|
28
|
-
const seeded = [];
|
|
29
|
-
const skipped = [];
|
|
30
|
-
// Resolve source directory: either provided or derived from module location
|
|
31
|
-
const sourceDir = opts.sourceDir ?? resolveDefaultSourceDir();
|
|
32
|
-
// Handle missing source directory gracefully
|
|
33
|
-
if (!existsSync(sourceDir)) {
|
|
34
|
-
opts.logger?.debug({ sourceDir }, "Bundled skills source directory not found, skipping seed");
|
|
35
|
-
return { seeded, skipped };
|
|
36
|
-
}
|
|
37
|
-
// Ensure target directory exists
|
|
38
|
-
mkdirSync(opts.targetDir, { recursive: true });
|
|
39
|
-
// Enumerate skill directories in source
|
|
40
|
-
let entries;
|
|
41
|
-
try {
|
|
42
|
-
entries = readdirSync(sourceDir);
|
|
43
|
-
}
|
|
44
|
-
catch {
|
|
45
|
-
return { seeded, skipped };
|
|
46
|
-
}
|
|
47
|
-
for (const entry of entries) {
|
|
48
|
-
const srcPath = resolve(sourceDir, entry);
|
|
49
|
-
// Only process directories (skip files like README.md)
|
|
50
|
-
try {
|
|
51
|
-
if (!statSync(srcPath).isDirectory())
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
const destPath = resolve(opts.targetDir, entry);
|
|
58
|
-
if (existsSync(destPath)) {
|
|
59
|
-
skipped.push(entry);
|
|
60
|
-
opts.logger?.debug({ skill: entry }, "Bundled skill already exists in target, skipping");
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
cpSync(srcPath, destPath, { recursive: true });
|
|
64
|
-
seeded.push(entry);
|
|
65
|
-
opts.logger?.debug({ skill: entry }, "Bundled skill seeded into target");
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
if (seeded.length > 0 || skipped.length > 0) {
|
|
69
|
-
opts.logger?.info({ seeded: seeded.length, skipped: skipped.length }, "Bundled skills seeded");
|
|
70
|
-
}
|
|
71
|
-
return { seeded, skipped };
|
|
72
|
-
}
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
// Internal helpers
|
|
75
|
-
// ---------------------------------------------------------------------------
|
|
76
|
-
/**
|
|
77
|
-
* Resolve the default bundled skills source directory relative to this module.
|
|
78
|
-
* From packages/daemon/dist/wiring/ -> repo root skills/
|
|
79
|
-
*/
|
|
80
|
-
function resolveDefaultSourceDir() {
|
|
81
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
82
|
-
const __dirname = resolve(__filename, "..");
|
|
83
|
-
return resolve(__dirname, "../../../../skills");
|
|
84
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Delivery mirror wiring: adapter creation, hook-based recording, periodic prune.
|
|
3
|
-
*
|
|
4
|
-
* Phase 502: Session Mirroring.
|
|
5
|
-
* @module
|
|
6
|
-
*/
|
|
7
|
-
import type { AppConfig, DeliveryMirrorPort } from "@comis/core";
|
|
8
|
-
import type { ComisLogger } from "@comis/infra";
|
|
9
|
-
import type { PluginRegistry } from "@comis/core";
|
|
10
|
-
export interface DeliveryMirrorResult {
|
|
11
|
-
/** The delivery mirror adapter (real or no-op), available immediately. */
|
|
12
|
-
deliveryMirror: DeliveryMirrorPort;
|
|
13
|
-
/** Starts the periodic prune timer. Call AFTER setupChannels. */
|
|
14
|
-
startPrune: () => void;
|
|
15
|
-
/** Clears the prune interval timer (call on shutdown). */
|
|
16
|
-
shutdown: () => void;
|
|
17
|
-
}
|
|
18
|
-
export declare function setupDeliveryMirror(deps: {
|
|
19
|
-
/** Raw better-sqlite3 database handle (typed as unknown to avoid cross-package type dep). */
|
|
20
|
-
db: unknown;
|
|
21
|
-
config: AppConfig;
|
|
22
|
-
pluginRegistry: PluginRegistry;
|
|
23
|
-
logger: ComisLogger;
|
|
24
|
-
}): Promise<DeliveryMirrorResult>;
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Delivery mirror wiring: adapter creation, hook-based recording, periodic prune.
|
|
3
|
-
*
|
|
4
|
-
* Phase 502: Session Mirroring.
|
|
5
|
-
* @module
|
|
6
|
-
*/
|
|
7
|
-
import { createNoOpDeliveryMirror } from "@comis/core";
|
|
8
|
-
import { createSqliteDeliveryMirror } from "@comis/memory";
|
|
9
|
-
import { ok } from "@comis/shared";
|
|
10
|
-
import { createHash } from "node:crypto";
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
// Idempotency key computation
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
/**
|
|
15
|
-
* Compute an idempotency key for a mirror entry.
|
|
16
|
-
* Uses session key + text hash + 1-second time bucket to deduplicate
|
|
17
|
-
* repeated deliveries of the same text within the same second.
|
|
18
|
-
*/
|
|
19
|
-
function computeIdempotencyKey(sessionKey, text, timestamp) {
|
|
20
|
-
const textHash = createHash("sha256").update(text).digest("hex").slice(0, 16);
|
|
21
|
-
const bucket = Math.floor(timestamp / 1000);
|
|
22
|
-
return `${sessionKey}:${textHash}:${bucket}`;
|
|
23
|
-
}
|
|
24
|
-
// ---------------------------------------------------------------------------
|
|
25
|
-
// Setup function
|
|
26
|
-
// ---------------------------------------------------------------------------
|
|
27
|
-
export async function setupDeliveryMirror(deps) {
|
|
28
|
-
const { db, config, pluginRegistry, logger } = deps;
|
|
29
|
-
const mirrorConfig = config.deliveryMirror;
|
|
30
|
-
// 1. No-op when disabled
|
|
31
|
-
if (!mirrorConfig?.enabled) {
|
|
32
|
-
logger.debug("Delivery mirror disabled by config");
|
|
33
|
-
return {
|
|
34
|
-
deliveryMirror: createNoOpDeliveryMirror(),
|
|
35
|
-
startPrune: () => { },
|
|
36
|
-
shutdown: () => { },
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- db is better-sqlite3 Database; typed as unknown to avoid cross-package type dependency
|
|
40
|
-
const deliveryMirror = createSqliteDeliveryMirror(db);
|
|
41
|
-
logger.info({ retentionMs: mirrorConfig.retentionMs, maxEntriesPerInjection: mirrorConfig.maxEntriesPerInjection, maxCharsPerInjection: mirrorConfig.maxCharsPerInjection }, "Delivery mirror enabled");
|
|
42
|
-
// 2. Hook registration: record delivered text via after_delivery hook
|
|
43
|
-
pluginRegistry.register({
|
|
44
|
-
id: "comis:delivery-mirror",
|
|
45
|
-
name: "Delivery Mirror",
|
|
46
|
-
version: "1.0.0",
|
|
47
|
-
register(api) {
|
|
48
|
-
api.registerHook("after_delivery", async (event, ctx) => {
|
|
49
|
-
if (!ctx.sessionKey)
|
|
50
|
-
return; // No session context -- skip (Pitfall 1)
|
|
51
|
-
const now = Date.now();
|
|
52
|
-
const idempotencyKey = computeIdempotencyKey(ctx.sessionKey, event.text, now);
|
|
53
|
-
const result = await deliveryMirror.record({
|
|
54
|
-
sessionKey: ctx.sessionKey,
|
|
55
|
-
text: event.text,
|
|
56
|
-
mediaUrls: [], // Phase 502 baseline -- HookAfterDeliveryEvent has no mediaUrls field; media URL mirroring deferred
|
|
57
|
-
channelType: event.channelType,
|
|
58
|
-
channelId: event.channelId,
|
|
59
|
-
origin: event.origin,
|
|
60
|
-
idempotencyKey,
|
|
61
|
-
});
|
|
62
|
-
if (result.ok) {
|
|
63
|
-
logger.debug({ sessionKey: ctx.sessionKey, channelType: event.channelType, idempotencyKey }, "Mirror entry recorded");
|
|
64
|
-
}
|
|
65
|
-
// Recording failures are silently tolerated (fire-and-forget hook)
|
|
66
|
-
});
|
|
67
|
-
return ok(undefined);
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
// 3. Prune timer
|
|
71
|
-
let pruneInterval;
|
|
72
|
-
const startPrune = () => {
|
|
73
|
-
pruneInterval = setInterval(async () => {
|
|
74
|
-
const result = await deliveryMirror.pruneOld(mirrorConfig.retentionMs);
|
|
75
|
-
if (result.ok && result.value > 0) {
|
|
76
|
-
logger.debug({ pruned: result.value }, "Delivery mirror pruned");
|
|
77
|
-
}
|
|
78
|
-
}, mirrorConfig.pruneIntervalMs);
|
|
79
|
-
pruneInterval.unref();
|
|
80
|
-
};
|
|
81
|
-
const shutdown = () => {
|
|
82
|
-
if (pruneInterval) {
|
|
83
|
-
clearInterval(pruneInterval);
|
|
84
|
-
pruneInterval = undefined;
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
return { deliveryMirror, startPrune, shutdown };
|
|
88
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Delivery queue wiring: adapter creation, startup drain, periodic prune.
|
|
3
|
-
*
|
|
4
|
-
* Two-phase lifecycle resolves the circular dependency between the queue and
|
|
5
|
-
* channel adapters:
|
|
6
|
-
* 1. setupDeliveryQueue() creates the adapter immediately (before setupChannels).
|
|
7
|
-
* 2. drainAndStartPrune() runs drain + starts prune timer AFTER setupChannels
|
|
8
|
-
* populates channelAdapters.
|
|
9
|
-
*
|
|
10
|
-
* Phase 499: Crash-Safe Delivery Queue.
|
|
11
|
-
* @module
|
|
12
|
-
*/
|
|
13
|
-
import type { AppConfig, TypedEventBus, DeliveryQueuePort } from "@comis/core";
|
|
14
|
-
import { type DeliveryAdapter } from "@comis/channels";
|
|
15
|
-
import type { ComisLogger } from "@comis/infra";
|
|
16
|
-
export interface DeliveryQueueResult {
|
|
17
|
-
/** The delivery queue adapter (real or no-op), available immediately. */
|
|
18
|
-
deliveryQueue: DeliveryQueuePort;
|
|
19
|
-
/** Runs startup drain then starts periodic prune timer. Call AFTER setupChannels. */
|
|
20
|
-
drainAndStartPrune: () => Promise<void>;
|
|
21
|
-
/** Clears the prune interval timer (call on shutdown). */
|
|
22
|
-
shutdown: () => void;
|
|
23
|
-
}
|
|
24
|
-
export declare function setupDeliveryQueue(deps: {
|
|
25
|
-
/** Raw better-sqlite3 database handle (typed as unknown to avoid cross-package type dep). */
|
|
26
|
-
db: unknown;
|
|
27
|
-
config: AppConfig;
|
|
28
|
-
eventBus: TypedEventBus;
|
|
29
|
-
logger: ComisLogger;
|
|
30
|
-
channelAdapters: Map<string, DeliveryAdapter>;
|
|
31
|
-
}): Promise<DeliveryQueueResult>;
|