@adhdev/daemon-core 0.9.81 → 0.9.82-rc.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 +125 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +125 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/router.ts +150 -3
package/package.json
CHANGED
package/src/commands/router.ts
CHANGED
|
@@ -85,6 +85,136 @@ function readProviderPriorityFromPolicy(policy: unknown): string[] {
|
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
function readObjectRecord(value: unknown): Record<string, any> {
|
|
89
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
90
|
+
? value as Record<string, any>
|
|
91
|
+
: {};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function readStringValue(...values: unknown[]): string | undefined {
|
|
95
|
+
for (const value of values) {
|
|
96
|
+
if (typeof value === 'string' && value.trim()) return value.trim();
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function readNumberValue(...values: unknown[]): number | undefined {
|
|
102
|
+
for (const value of values) {
|
|
103
|
+
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
|
104
|
+
}
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function readBooleanValue(...values: unknown[]): boolean | undefined {
|
|
109
|
+
for (const value of values) {
|
|
110
|
+
if (typeof value === 'boolean') return value;
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function buildCachedInlineMeshGitStatus(node: any): Record<string, unknown> | undefined {
|
|
116
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
117
|
+
const cachedGit = readObjectRecord(cachedStatus.git);
|
|
118
|
+
if (Object.keys(cachedGit).length) {
|
|
119
|
+
const conflictFiles = Array.isArray(cachedGit.conflictFiles)
|
|
120
|
+
? cachedGit.conflictFiles.filter((value: unknown): value is string => typeof value === 'string')
|
|
121
|
+
: [];
|
|
122
|
+
const conflictCount = readNumberValue(cachedGit.conflicts) ?? conflictFiles.length;
|
|
123
|
+
const hasConflicts = readBooleanValue(cachedGit.hasConflicts) ?? conflictCount > 0;
|
|
124
|
+
const isGitRepo = readBooleanValue(cachedGit.isGitRepo);
|
|
125
|
+
if (isGitRepo !== undefined) {
|
|
126
|
+
return {
|
|
127
|
+
workspace: readStringValue(cachedGit.workspace, node?.workspace) || '',
|
|
128
|
+
repoRoot: readStringValue(cachedGit.repoRoot, node?.repoRoot, node?.workspace) || null,
|
|
129
|
+
isGitRepo,
|
|
130
|
+
branch: readStringValue(cachedGit.branch) ?? null,
|
|
131
|
+
headCommit: readStringValue(cachedGit.headCommit) ?? null,
|
|
132
|
+
headMessage: readStringValue(cachedGit.headMessage) ?? null,
|
|
133
|
+
upstream: readStringValue(cachedGit.upstream) ?? null,
|
|
134
|
+
ahead: readNumberValue(cachedGit.ahead) ?? 0,
|
|
135
|
+
behind: readNumberValue(cachedGit.behind) ?? 0,
|
|
136
|
+
staged: readNumberValue(cachedGit.staged) ?? 0,
|
|
137
|
+
modified: readNumberValue(cachedGit.modified) ?? 0,
|
|
138
|
+
untracked: readNumberValue(cachedGit.untracked) ?? 0,
|
|
139
|
+
deleted: readNumberValue(cachedGit.deleted) ?? 0,
|
|
140
|
+
renamed: readNumberValue(cachedGit.renamed) ?? 0,
|
|
141
|
+
hasConflicts,
|
|
142
|
+
conflictFiles,
|
|
143
|
+
stashCount: readNumberValue(cachedGit.stashCount) ?? 0,
|
|
144
|
+
lastCheckedAt: readNumberValue(cachedGit.lastCheckedAt) ?? Date.now(),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const rawGit = readObjectRecord(node?.lastGit ?? node?.last_git);
|
|
150
|
+
const gitResult = readObjectRecord(rawGit.result);
|
|
151
|
+
const directStatus = readObjectRecord(rawGit.status);
|
|
152
|
+
const nestedStatus = readObjectRecord(gitResult.status);
|
|
153
|
+
const rawProbe = readObjectRecord(node?.lastProbe ?? node?.last_probe);
|
|
154
|
+
const probeGit = readObjectRecord(rawProbe.git);
|
|
155
|
+
const probeGitResult = readObjectRecord(probeGit.result);
|
|
156
|
+
const probeDirectStatus = readObjectRecord(probeGit.status);
|
|
157
|
+
const probeNestedStatus = readObjectRecord(probeGitResult.status);
|
|
158
|
+
const status = Object.keys(directStatus).length
|
|
159
|
+
? directStatus
|
|
160
|
+
: Object.keys(nestedStatus).length
|
|
161
|
+
? nestedStatus
|
|
162
|
+
: Object.keys(probeDirectStatus).length
|
|
163
|
+
? probeDirectStatus
|
|
164
|
+
: Object.keys(probeNestedStatus).length
|
|
165
|
+
? probeNestedStatus
|
|
166
|
+
: {};
|
|
167
|
+
const isGitRepo = readBooleanValue(status.isGitRepo);
|
|
168
|
+
if (!Object.keys(status).length || isGitRepo === undefined) return undefined;
|
|
169
|
+
const conflictFiles = Array.isArray(status.conflictFiles)
|
|
170
|
+
? status.conflictFiles.filter((value: unknown): value is string => typeof value === 'string')
|
|
171
|
+
: [];
|
|
172
|
+
const conflictCount = readNumberValue(status.conflicts) ?? conflictFiles.length;
|
|
173
|
+
const hasConflicts = readBooleanValue(status.hasConflicts) ?? conflictCount > 0;
|
|
174
|
+
return {
|
|
175
|
+
workspace: readStringValue(status.workspace, node?.workspace) || '',
|
|
176
|
+
repoRoot: readStringValue(status.repoRoot, node?.repoRoot, node?.workspace) || null,
|
|
177
|
+
isGitRepo,
|
|
178
|
+
branch: readStringValue(status.branch) ?? null,
|
|
179
|
+
headCommit: readStringValue(status.headCommit) ?? null,
|
|
180
|
+
headMessage: readStringValue(status.headMessage) ?? null,
|
|
181
|
+
upstream: readStringValue(status.upstream) ?? null,
|
|
182
|
+
ahead: readNumberValue(status.ahead) ?? 0,
|
|
183
|
+
behind: readNumberValue(status.behind) ?? 0,
|
|
184
|
+
staged: readNumberValue(status.staged) ?? 0,
|
|
185
|
+
modified: readNumberValue(status.modified) ?? 0,
|
|
186
|
+
untracked: readNumberValue(status.untracked) ?? 0,
|
|
187
|
+
deleted: readNumberValue(status.deleted) ?? 0,
|
|
188
|
+
renamed: readNumberValue(status.renamed) ?? 0,
|
|
189
|
+
hasConflicts,
|
|
190
|
+
conflictFiles,
|
|
191
|
+
stashCount: readNumberValue(status.stashCount) ?? 0,
|
|
192
|
+
lastCheckedAt: Date.now(),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function applyCachedInlineMeshNodeStatus(status: Record<string, unknown>, node: any): boolean {
|
|
197
|
+
const cachedStatus = readObjectRecord(node?.cachedStatus);
|
|
198
|
+
const git = buildCachedInlineMeshGitStatus(node);
|
|
199
|
+
const error = readStringValue(cachedStatus.error, node?.error);
|
|
200
|
+
const health = readStringValue(cachedStatus.health, node?.health);
|
|
201
|
+
const machineStatus = readStringValue(cachedStatus.machineStatus, node?.machineStatus);
|
|
202
|
+
if (!git && !error && !health) return false;
|
|
203
|
+
if (!machineStatus && !git && !error) return false;
|
|
204
|
+
if (git) status.git = git;
|
|
205
|
+
if (error) status.error = error;
|
|
206
|
+
if (health) {
|
|
207
|
+
status.health = health;
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
if (git) {
|
|
211
|
+
const dirty = Number(git.staged || 0) + Number(git.modified || 0) + Number(git.untracked || 0) + Number(git.deleted || 0) + Number(git.renamed || 0) > 0;
|
|
212
|
+
status.health = git.isGitRepo === false ? 'degraded' : dirty ? 'dirty' : 'online';
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
|
|
88
218
|
async function resolveProviderTypeFromPriority(args: {
|
|
89
219
|
nodeId: string;
|
|
90
220
|
providerPriority: string[];
|
|
@@ -632,7 +762,16 @@ export class DaemonCommandRouter {
|
|
|
632
762
|
return this.inlineMeshCache.get(meshId);
|
|
633
763
|
}
|
|
634
764
|
|
|
635
|
-
private async getMeshForCommand(
|
|
765
|
+
private async getMeshForCommand(
|
|
766
|
+
meshId: string,
|
|
767
|
+
inlineMesh?: unknown,
|
|
768
|
+
options?: { preferInline?: boolean },
|
|
769
|
+
): Promise<{ mesh: any; inline: boolean } | null> {
|
|
770
|
+
const preferInline = options?.preferInline === true;
|
|
771
|
+
if (preferInline) {
|
|
772
|
+
const cached = this.getCachedInlineMesh(meshId, inlineMesh);
|
|
773
|
+
if (cached) return { mesh: cached, inline: true };
|
|
774
|
+
}
|
|
636
775
|
try {
|
|
637
776
|
const { getMesh } = await import('../config/mesh-config.js');
|
|
638
777
|
const mesh = getMesh(meshId);
|
|
@@ -2734,7 +2873,7 @@ export class DaemonCommandRouter {
|
|
|
2734
2873
|
const meshId = typeof args?.meshId === 'string' ? args.meshId.trim() : '';
|
|
2735
2874
|
if (!meshId) return { success: false, error: 'meshId required' };
|
|
2736
2875
|
try {
|
|
2737
|
-
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
|
|
2876
|
+
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
2738
2877
|
const mesh = meshRecord?.mesh;
|
|
2739
2878
|
if (!mesh) return { success: false, error: 'Mesh not found' };
|
|
2740
2879
|
|
|
@@ -2762,6 +2901,10 @@ export class DaemonCommandRouter {
|
|
|
2762
2901
|
activeSessions: [],
|
|
2763
2902
|
};
|
|
2764
2903
|
if (node.workspace && typeof node.workspace === 'string') {
|
|
2904
|
+
if (!fs.existsSync(node.workspace as string) && applyCachedInlineMeshNodeStatus(status, node)) {
|
|
2905
|
+
nodeStatuses.push(status);
|
|
2906
|
+
continue;
|
|
2907
|
+
}
|
|
2765
2908
|
try {
|
|
2766
2909
|
const { execFile } = await import('node:child_process');
|
|
2767
2910
|
const { promisify } = await import('node:util');
|
|
@@ -2826,8 +2969,12 @@ export class DaemonCommandRouter {
|
|
|
2826
2969
|
};
|
|
2827
2970
|
status.health = branch ? (dirty ? 'dirty' : 'online') : 'degraded';
|
|
2828
2971
|
} catch {
|
|
2829
|
-
status
|
|
2972
|
+
if (!applyCachedInlineMeshNodeStatus(status, node)) {
|
|
2973
|
+
status.health = 'degraded';
|
|
2974
|
+
}
|
|
2830
2975
|
}
|
|
2976
|
+
} else {
|
|
2977
|
+
applyCachedInlineMeshNodeStatus(status, node);
|
|
2831
2978
|
}
|
|
2832
2979
|
nodeStatuses.push(status);
|
|
2833
2980
|
}
|