@adhdev/daemon-core 0.9.76-rc.64 → 0.9.76-rc.66
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.d.ts +1 -1
- package/dist/index.js +38 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +40 -5
- package/dist/index.mjs.map +1 -1
- package/dist/repo-mesh-types.d.ts +7 -0
- package/package.json +1 -1
- package/src/chat/subscription-updates.ts +2 -2
- package/src/config/mesh-config.ts +4 -0
- package/src/index.ts +4 -0
- package/src/mesh/mesh-events.ts +13 -2
- package/src/providers/cli-provider-instance.ts +31 -1
- package/src/repo-mesh-types.ts +8 -0
|
@@ -41,6 +41,7 @@ export interface RepoMeshNode {
|
|
|
41
41
|
}
|
|
42
42
|
export type RepoMeshNodeHealth = 'online' | 'offline' | 'degraded' | 'dirty' | 'wrong_branch' | 'unknown';
|
|
43
43
|
export type RepoMeshSessionCleanupMode = 'preserve' | 'stop' | 'delete_stopped' | 'stop_and_delete';
|
|
44
|
+
export type RepoMeshSpawnedSessionVisibility = 'visible' | 'hidden';
|
|
44
45
|
export interface RepoMeshPolicy {
|
|
45
46
|
requirePreTaskCheckpoint: boolean;
|
|
46
47
|
requirePostTaskCheckpoint: boolean;
|
|
@@ -49,6 +50,12 @@ export interface RepoMeshPolicy {
|
|
|
49
50
|
dirtyWorkspaceBehavior: 'block' | 'warn' | 'checkpoint_then_continue';
|
|
50
51
|
maxParallelTasks: number;
|
|
51
52
|
allowedProviders?: string[];
|
|
53
|
+
/**
|
|
54
|
+
* Whether sessions spawned by mesh/coordinator policy should auto-open as visible
|
|
55
|
+
* dashboard tabs or start hidden. Defaults to 'visible' to preserve existing
|
|
56
|
+
* watch-the-agents behavior; hidden sessions remain discoverable and manually openable.
|
|
57
|
+
*/
|
|
58
|
+
spawnedSessionVisibility?: RepoMeshSpawnedSessionVisibility;
|
|
52
59
|
/**
|
|
53
60
|
* What to do with delegated session-host records for a node when it is removed.
|
|
54
61
|
* Defaults to 'preserve' so completed work can be reviewed later and live
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
buildSessionModalDeliverySignature,
|
|
9
9
|
} from './chat-signatures.js'
|
|
10
10
|
import { normalizeManagedStatus } from '../status/normalize.js'
|
|
11
|
-
import {
|
|
11
|
+
import { normalizeChatMessages } from '../providers/chat-message-normalization.js'
|
|
12
12
|
|
|
13
13
|
export interface ChatTailSubscriptionCursor {
|
|
14
14
|
tailLimit: number
|
|
@@ -103,7 +103,7 @@ export function prepareSessionChatTailUpdate(
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
const fullMessages = normalizeChatMessages(Array.isArray(result.messages) ? result.messages as any[] : [])
|
|
106
|
-
const messages =
|
|
106
|
+
const messages = fullMessages
|
|
107
107
|
const title = typeof result.title === 'string' ? result.title : undefined
|
|
108
108
|
const activeModal = normalizeChatTailActiveModal(result.activeModal)
|
|
109
109
|
const status = typeof result.status === 'string' ? result.status : 'idle'
|
|
@@ -75,6 +75,7 @@ export function normalizeRepoIdentity(remoteUrl: string): string {
|
|
|
75
75
|
// ─── CRUD Operations ────────────────────────────
|
|
76
76
|
|
|
77
77
|
const SESSION_CLEANUP_MODES = new Set(['preserve', 'stop', 'delete_stopped', 'stop_and_delete']);
|
|
78
|
+
const SPAWNED_SESSION_VISIBILITY_MODES = new Set(['visible', 'hidden']);
|
|
78
79
|
|
|
79
80
|
function mergeMeshPolicy(base: RepoMeshPolicy | undefined, patch: Partial<RepoMeshPolicy> | undefined): RepoMeshPolicy {
|
|
80
81
|
const policy: RepoMeshPolicy = { ...DEFAULT_MESH_POLICY, ...(base || {}), ...(patch || {}) };
|
|
@@ -86,6 +87,9 @@ function mergeMeshPolicy(base: RepoMeshPolicy | undefined, patch: Partial<RepoMe
|
|
|
86
87
|
if (!SESSION_CLEANUP_MODES.has(String(policy.sessionCleanupOnNodeRemove))) {
|
|
87
88
|
policy.sessionCleanupOnNodeRemove = 'preserve';
|
|
88
89
|
}
|
|
90
|
+
if (!SPAWNED_SESSION_VISIBILITY_MODES.has(String(policy.spawnedSessionVisibility))) {
|
|
91
|
+
policy.spawnedSessionVisibility = 'visible';
|
|
92
|
+
}
|
|
89
93
|
return policy;
|
|
90
94
|
}
|
|
91
95
|
|
package/src/index.ts
CHANGED
|
@@ -79,6 +79,10 @@ export type {
|
|
|
79
79
|
CliProviderState,
|
|
80
80
|
AcpProviderState,
|
|
81
81
|
ExtensionProviderState,
|
|
82
|
+
MessageInputSupport,
|
|
83
|
+
InputMediaStrategyDescriptor,
|
|
84
|
+
InputAttachmentStrategy,
|
|
85
|
+
InputMediaType,
|
|
82
86
|
} from './shared-types.js';
|
|
83
87
|
|
|
84
88
|
// ── Repo Mesh Types (cross-package) ──
|
package/src/mesh/mesh-events.ts
CHANGED
|
@@ -99,10 +99,21 @@ export function setupMeshEventForwarding(components: DaemonComponents) {
|
|
|
99
99
|
const workspace = readNonEmptyString(state.workspace);
|
|
100
100
|
if (!workspace) return;
|
|
101
101
|
const settings = state.settings && typeof state.settings === 'object' ? state.settings as Record<string, unknown> : {};
|
|
102
|
+
|
|
103
|
+
// Coordinator sessions must never inject events into themselves.
|
|
104
|
+
// A coordinator instance carries meshCoordinatorFor but not meshNodeFor/launchedByCoordinator.
|
|
105
|
+
if (readNonEmptyString(settings.meshCoordinatorFor)) return;
|
|
106
|
+
|
|
102
107
|
const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor);
|
|
103
108
|
|
|
104
|
-
//
|
|
105
|
-
//
|
|
109
|
+
// Only forward events for sessions that were explicitly launched as mesh-node delegates
|
|
110
|
+
// (meshNodeFor set by mesh_launch_session) or that carry the launchedByCoordinator flag.
|
|
111
|
+
// Do NOT fall back to workspace-based mesh lookup: that would pick up coordinator sessions
|
|
112
|
+
// and any other CLI session that happens to share the same workspace, causing spurious
|
|
113
|
+
// system-message injection into the coordinator's own conversation.
|
|
114
|
+
const isMeshDelegate = Boolean(meshIdFromRuntime || settings.launchedByCoordinator);
|
|
115
|
+
if (!isMeshDelegate) return;
|
|
116
|
+
|
|
106
117
|
const mesh = meshIdFromRuntime ? getMesh(meshIdFromRuntime) : getMeshByRepo(workspace);
|
|
107
118
|
const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
|
|
108
119
|
if (!meshId) return;
|
|
@@ -76,9 +76,33 @@ function materializeImageDataPart(part: Extract<InputPart, { type: 'image' }>, i
|
|
|
76
76
|
fs.mkdirSync(dir, { recursive: true });
|
|
77
77
|
const filePath = path.join(dir, safeInputImageBasename(index, part.mimeType));
|
|
78
78
|
fs.writeFileSync(filePath, Buffer.from(rawData, 'base64'));
|
|
79
|
+
cleanupStaleMaterializedImages(dir);
|
|
79
80
|
return filePath;
|
|
80
81
|
}
|
|
81
82
|
|
|
83
|
+
const MATERIALIZED_IMAGE_MAX_AGE_MS = 60 * 60 * 1000; // 1 hour
|
|
84
|
+
const MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
|
|
85
|
+
let lastMaterializedImageCleanupAt = 0;
|
|
86
|
+
|
|
87
|
+
function cleanupStaleMaterializedImages(dir: string): void {
|
|
88
|
+
const now = Date.now();
|
|
89
|
+
if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
|
|
90
|
+
lastMaterializedImageCleanupAt = now;
|
|
91
|
+
try {
|
|
92
|
+
const entries = fs.readdirSync(dir);
|
|
93
|
+
for (const entry of entries) {
|
|
94
|
+
if (!entry.startsWith('adhdev-input-image-')) continue;
|
|
95
|
+
const fullPath = path.join(dir, entry);
|
|
96
|
+
try {
|
|
97
|
+
const stat = fs.statSync(fullPath);
|
|
98
|
+
if (now - stat.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
|
|
99
|
+
fs.unlinkSync(fullPath);
|
|
100
|
+
}
|
|
101
|
+
} catch { /* file may have been removed concurrently */ }
|
|
102
|
+
}
|
|
103
|
+
} catch { /* dir may not exist or be inaccessible */ }
|
|
104
|
+
}
|
|
105
|
+
|
|
82
106
|
export function buildCliStructuredInputPrompt(
|
|
83
107
|
input: InputEnvelope,
|
|
84
108
|
options: { materializeDir?: string } = {},
|
|
@@ -113,7 +137,13 @@ export function buildCliStructuredInputPrompt(
|
|
|
113
137
|
}
|
|
114
138
|
});
|
|
115
139
|
|
|
116
|
-
|
|
140
|
+
// Only use textFallback when no explicit text parts were collected — it is
|
|
141
|
+
// the flattened version of the same parts, so appending it alongside them
|
|
142
|
+
// would duplicate the content for multipart inputs.
|
|
143
|
+
const hasExplicitTextParts = input.parts.some((part) => part.type === 'text' && part.text.trim());
|
|
144
|
+
if (!hasExplicitTextParts && input.textFallback.trim()) {
|
|
145
|
+
promptParts.push(input.textFallback.trim());
|
|
146
|
+
}
|
|
117
147
|
|
|
118
148
|
const ordered = [
|
|
119
149
|
...imageRefs,
|
package/src/repo-mesh-types.ts
CHANGED
|
@@ -56,6 +56,7 @@ export type RepoMeshNodeHealth =
|
|
|
56
56
|
// ─── Policy Types ───────────────────────────────
|
|
57
57
|
|
|
58
58
|
export type RepoMeshSessionCleanupMode = 'preserve' | 'stop' | 'delete_stopped' | 'stop_and_delete';
|
|
59
|
+
export type RepoMeshSpawnedSessionVisibility = 'visible' | 'hidden';
|
|
59
60
|
|
|
60
61
|
export interface RepoMeshPolicy {
|
|
61
62
|
requirePreTaskCheckpoint: boolean;
|
|
@@ -65,6 +66,12 @@ export interface RepoMeshPolicy {
|
|
|
65
66
|
dirtyWorkspaceBehavior: 'block' | 'warn' | 'checkpoint_then_continue';
|
|
66
67
|
maxParallelTasks: number;
|
|
67
68
|
allowedProviders?: string[];
|
|
69
|
+
/**
|
|
70
|
+
* Whether sessions spawned by mesh/coordinator policy should auto-open as visible
|
|
71
|
+
* dashboard tabs or start hidden. Defaults to 'visible' to preserve existing
|
|
72
|
+
* watch-the-agents behavior; hidden sessions remain discoverable and manually openable.
|
|
73
|
+
*/
|
|
74
|
+
spawnedSessionVisibility?: RepoMeshSpawnedSessionVisibility;
|
|
68
75
|
/**
|
|
69
76
|
* What to do with delegated session-host records for a node when it is removed.
|
|
70
77
|
* Defaults to 'preserve' so completed work can be reviewed later and live
|
|
@@ -101,6 +108,7 @@ export const DEFAULT_MESH_POLICY: RepoMeshPolicy = {
|
|
|
101
108
|
requireApprovalForDestructiveGit: true,
|
|
102
109
|
dirtyWorkspaceBehavior: 'warn',
|
|
103
110
|
maxParallelTasks: 2,
|
|
111
|
+
spawnedSessionVisibility: 'visible',
|
|
104
112
|
sessionCleanupOnNodeRemove: 'preserve',
|
|
105
113
|
};
|
|
106
114
|
|