nomoreide 0.1.56 → 0.1.57
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/core/agent-runtime.d.ts +12 -2
- package/dist/core/agent-runtime.js +16 -5
- package/dist/core/agent-runtime.js.map +1 -1
- package/dist/core/config-store.d.ts +2 -0
- package/dist/core/config-store.js +15 -0
- package/dist/core/config-store.js.map +1 -1
- package/dist/core/process-manager.d.ts +13 -0
- package/dist/core/process-manager.js +59 -2
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/service-graph.d.ts +50 -0
- package/dist/core/service-graph.js +143 -0
- package/dist/core/service-graph.js.map +1 -0
- package/dist/core/types.d.ts +10 -0
- package/dist/web/client/assets/{code-editor-BnSokx6t.js → code-editor-BxFHS7P5.js} +1 -1
- package/dist/web/client/assets/core-DhEqZVGG.js +1 -0
- package/dist/web/client/assets/event-BK_86lmQ.js +1 -0
- package/dist/web/client/assets/index-4FJ5hj8X.js +222 -0
- package/dist/web/client/assets/index-Ca7-Vu2E.css +1 -0
- package/dist/web/client/assets/window-DlR023_X.js +1 -0
- package/dist/web/client/index.html +2 -2
- package/dist/web/routes/agent-chat-routes.js +41 -13
- package/dist/web/routes/agent-chat-routes.js.map +1 -1
- package/dist/web/routes/service-routes.js +16 -0
- package/dist/web/routes/service-routes.js.map +1 -1
- package/package.json +5 -1
- package/dist/web/client/assets/index-B0Tno-0X.js +0 -215
- package/dist/web/client/assets/index-CBZqXKDN.css +0 -1
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/** Thrown by {@link resolveStartOrder} when the requested set contains a cycle. */
|
|
2
|
+
export class DependencyCycleError extends Error {
|
|
3
|
+
cycle;
|
|
4
|
+
constructor(cycle) {
|
|
5
|
+
super(`Service dependency cycle detected: ${cycle.join(" → ")}.`);
|
|
6
|
+
this.name = "DependencyCycleError";
|
|
7
|
+
this.cycle = cycle;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Build the full graph for every registered service (used by the UI panel). */
|
|
11
|
+
export function buildServiceGraph(services) {
|
|
12
|
+
const registered = new Set(services.map((service) => service.name));
|
|
13
|
+
const nodes = services.map((service) => {
|
|
14
|
+
const declared = dedupe(service.dependsOn ?? []).filter((dep) => dep !== service.name);
|
|
15
|
+
return {
|
|
16
|
+
name: service.name,
|
|
17
|
+
dependsOn: declared.filter((dep) => registered.has(dep)),
|
|
18
|
+
missing: declared.filter((dep) => !registered.has(dep)),
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
const edges = nodes.flatMap((node) => node.dependsOn.map((to) => ({ from: node.name, to })));
|
|
22
|
+
const { order, cycles } = topoSort(nodes);
|
|
23
|
+
return { nodes, edges, order, cycles };
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the start order for `requested` services, expanding to include any
|
|
27
|
+
* transitive dependencies that are also registered. Deps come before the
|
|
28
|
+
* services that need them. Throws {@link DependencyCycleError} if the expanded
|
|
29
|
+
* set contains a cycle. Unknown deps are silently skipped (they surface in the
|
|
30
|
+
* UI graph instead — a missing dependency shouldn't block a manual bundle run).
|
|
31
|
+
*/
|
|
32
|
+
export function resolveStartOrder(services, requested) {
|
|
33
|
+
const byName = new Map(services.map((service) => [service.name, service]));
|
|
34
|
+
const wanted = new Set();
|
|
35
|
+
const visit = (name) => {
|
|
36
|
+
if (wanted.has(name))
|
|
37
|
+
return;
|
|
38
|
+
const service = byName.get(name);
|
|
39
|
+
if (!service)
|
|
40
|
+
return; // not registered → caller handles the error on start
|
|
41
|
+
wanted.add(name);
|
|
42
|
+
for (const dep of service.dependsOn ?? []) {
|
|
43
|
+
if (dep !== name)
|
|
44
|
+
visit(dep);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
for (const name of requested)
|
|
48
|
+
visit(name);
|
|
49
|
+
const subset = buildServiceGraph(services.filter((service) => wanted.has(service.name)));
|
|
50
|
+
if (subset.cycles.length > 0) {
|
|
51
|
+
throw new DependencyCycleError(subset.cycles[0]);
|
|
52
|
+
}
|
|
53
|
+
return subset.order;
|
|
54
|
+
}
|
|
55
|
+
function dedupe(values) {
|
|
56
|
+
return [...new Set(values)];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Kahn's algorithm. Returns the topological `order` and, for any nodes left
|
|
60
|
+
* unsorted (i.e. inside a cycle), the distinct `cycles` extracted via DFS.
|
|
61
|
+
*/
|
|
62
|
+
function topoSort(nodes) {
|
|
63
|
+
const inDegree = new Map();
|
|
64
|
+
const dependents = new Map();
|
|
65
|
+
for (const node of nodes) {
|
|
66
|
+
inDegree.set(node.name, 0);
|
|
67
|
+
dependents.set(node.name, []);
|
|
68
|
+
}
|
|
69
|
+
for (const node of nodes) {
|
|
70
|
+
for (const dep of node.dependsOn) {
|
|
71
|
+
// dep must run before node → edge dep -> node.
|
|
72
|
+
inDegree.set(node.name, (inDegree.get(node.name) ?? 0) + 1);
|
|
73
|
+
dependents.get(dep)?.push(node.name);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const queue = nodes.filter((node) => inDegree.get(node.name) === 0).map((node) => node.name);
|
|
77
|
+
const order = [];
|
|
78
|
+
while (queue.length > 0) {
|
|
79
|
+
const name = queue.shift();
|
|
80
|
+
order.push(name);
|
|
81
|
+
for (const next of dependents.get(name) ?? []) {
|
|
82
|
+
const remaining = (inDegree.get(next) ?? 0) - 1;
|
|
83
|
+
inDegree.set(next, remaining);
|
|
84
|
+
if (remaining === 0)
|
|
85
|
+
queue.push(next);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (order.length === nodes.length) {
|
|
89
|
+
return { order, cycles: [] };
|
|
90
|
+
}
|
|
91
|
+
// Nodes not emitted are part of one or more cycles. A topo sort can't order
|
|
92
|
+
// them, so callers should treat `order` as invalid when `cycles` is non-empty.
|
|
93
|
+
const stuck = new Set(nodes.map((node) => node.name).filter((name) => !order.includes(name)));
|
|
94
|
+
return { order: [], cycles: findCycles(nodes, stuck) };
|
|
95
|
+
}
|
|
96
|
+
/** DFS over the unsorted nodes to extract concrete cycle paths for display. */
|
|
97
|
+
function findCycles(nodes, stuck) {
|
|
98
|
+
const depMap = new Map(nodes.map((node) => [node.name, node.dependsOn]));
|
|
99
|
+
const cycles = [];
|
|
100
|
+
const seen = new Set();
|
|
101
|
+
const stack = [];
|
|
102
|
+
const onStack = new Set();
|
|
103
|
+
const dfs = (name) => {
|
|
104
|
+
if (!stuck.has(name))
|
|
105
|
+
return;
|
|
106
|
+
stack.push(name);
|
|
107
|
+
onStack.add(name);
|
|
108
|
+
for (const dep of depMap.get(name) ?? []) {
|
|
109
|
+
if (!stuck.has(dep))
|
|
110
|
+
continue;
|
|
111
|
+
if (onStack.has(dep)) {
|
|
112
|
+
const start = stack.indexOf(dep);
|
|
113
|
+
if (start !== -1)
|
|
114
|
+
cycles.push(stack.slice(start));
|
|
115
|
+
}
|
|
116
|
+
else if (!seen.has(dep)) {
|
|
117
|
+
dfs(dep);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
stack.pop();
|
|
121
|
+
onStack.delete(name);
|
|
122
|
+
seen.add(name);
|
|
123
|
+
};
|
|
124
|
+
for (const name of stuck) {
|
|
125
|
+
if (!seen.has(name))
|
|
126
|
+
dfs(name);
|
|
127
|
+
}
|
|
128
|
+
return dedupeCycles(cycles);
|
|
129
|
+
}
|
|
130
|
+
/** Collapse rotations/duplicates so the same cycle is reported once. */
|
|
131
|
+
function dedupeCycles(cycles) {
|
|
132
|
+
const seen = new Set();
|
|
133
|
+
const result = [];
|
|
134
|
+
for (const cycle of cycles) {
|
|
135
|
+
const key = [...cycle].sort().join("|");
|
|
136
|
+
if (seen.has(key))
|
|
137
|
+
continue;
|
|
138
|
+
seen.add(key);
|
|
139
|
+
result.push(cycle);
|
|
140
|
+
}
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=service-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-graph.js","sourceRoot":"","sources":["../../src/core/service-graph.ts"],"names":[],"mappings":"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"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ export interface ServiceDefinition {
|
|
|
9
9
|
description?: string;
|
|
10
10
|
/** Test Runner command; defaults to `npm test` when absent. */
|
|
11
11
|
test?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Names of services that must be started (and healthy) before this one, used
|
|
14
|
+
* to order `startBundle`. Self/unknown references are ignored at start time.
|
|
15
|
+
*/
|
|
16
|
+
dependsOn?: string[];
|
|
12
17
|
command?: string;
|
|
13
18
|
cwd?: string;
|
|
14
19
|
env?: Record<string, string>;
|
|
@@ -116,6 +121,11 @@ export interface NoMoreIdeConfig {
|
|
|
116
121
|
githubTokens: GitHubToken[];
|
|
117
122
|
/** User-saved git/GitHub workflows (forks/edits of the built-in templates). */
|
|
118
123
|
workflows: Workflow[];
|
|
124
|
+
/**
|
|
125
|
+
* Which CLI the in-dock agent chat drives. Undefined = never chosen → fall
|
|
126
|
+
* back to startup-agent detection.
|
|
127
|
+
*/
|
|
128
|
+
chatProvider?: "claude" | "codex";
|
|
119
129
|
}
|
|
120
130
|
export type ServiceState = "stopped" | "starting" | "running" | "exited";
|
|
121
131
|
export interface ServiceStatus {
|