u-foo 2.4.5 → 2.4.7
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 +6 -8
- package/README.zh-CN.md +5 -5
- package/SKILLS/ufoo/SKILL.md +2 -2
- package/SKILLS/uinit/SKILL.md +8 -11
- package/package.json +3 -8
- package/scripts/postinstall.js +1 -21
- package/src/agents/launch/launcher.js +1 -13
- package/src/app/chat/commandExecutor.js +14 -9
- package/src/app/chat/commands.js +2 -2
- package/src/app/chat/daemonCoordinator.js +4 -0
- package/src/app/chat/daemonReconnect.js +17 -7
- package/src/app/cli/features/doctor.js +11 -18
- package/src/app/cli/features/init.js +12 -191
- package/src/app/cli/features/skills.js +0 -15
- package/src/app/cli/run.js +12 -7
- package/src/code/README.md +4 -4
- package/src/code/cli.js +1 -1
- package/src/code/launcher/ucode.js +18 -45
- package/src/code/skills/loader.js +0 -13
- package/src/coordination/context/doctor.js +6 -26
- package/src/online/server.js +1 -1
- package/src/runtime/daemon/index.js +1 -1
- package/src/runtime/daemon/mcpServer.js +1 -1
- package/src/runtime/daemon/restart.js +293 -0
- package/src/runtime/daemon/run.js +31 -37
- package/src/runtime/terminal/index.js +1 -1
- package/src/ui/MIGRATION.md +8 -10
- package/src/ui/ink/ChatApp.js +12 -6
- package/bin/ucode-core.js +0 -15
- package/bin/ufoo +0 -71
- package/modules/AGENTS.template.md +0 -8
- package/modules/bus/README.md +0 -140
- package/modules/context/README.md +0 -60
- package/modules/online/README.md +0 -92
- package/modules/resources/ICONS/README.md +0 -12
- package/modules/resources/ICONS/libraries/README.md +0 -17
- package/modules/resources/ICONS/libraries/heroicons/LICENSE +0 -22
- package/modules/resources/ICONS/libraries/heroicons/README.md +0 -15
- package/modules/resources/ICONS/libraries/heroicons/arrow-right.svg +0 -4
- package/modules/resources/ICONS/libraries/heroicons/check.svg +0 -4
- package/modules/resources/ICONS/libraries/heroicons/chevron-down.svg +0 -4
- package/modules/resources/ICONS/libraries/heroicons/cog-6-tooth.svg +0 -5
- package/modules/resources/ICONS/libraries/heroicons/magnifying-glass.svg +0 -4
- package/modules/resources/ICONS/libraries/heroicons/x-mark.svg +0 -4
- package/modules/resources/ICONS/libraries/lucide/LICENSE +0 -40
- package/modules/resources/ICONS/libraries/lucide/README.md +0 -15
- package/modules/resources/ICONS/libraries/lucide/arrow-right.svg +0 -15
- package/modules/resources/ICONS/libraries/lucide/check.svg +0 -14
- package/modules/resources/ICONS/libraries/lucide/chevron-down.svg +0 -14
- package/modules/resources/ICONS/libraries/lucide/search.svg +0 -15
- package/modules/resources/ICONS/libraries/lucide/settings.svg +0 -15
- package/modules/resources/ICONS/libraries/lucide/x.svg +0 -15
- package/modules/resources/ICONS/rules.md +0 -7
- package/modules/resources/README.md +0 -9
- package/modules/resources/UI/ANTI-PATTERNS.md +0 -6
- package/modules/resources/UI/TONE.md +0 -6
- package/scripts/chat-app-smoke.js +0 -30
- package/scripts/global-chat-switch-benchmark.js +0 -406
- package/scripts/ink-demo.js +0 -23
- package/scripts/ink-smoke.js +0 -30
- package/scripts/ucode-app-smoke.js +0 -36
- /package/{modules/bus/SKILLS → SKILLS}/ubus/SKILL.md +0 -0
- /package/{modules/context/SKILLS → SKILLS}/uctx/SKILL.md +0 -0
- /package/{modules/online/SKILLS → SKILLS}/ufoo-online/SKILL.md +0 -0
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ Initialize a project and open the chat dashboard:
|
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
cd your-project
|
|
72
|
-
ufoo init --
|
|
72
|
+
ufoo init --targets context,bus
|
|
73
73
|
ufoo
|
|
74
74
|
```
|
|
75
75
|
|
|
@@ -167,7 +167,7 @@ still available, but the normal ufoo workflow is to work from chat.
|
|
|
167
167
|
These are setup or troubleshooting commands. In chat, use slash commands:
|
|
168
168
|
|
|
169
169
|
```text
|
|
170
|
-
/init context bus
|
|
170
|
+
/init context bus
|
|
171
171
|
/doctor
|
|
172
172
|
/status
|
|
173
173
|
/daemon status
|
|
@@ -177,11 +177,11 @@ These are setup or troubleshooting commands. In chat, use slash commands:
|
|
|
177
177
|
```
|
|
178
178
|
|
|
179
179
|
`ufoo init` creates `.ufoo/`, ensures `AGENTS.md` and `CLAUDE.md`, initializes
|
|
180
|
-
selected
|
|
181
|
-
edit project instructions in `AGENTS.md`.
|
|
180
|
+
selected workspace state, and prepares shared storage. `CLAUDE.md` may be a
|
|
181
|
+
symlink; edit project instructions in `AGENTS.md`.
|
|
182
182
|
|
|
183
183
|
Before a project has been initialized, the equivalent CLI form is also useful:
|
|
184
|
-
`ufoo init --
|
|
184
|
+
`ufoo init --targets context,bus`.
|
|
185
185
|
|
|
186
186
|
### Event Bus
|
|
187
187
|
|
|
@@ -322,8 +322,7 @@ src/
|
|
|
322
322
|
online/ relay client/server/runner/token helpers
|
|
323
323
|
```
|
|
324
324
|
|
|
325
|
-
See [PROJECT.md](PROJECT.md) for the maintainer-facing map and
|
|
326
|
-
[docs/source-structure.md](docs/source-structure.md) for detailed package
|
|
325
|
+
See [PROJECT.md](PROJECT.md) for the maintainer-facing map and detailed package
|
|
327
326
|
ownership.
|
|
328
327
|
|
|
329
328
|
## Development
|
|
@@ -340,7 +339,6 @@ Useful checks:
|
|
|
340
339
|
```bash
|
|
341
340
|
npm run test:watch
|
|
342
341
|
npm run test:coverage
|
|
343
|
-
npm run bench:global-switch
|
|
344
342
|
```
|
|
345
343
|
|
|
346
344
|
The repository is CommonJS, targets Node.js 18+, and has no build step.
|
package/README.zh-CN.md
CHANGED
|
@@ -67,7 +67,7 @@ npm link
|
|
|
67
67
|
|
|
68
68
|
```bash
|
|
69
69
|
cd your-project
|
|
70
|
-
ufoo init --
|
|
70
|
+
ufoo init --targets context,bus
|
|
71
71
|
ufoo
|
|
72
72
|
```
|
|
73
73
|
|
|
@@ -163,7 +163,7 @@ ufoo -g
|
|
|
163
163
|
这些是初始化或排障命令。进入 chat 后优先使用 slash command:
|
|
164
164
|
|
|
165
165
|
```text
|
|
166
|
-
/init context bus
|
|
166
|
+
/init context bus
|
|
167
167
|
/doctor
|
|
168
168
|
/status
|
|
169
169
|
/daemon status
|
|
@@ -173,10 +173,10 @@ ufoo -g
|
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
`ufoo init` 会创建 `.ufoo/`,确保 `AGENTS.md` 和 `CLAUDE.md` 存在,
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
初始化选中的工作区状态,并准备共享存储。`CLAUDE.md` 可以是 symlink;
|
|
177
|
+
项目指令优先编辑 `AGENTS.md`。
|
|
178
178
|
|
|
179
|
-
项目尚未初始化时,也可以先在外部执行等价 CLI:`ufoo init --
|
|
179
|
+
项目尚未初始化时,也可以先在外部执行等价 CLI:`ufoo init --targets context,bus`。
|
|
180
180
|
|
|
181
181
|
### 事件总线
|
|
182
182
|
|
package/SKILLS/ufoo/SKILL.md
CHANGED
|
@@ -13,7 +13,7 @@ ufoo is the multi-agent coordination layer. It provides four capabilities:
|
|
|
13
13
|
1. **Context Decisions** — Sparse log of major plan-level choices shared across agents
|
|
14
14
|
2. **Shared Memory** — Durable, low-noise project facts shared across agents
|
|
15
15
|
3. **Event Bus** — Inter-agent messaging
|
|
16
|
-
4. **Initialization** — Project setup for ufoo
|
|
16
|
+
4. **Initialization** — Project setup for ufoo workspace state
|
|
17
17
|
|
|
18
18
|
## 1. Context Decisions (uctx)
|
|
19
19
|
|
|
@@ -199,7 +199,7 @@ ufoo history prompt [limit] # Render as injectable prompt block
|
|
|
199
199
|
Trigger: `/uinit` or `/ufoo init`
|
|
200
200
|
|
|
201
201
|
```bash
|
|
202
|
-
ufoo init --
|
|
202
|
+
ufoo init --targets context,bus --project $(pwd)
|
|
203
203
|
```
|
|
204
204
|
|
|
205
205
|
After init, auto-join bus if enabled.
|
package/SKILLS/uinit/SKILL.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: uinit
|
|
3
3
|
description: |
|
|
4
|
-
Initialize ufoo
|
|
4
|
+
Initialize ufoo workspace state in current project.
|
|
5
5
|
Use when: (1) new project needs context/bus enabled, (2) user inputs /uinit or /ufoo init.
|
|
6
|
-
Provides interactive
|
|
6
|
+
Provides interactive target selection, defaults to all selected.
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# uinit
|
|
10
10
|
|
|
11
|
-
Initialize ufoo
|
|
11
|
+
Initialize ufoo workspace state in current project.
|
|
12
12
|
|
|
13
13
|
## Trigger
|
|
14
14
|
|
|
@@ -16,22 +16,20 @@ User inputs `/uinit` or `/ufoo init`
|
|
|
16
16
|
|
|
17
17
|
## Execution Flow
|
|
18
18
|
|
|
19
|
-
### 1. Ask user to select
|
|
19
|
+
### 1. Ask user to select init targets
|
|
20
20
|
|
|
21
21
|
Use AskUserQuestion tool, provide multi-select, default all selected:
|
|
22
22
|
|
|
23
23
|
```
|
|
24
|
-
Please select
|
|
24
|
+
Please select ufoo state to enable:
|
|
25
25
|
|
|
26
26
|
☑ context - Shared context protocol (.ufoo/context/)
|
|
27
27
|
☑ bus - Agent event bus (.ufoo/bus/ + .ufoo/agent/)
|
|
28
|
-
☐ resources - UI/Icons resources (optional)
|
|
29
28
|
```
|
|
30
29
|
|
|
31
30
|
Options:
|
|
32
31
|
- `context` (recommended) - Shared context, sparse decision log for major plan-level choices
|
|
33
32
|
- `bus` (recommended) - Multi-agent communication, task delegation, message passing
|
|
34
|
-
- `resources` (optional) - UI tone guide, icon library
|
|
35
33
|
|
|
36
34
|
Default selected: context, bus
|
|
37
35
|
|
|
@@ -40,10 +38,10 @@ Default selected: context, bus
|
|
|
40
38
|
Based on user selection, execute:
|
|
41
39
|
|
|
42
40
|
```bash
|
|
43
|
-
ufoo init --
|
|
41
|
+
ufoo init --targets <selected_targets> --project $(pwd)
|
|
44
42
|
```
|
|
45
43
|
|
|
46
|
-
### 3. If bus
|
|
44
|
+
### 3. If bus target selected, auto-join bus
|
|
47
45
|
|
|
48
46
|
```bash
|
|
49
47
|
SUBSCRIBER="${UFOO_SUBSCRIBER_ID:-$(ufoo bus whoami 2>/dev/null || true)}"
|
|
@@ -60,7 +58,7 @@ fi
|
|
|
60
58
|
```
|
|
61
59
|
=== ufoo initialization complete ===
|
|
62
60
|
|
|
63
|
-
Enabled
|
|
61
|
+
Enabled ufoo state:
|
|
64
62
|
✓ core memory → .ufoo/memory/
|
|
65
63
|
✓ context → .ufoo/context/
|
|
66
64
|
✓ bus → .ufoo/bus/ + .ufoo/agent/
|
|
@@ -76,4 +74,3 @@ Next steps:
|
|
|
76
74
|
|
|
77
75
|
- If .ufoo/memory, .ufoo/context, .ufoo/bus, or .ufoo/agent already exists, skip creation
|
|
78
76
|
- After initialization, reuse existing subscriber ID first, join only as fallback (if bus enabled)
|
|
79
|
-
- AGENTS.md will have protocol description block injected
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "u-foo",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.7",
|
|
4
4
|
"description": "Multi-Agent Workspace Protocol. Just add u. claude → uclaude, codex → ucodex.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://ufoo.dev",
|
|
@@ -20,8 +20,7 @@
|
|
|
20
20
|
"uclaude": "bin/uclaude.js",
|
|
21
21
|
"ucodex": "bin/ucodex.js",
|
|
22
22
|
"uagy": "bin/uagy.js",
|
|
23
|
-
"ucode": "bin/ucode.js"
|
|
24
|
-
"ucode-core": "bin/ucode-core.js"
|
|
23
|
+
"ucode": "bin/ucode.js"
|
|
25
24
|
},
|
|
26
25
|
"files": [
|
|
27
26
|
"bin/",
|
|
@@ -30,7 +29,6 @@
|
|
|
30
29
|
"online/",
|
|
31
30
|
"scripts/",
|
|
32
31
|
"SKILLS/",
|
|
33
|
-
"modules/",
|
|
34
32
|
"LICENSE",
|
|
35
33
|
"README.md"
|
|
36
34
|
],
|
|
@@ -42,10 +40,7 @@
|
|
|
42
40
|
"postinstall": "node scripts/postinstall.js",
|
|
43
41
|
"test": "jest",
|
|
44
42
|
"test:watch": "jest --watch",
|
|
45
|
-
"test:coverage": "jest --coverage"
|
|
46
|
-
"ink:demo": "node scripts/ink-demo.js",
|
|
47
|
-
"ink:smoke": "node scripts/ink-smoke.js",
|
|
48
|
-
"bench:global-switch": "node scripts/global-chat-switch-benchmark.js"
|
|
43
|
+
"test:coverage": "jest --coverage"
|
|
49
44
|
},
|
|
50
45
|
"dependencies": {
|
|
51
46
|
"@anthropic-ai/claude-agent-sdk": "^0.2.138",
|
package/scripts/postinstall.js
CHANGED
|
@@ -30,11 +30,9 @@ for (const platform of platforms) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
// Collect all skill sources from package
|
|
33
|
+
// Collect all skill sources from the package-level SKILLS directory.
|
|
34
34
|
function collectSkillSources(pkgRoot) {
|
|
35
35
|
const sources = [];
|
|
36
|
-
|
|
37
|
-
// Top-level SKILLS/
|
|
38
36
|
const topSkills = path.join(pkgRoot, "SKILLS");
|
|
39
37
|
if (fs.existsSync(topSkills)) {
|
|
40
38
|
for (const entry of fs.readdirSync(topSkills, { withFileTypes: true })) {
|
|
@@ -46,24 +44,6 @@ function collectSkillSources(pkgRoot) {
|
|
|
46
44
|
}
|
|
47
45
|
}
|
|
48
46
|
}
|
|
49
|
-
|
|
50
|
-
// modules/*/SKILLS/
|
|
51
|
-
const modulesDir = path.join(pkgRoot, "modules");
|
|
52
|
-
if (fs.existsSync(modulesDir)) {
|
|
53
|
-
for (const mod of fs.readdirSync(modulesDir, { withFileTypes: true })) {
|
|
54
|
-
if (!mod.isDirectory()) continue;
|
|
55
|
-
const modSkills = path.join(modulesDir, mod.name, "SKILLS");
|
|
56
|
-
if (!fs.existsSync(modSkills)) continue;
|
|
57
|
-
for (const entry of fs.readdirSync(modSkills, { withFileTypes: true })) {
|
|
58
|
-
if (!entry.isDirectory()) continue;
|
|
59
|
-
const skillMd = path.join(modSkills, entry.name, "SKILL.md");
|
|
60
|
-
if (fs.existsSync(skillMd)) {
|
|
61
|
-
sources.push({ name: entry.name, dir: path.join(modSkills, entry.name), md: skillMd });
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
47
|
return sources;
|
|
68
48
|
}
|
|
69
49
|
|
|
@@ -323,23 +323,11 @@ class AgentLauncher {
|
|
|
323
323
|
|
|
324
324
|
if (!fs.existsSync(busDir)) {
|
|
325
325
|
// 调用 ufoo init
|
|
326
|
-
spawnSync("ufoo", ["init", "--
|
|
326
|
+
spawnSync("ufoo", ["init", "--targets", "context,bus"], {
|
|
327
327
|
cwd: this.cwd,
|
|
328
328
|
stdio: "ignore",
|
|
329
329
|
});
|
|
330
330
|
}
|
|
331
|
-
|
|
332
|
-
// 检查 AGENTS.md 是否有 ufoo template
|
|
333
|
-
const agentsFile = path.join(this.cwd, "AGENTS.md");
|
|
334
|
-
if (fs.existsSync(agentsFile)) {
|
|
335
|
-
const content = fs.readFileSync(agentsFile, "utf8");
|
|
336
|
-
if (!content.includes("<!-- ufoo -->")) {
|
|
337
|
-
spawnSync("ufoo", ["init", "--modules", "context,bus"], {
|
|
338
|
-
cwd: this.cwd,
|
|
339
|
-
stdio: "ignore",
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
331
|
}
|
|
344
332
|
|
|
345
333
|
/**
|
|
@@ -19,6 +19,7 @@ const { parseIntervalMs, formatIntervalMs } = require("./cronScheduler");
|
|
|
19
19
|
const { isGlobalControllerProjectRoot, resolveGlobalControllerUfooDir } = require("../../runtime/projects");
|
|
20
20
|
const { loadPromptProfileRegistry } = require("../../orchestration/groups/promptProfiles");
|
|
21
21
|
const { resolveSoloAgentType } = require("../../orchestration/solo/commands");
|
|
22
|
+
const { restartDaemonLifecycle } = require("../../runtime/daemon/restart");
|
|
22
23
|
const {
|
|
23
24
|
inspectDirectAuthStatus,
|
|
24
25
|
formatDirectAuthStatus,
|
|
@@ -269,15 +270,19 @@ function createCommandExecutor(options = {}) {
|
|
|
269
270
|
}
|
|
270
271
|
|
|
271
272
|
statusMsg("{gray-fg}⚙{/gray-fg} Restarting daemon...");
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
273
|
+
const result = await restartDaemonLifecycle({
|
|
274
|
+
projectRoot: targetRoot,
|
|
275
|
+
isRunning: isDaemonRunning,
|
|
276
|
+
stopDaemon,
|
|
277
|
+
startDaemon,
|
|
278
|
+
stopOptions: { source: "chat-command:/daemon restart" },
|
|
279
|
+
sleep,
|
|
280
|
+
});
|
|
281
|
+
if (result.error === "failed_to_stop") {
|
|
275
282
|
statusMsg("{gray-fg}✗{/gray-fg} Failed to stop daemon");
|
|
276
283
|
return;
|
|
277
284
|
}
|
|
278
|
-
|
|
279
|
-
await sleep(1000);
|
|
280
|
-
if (isDaemonRunning(targetRoot)) {
|
|
285
|
+
if (result.ok) {
|
|
281
286
|
statusMsg("{gray-fg}✓{/gray-fg} Daemon restarted");
|
|
282
287
|
} else {
|
|
283
288
|
statusMsg("{gray-fg}✗{/gray-fg} Failed to restart daemon");
|
|
@@ -298,7 +303,7 @@ function createCommandExecutor(options = {}) {
|
|
|
298
303
|
}
|
|
299
304
|
|
|
300
305
|
async function handleInitCommand(args = []) {
|
|
301
|
-
logMessage("system", "{white-fg}⚙{/white-fg} Initializing ufoo
|
|
306
|
+
logMessage("system", "{white-fg}⚙{/white-fg} Initializing ufoo workspace...");
|
|
302
307
|
|
|
303
308
|
await withCapturedConsole(
|
|
304
309
|
{
|
|
@@ -314,8 +319,8 @@ function createCommandExecutor(options = {}) {
|
|
|
314
319
|
try {
|
|
315
320
|
const repoRoot = path.join(__dirname, "..", "..");
|
|
316
321
|
const init = createInit(repoRoot);
|
|
317
|
-
const
|
|
318
|
-
await init.init({
|
|
322
|
+
const targets = args.length > 0 ? args.join(",") : "context,bus";
|
|
323
|
+
await init.init({ targets, project: projectRoot });
|
|
319
324
|
|
|
320
325
|
logMessage("system", "{white-fg}✓{/white-fg} Initialization complete");
|
|
321
326
|
renderScreen();
|
package/src/app/chat/commands.js
CHANGED
|
@@ -47,7 +47,7 @@ const COMMAND_TREE = {
|
|
|
47
47
|
templates: { desc: "List available templates" },
|
|
48
48
|
},
|
|
49
49
|
},
|
|
50
|
-
"/init": { desc: "Initialize
|
|
50
|
+
"/init": { desc: "Initialize workspace" },
|
|
51
51
|
"/multi": { desc: "Toggle multi-window agent view" },
|
|
52
52
|
"/open": { desc: "Open project path in global mode" },
|
|
53
53
|
"/launch": {
|
|
@@ -305,7 +305,7 @@ function describeCommandForChat(text) {
|
|
|
305
305
|
if (command === "multi") return "Toggling multi-pane view";
|
|
306
306
|
if (command === "open") return `Opening project ${args[0] || ""}`.trim();
|
|
307
307
|
if (command === "resume") return args[0] === "list" ? "Listing recoverable agents" : `Resuming ${args[0] || "agents"}`;
|
|
308
|
-
if (command === "init") return "Initializing ufoo
|
|
308
|
+
if (command === "init") return "Initializing ufoo workspace";
|
|
309
309
|
|
|
310
310
|
return `Running /${command}`;
|
|
311
311
|
}
|
|
@@ -12,8 +12,10 @@ function createDaemonCoordinator(options = {}) {
|
|
|
12
12
|
logMessage,
|
|
13
13
|
stopDaemon,
|
|
14
14
|
startDaemon,
|
|
15
|
+
isDaemonRunning,
|
|
15
16
|
daemonConnection,
|
|
16
17
|
restartDaemon,
|
|
18
|
+
sleep,
|
|
17
19
|
} = options;
|
|
18
20
|
|
|
19
21
|
const connectClientFn = connectClient
|
|
@@ -37,9 +39,11 @@ function createDaemonCoordinator(options = {}) {
|
|
|
37
39
|
projectRoot,
|
|
38
40
|
stopDaemon,
|
|
39
41
|
startDaemon,
|
|
42
|
+
isDaemonRunning,
|
|
40
43
|
daemonConnection: connection,
|
|
41
44
|
logMessage,
|
|
42
45
|
resolveStatusLine,
|
|
46
|
+
sleep,
|
|
43
47
|
});
|
|
44
48
|
let switchProjectChain = Promise.resolve();
|
|
45
49
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { restartLocks } = require("./daemonTransport");
|
|
2
|
+
const { restartDaemonLifecycle } = require("../../runtime/daemon/restart");
|
|
2
3
|
|
|
3
4
|
function resolveDaemonConnection(daemonConnection) {
|
|
4
5
|
return typeof daemonConnection === "function" ? daemonConnection() : daemonConnection;
|
|
@@ -9,9 +10,11 @@ function restartDaemonFlow(options = {}) {
|
|
|
9
10
|
projectRoot,
|
|
10
11
|
stopDaemon,
|
|
11
12
|
startDaemon,
|
|
13
|
+
isDaemonRunning,
|
|
12
14
|
daemonConnection,
|
|
13
15
|
logMessage,
|
|
14
16
|
resolveStatusLine = null,
|
|
17
|
+
sleep,
|
|
15
18
|
} = options;
|
|
16
19
|
|
|
17
20
|
const statusMsg = resolveStatusLine || ((text) => logMessage("status", text));
|
|
@@ -26,14 +29,21 @@ function restartDaemonFlow(options = {}) {
|
|
|
26
29
|
if (connection) {
|
|
27
30
|
connection.close();
|
|
28
31
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const result = await restartDaemonLifecycle({
|
|
33
|
+
projectRoot,
|
|
34
|
+
isRunning: isDaemonRunning,
|
|
35
|
+
stopDaemon,
|
|
36
|
+
startDaemon,
|
|
37
|
+
connect: connection ? () => connection.connect() : null,
|
|
38
|
+
requestStatus: connection && typeof connection.requestStatus === "function"
|
|
39
|
+
? () => connection.requestStatus()
|
|
40
|
+
: null,
|
|
41
|
+
sleep,
|
|
42
|
+
});
|
|
43
|
+
if (result.ok) {
|
|
36
44
|
statusMsg("{gray-fg}✓{/gray-fg} Daemon reconnected");
|
|
45
|
+
} else if (result.error === "failed_to_stop") {
|
|
46
|
+
statusMsg("{gray-fg}✗{/gray-fg} Failed to stop daemon");
|
|
37
47
|
} else {
|
|
38
48
|
statusMsg("{gray-fg}✗{/gray-fg} Failed to reconnect to daemon");
|
|
39
49
|
}
|
|
@@ -14,29 +14,22 @@ class RepoDoctor {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
run() {
|
|
17
|
-
const
|
|
17
|
+
const skillsDir = path.join(this.repoRoot, "SKILLS");
|
|
18
|
+
const contextSkill = path.join(skillsDir, "uctx", "SKILL.md");
|
|
19
|
+
const busSkill = path.join(skillsDir, "ubus", "SKILL.md");
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
if (!
|
|
21
|
-
this.fail(`missing ${contextMod}`);
|
|
22
|
-
}
|
|
21
|
+
if (!fs.existsSync(contextSkill)) this.fail(`missing ${contextSkill}`);
|
|
22
|
+
if (!fs.existsSync(busSkill)) this.fail(`missing ${busSkill}`);
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (!ok) this.failed = true;
|
|
28
|
-
}
|
|
24
|
+
const contextDoctor = new ContextDoctor(this.repoRoot);
|
|
25
|
+
const ok = contextDoctor.lintProtocol();
|
|
26
|
+
if (!ok) this.failed = true;
|
|
29
27
|
|
|
30
28
|
console.log("=== ufoo doctor ===");
|
|
31
29
|
console.log(`Monorepo: ${this.repoRoot}`);
|
|
32
|
-
console.log("
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
const resources = path.join(this.repoRoot, "modules", "resources");
|
|
37
|
-
if (fs.existsSync(resources)) {
|
|
38
|
-
console.log(`- resources: ${resources}`);
|
|
39
|
-
}
|
|
30
|
+
console.log("Skills:");
|
|
31
|
+
if (fs.existsSync(contextSkill)) console.log(`- uctx: ${contextSkill}`);
|
|
32
|
+
if (fs.existsSync(busSkill)) console.log(`- ubus: ${busSkill}`);
|
|
40
33
|
|
|
41
34
|
if (this.failed) {
|
|
42
35
|
console.log("Status: FAILED");
|