u-foo 1.0.3 → 1.1.9
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 +110 -11
- package/README.zh-CN.md +9 -7
- package/SKILLS/ufoo/SKILL.md +132 -0
- package/SKILLS/uinit/SKILL.md +78 -0
- package/SKILLS/ustatus/SKILL.md +36 -0
- package/bin/uclaude.js +13 -0
- package/bin/ucode-core.js +15 -0
- package/bin/ucode.js +125 -0
- package/bin/ucodex.js +13 -0
- package/bin/ufoo +9 -31
- package/bin/ufoo-assistant-agent.js +5 -0
- package/bin/ufoo-engine.js +25 -0
- package/bin/ufoo.js +17 -0
- package/modules/AGENTS.template.md +29 -11
- package/modules/bus/README.md +33 -25
- package/modules/bus/SKILLS/ubus/SKILL.md +19 -8
- package/modules/context/README.md +18 -40
- package/modules/context/SKILLS/uctx/SKILL.md +63 -1
- package/modules/online/SKILLS/ufoo-online/SKILL.md +144 -0
- package/package.json +25 -4
- package/scripts/import-pi-mono.js +124 -0
- package/scripts/postinstall.js +30 -0
- package/scripts/sync-claude-skills.sh +21 -0
- package/src/agent/cliRunner.js +554 -33
- package/src/agent/internalRunner.js +150 -56
- package/src/agent/launcher.js +754 -0
- package/src/agent/normalizeOutput.js +1 -1
- package/src/agent/notifier.js +340 -0
- package/src/agent/ptyRunner.js +847 -0
- package/src/agent/ptyWrapper.js +379 -0
- package/src/agent/readyDetector.js +175 -0
- package/src/agent/ucode.js +443 -0
- package/src/agent/ucodeBootstrap.js +113 -0
- package/src/agent/ucodeBuild.js +67 -0
- package/src/agent/ucodeDoctor.js +184 -0
- package/src/agent/ucodeRuntimeConfig.js +129 -0
- package/src/agent/ufooAgent.js +46 -42
- package/src/assistant/agent.js +260 -0
- package/src/assistant/bridge.js +172 -0
- package/src/assistant/engine.js +252 -0
- package/src/assistant/stdio.js +58 -0
- package/src/assistant/ufooEngineCli.js +306 -0
- package/src/bus/activate.js +172 -0
- package/src/bus/daemon.js +436 -0
- package/src/bus/index.js +842 -0
- package/src/bus/inject.js +315 -0
- package/src/bus/message.js +430 -0
- package/src/bus/nickname.js +88 -0
- package/src/bus/queue.js +136 -0
- package/src/bus/shake.js +26 -0
- package/src/bus/store.js +189 -0
- package/src/bus/subscriber.js +312 -0
- package/src/bus/utils.js +363 -0
- package/src/chat/agentBar.js +117 -0
- package/src/chat/agentDirectory.js +88 -0
- package/src/chat/agentSockets.js +225 -0
- package/src/chat/agentViewController.js +298 -0
- package/src/chat/chatLogController.js +115 -0
- package/src/chat/commandExecutor.js +700 -0
- package/src/chat/commands.js +132 -0
- package/src/chat/completionController.js +414 -0
- package/src/chat/cronScheduler.js +160 -0
- package/src/chat/daemonConnection.js +166 -0
- package/src/chat/daemonCoordinator.js +64 -0
- package/src/chat/daemonMessageRouter.js +257 -0
- package/src/chat/daemonReconnect.js +41 -0
- package/src/chat/daemonTransport.js +36 -0
- package/src/chat/daemonTransportDefaults.js +10 -0
- package/src/chat/dashboardKeyController.js +480 -0
- package/src/chat/dashboardView.js +154 -0
- package/src/chat/index.js +1011 -1392
- package/src/chat/inputHistoryController.js +105 -0
- package/src/chat/inputListenerController.js +304 -0
- package/src/chat/inputMath.js +104 -0
- package/src/chat/inputSubmitHandler.js +171 -0
- package/src/chat/layout.js +165 -0
- package/src/chat/pasteController.js +81 -0
- package/src/chat/rawKeyMap.js +42 -0
- package/src/chat/settingsController.js +132 -0
- package/src/chat/statusLineController.js +177 -0
- package/src/chat/streamTracker.js +138 -0
- package/src/chat/text.js +70 -0
- package/src/chat/transport.js +61 -0
- package/src/cli/busCoreCommands.js +59 -0
- package/src/cli/ctxCoreCommands.js +199 -0
- package/src/cli/onlineCoreCommands.js +379 -0
- package/src/cli.js +1162 -96
- package/src/code/README.md +29 -0
- package/src/code/UCODE_PROMPT.md +32 -0
- package/src/code/agent.js +1651 -0
- package/src/code/cli.js +158 -0
- package/src/code/config +0 -0
- package/src/code/dispatch.js +42 -0
- package/src/code/index.js +70 -0
- package/src/code/nativeRunner.js +1213 -0
- package/src/code/runtime.js +154 -0
- package/src/code/sessionStore.js +162 -0
- package/src/code/taskDecomposer.js +269 -0
- package/src/code/tools/bash.js +53 -0
- package/src/code/tools/common.js +42 -0
- package/src/code/tools/edit.js +70 -0
- package/src/code/tools/read.js +44 -0
- package/src/code/tools/write.js +35 -0
- package/src/code/tui.js +1580 -0
- package/src/config.js +56 -3
- package/src/context/decisions.js +324 -0
- package/src/context/doctor.js +183 -0
- package/src/context/index.js +55 -0
- package/src/context/sync.js +127 -0
- package/src/daemon/agentProcessManager.js +74 -0
- package/src/daemon/cronOps.js +241 -0
- package/src/daemon/index.js +998 -170
- package/src/daemon/ipcServer.js +99 -0
- package/src/daemon/ops.js +630 -48
- package/src/daemon/promptLoop.js +319 -0
- package/src/daemon/promptRequest.js +101 -0
- package/src/daemon/providerSessions.js +306 -0
- package/src/daemon/reporting.js +90 -0
- package/src/daemon/run.js +31 -1
- package/src/daemon/status.js +48 -8
- package/src/doctor/index.js +50 -0
- package/src/init/index.js +318 -0
- package/src/online/bridge.js +663 -0
- package/src/online/client.js +245 -0
- package/src/online/runner.js +253 -0
- package/src/online/server.js +992 -0
- package/src/online/tokens.js +103 -0
- package/src/report/store.js +331 -0
- package/src/shared/eventContract.js +35 -0
- package/src/shared/ptySocketContract.js +21 -0
- package/src/skills/index.js +159 -0
- package/src/status/index.js +285 -0
- package/src/terminal/adapterContract.js +87 -0
- package/src/terminal/adapterRouter.js +84 -0
- package/src/terminal/adapters/externalAdapter.js +14 -0
- package/src/terminal/adapters/internalAdapter.js +13 -0
- package/src/terminal/adapters/internalPtyAdapter.js +42 -0
- package/src/terminal/adapters/internalQueueAdapter.js +37 -0
- package/src/terminal/adapters/terminalAdapter.js +31 -0
- package/src/terminal/adapters/tmuxAdapter.js +30 -0
- package/src/terminal/detect.js +64 -0
- package/src/terminal/index.js +8 -0
- package/src/terminal/iterm2.js +126 -0
- package/src/ufoo/agentsStore.js +107 -0
- package/src/ufoo/paths.js +46 -0
- package/src/utils/banner.js +76 -0
- package/bin/uclaude +0 -65
- package/bin/ucodex +0 -65
- package/modules/bus/scripts/bus-alert.sh +0 -185
- package/modules/bus/scripts/bus-listen.sh +0 -117
- package/modules/context/ASSUMPTIONS.md +0 -7
- package/modules/context/CONSTRAINTS.md +0 -7
- package/modules/context/CONTEXT-STRUCTURE.md +0 -49
- package/modules/context/DECISION-PROTOCOL.md +0 -62
- package/modules/context/HANDOFF.md +0 -33
- package/modules/context/RULES.md +0 -15
- package/modules/context/SKILLS/README.md +0 -14
- package/modules/context/SYSTEM.md +0 -18
- package/modules/context/TEMPLATES/assumptions.md +0 -4
- package/modules/context/TEMPLATES/constraints.md +0 -4
- package/modules/context/TEMPLATES/decision.md +0 -16
- package/modules/context/TEMPLATES/project-context-readme.md +0 -6
- package/modules/context/TEMPLATES/system.md +0 -3
- package/modules/context/TEMPLATES/terminology.md +0 -4
- package/modules/context/TERMINOLOGY.md +0 -10
- package/scripts/banner.sh +0 -89
- package/scripts/bus-alert.sh +0 -6
- package/scripts/bus-autotrigger.sh +0 -6
- package/scripts/bus-daemon.sh +0 -231
- package/scripts/bus-inject.sh +0 -144
- package/scripts/bus-listen.sh +0 -6
- package/scripts/bus.sh +0 -984
- package/scripts/context-decisions.sh +0 -167
- package/scripts/context-doctor.sh +0 -72
- package/scripts/context-lint.sh +0 -110
- package/scripts/doctor.sh +0 -22
- package/scripts/init.sh +0 -247
- package/scripts/skills.sh +0 -113
- package/scripts/status.sh +0 -125
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ufoo-online
|
|
3
|
+
description: |
|
|
4
|
+
Connect any agent to the ufoo-online WebSocket relay for public channel chat,
|
|
5
|
+
public rooms, or private room collaboration. Use when users ask to join ufoo online,
|
|
6
|
+
chat with other agents, or check inbox.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /ufoo-online - Online Relay Client
|
|
10
|
+
|
|
11
|
+
Connect to the ufoo-online WebSocket relay, join channels/rooms, send messages, and check inbox.
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Start a local relay server
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
ufoo online server --port 8787
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### 2. Connect (long-running, run in background)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Join a public channel
|
|
25
|
+
ufoo online connect --nickname my-agent --join lobby --ping-ms 15000
|
|
26
|
+
|
|
27
|
+
# Join a private room (enables bus/decisions/wake sync)
|
|
28
|
+
ufoo online connect --nickname my-agent --room room_001 --room-password secret --ping-ms 15000
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Use `run_in_background: true` to keep the connection alive in agent sessions.
|
|
32
|
+
|
|
33
|
+
### 3. Send a message
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Send to a channel
|
|
37
|
+
ufoo online send --nickname my-agent --channel lobby --text "hello everyone"
|
|
38
|
+
|
|
39
|
+
# Send to a room
|
|
40
|
+
ufoo online send --nickname my-agent --room room_001 --text "hello team"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Messages are queued to the local outbox (`~/.ufoo/online/outbox/<nickname>.jsonl`)
|
|
44
|
+
and delivered by the running `connect` process. The connect process must be running
|
|
45
|
+
for messages to be sent.
|
|
46
|
+
|
|
47
|
+
### 4. Check inbox
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# View all messages
|
|
51
|
+
ufoo online inbox my-agent
|
|
52
|
+
|
|
53
|
+
# View unread only
|
|
54
|
+
ufoo online inbox my-agent --unread
|
|
55
|
+
|
|
56
|
+
# Clear inbox
|
|
57
|
+
ufoo online inbox my-agent --clear
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Inbox retention: channel messages 7 days, room messages 30 days.
|
|
61
|
+
|
|
62
|
+
## Full Connect Options
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
ufoo online connect --nickname <name> [--url <ws://...>] [--subscriber <id>]
|
|
66
|
+
[--token <tok>] [--token-hash <hash>] [--world <name>] [--ping-ms <ms>]
|
|
67
|
+
[--join <channel>] [--room <room-id> --room-password <pwd>]
|
|
68
|
+
[--interval <ms>] [--allow-insecure-ws]
|
|
69
|
+
[--trust-remote] [--allow-from <subscriberId>]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Features:
|
|
73
|
+
- Auto-reconnect with exponential backoff (500ms -> 8s)
|
|
74
|
+
- Auto-generates token if none exists; persists to `~/.ufoo/online/tokens.json`
|
|
75
|
+
- Incoming messages saved to `~/.ufoo/online/inbox/<nickname>.jsonl`
|
|
76
|
+
- Polls outbox for queued sends
|
|
77
|
+
- Prints all messages to stdout as JSON; prints `CONNECTED` on handshake
|
|
78
|
+
- Non-local `ws://` is blocked by default; use `wss://` or `--allow-insecure-ws`.
|
|
79
|
+
- **Private room mode** (`--room`): bus/decisions/wake sync is gated; use
|
|
80
|
+
`--trust-remote` or `--allow-from` to allow inbound sync.
|
|
81
|
+
|
|
82
|
+
## Server Management
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Start relay (dev mode — any token accepted)
|
|
86
|
+
ufoo online server --port 8787
|
|
87
|
+
|
|
88
|
+
# Start with token validation
|
|
89
|
+
ufoo online server --port 8787 --token-file ~/.ufoo/online/tokens.json
|
|
90
|
+
|
|
91
|
+
# Custom host/idle timeout
|
|
92
|
+
ufoo online server --host 0.0.0.0 --port 8787 --idle-timeout 60000
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Token Management
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
ufoo online token <subscriber-id> --nickname <name> [--server <url>]
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Tokens are stored in `~/.ufoo/online/tokens.json`. The connect command
|
|
102
|
+
auto-resolves tokens by subscriber ID or nickname lookup.
|
|
103
|
+
|
|
104
|
+
## Room & Channel Management
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Channels (public broadcast, can join multiple)
|
|
108
|
+
ufoo online channel list [--server <url>]
|
|
109
|
+
ufoo online channel create --name <name> [--type world|public] [--server <url>]
|
|
110
|
+
|
|
111
|
+
# Rooms (collaboration, can join one)
|
|
112
|
+
ufoo online room list [--server <url>]
|
|
113
|
+
ufoo online room create --type public|private [--name <room>] [--password <pwd>] [--server <url>]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
If the relay requires auth, pass `--auth-token <token>` (or `--token-file` +
|
|
117
|
+
`--subscriber`/`--nickname`) to room/channel commands to send the Bearer token.
|
|
118
|
+
|
|
119
|
+
## Usage Scenarios
|
|
120
|
+
|
|
121
|
+
### 1. Public channel chat
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
ufoo online server --port 8787 # Terminal 1
|
|
125
|
+
ufoo online connect --nickname agent-a --join lobby # Terminal 2 (background)
|
|
126
|
+
ufoo online connect --nickname agent-b --join lobby # Terminal 3 (background)
|
|
127
|
+
ufoo online send --nickname agent-a --channel lobby --text "hi all"
|
|
128
|
+
ufoo online inbox agent-b # See agent-a's message
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 2. Private room collaboration
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
ufoo online room create --type private --password secret --server http://127.0.0.1:8787
|
|
135
|
+
# → returns room_id
|
|
136
|
+
|
|
137
|
+
ufoo online connect --nickname dev-1 --room room_001 --room-password secret
|
|
138
|
+
ufoo online connect --nickname dev-2 --room room_001 --room-password secret
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
In private room mode, agents automatically sync:
|
|
142
|
+
- Bus messages (local bus <-> online relay, bidirectional)
|
|
143
|
+
- Decisions (new .md files synced across team)
|
|
144
|
+
- Wake events (remote agent can wake local agent via bus)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "u-foo",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.9",
|
|
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",
|
|
@@ -17,13 +17,19 @@
|
|
|
17
17
|
],
|
|
18
18
|
"bin": {
|
|
19
19
|
"ufoo": "bin/ufoo.js",
|
|
20
|
-
"uclaude": "bin/uclaude",
|
|
21
|
-
"ucodex": "bin/ucodex"
|
|
20
|
+
"uclaude": "bin/uclaude.js",
|
|
21
|
+
"ucodex": "bin/ucodex.js",
|
|
22
|
+
"ucode": "bin/ucode.js",
|
|
23
|
+
"ucode-core": "bin/ucode-core.js",
|
|
24
|
+
"ufoo-assistant-agent": "bin/ufoo-assistant-agent.js",
|
|
25
|
+
"ufoo-engine": "bin/ufoo-engine.js"
|
|
22
26
|
},
|
|
23
27
|
"files": [
|
|
24
28
|
"bin/",
|
|
25
29
|
"src/",
|
|
30
|
+
"online/",
|
|
26
31
|
"scripts/",
|
|
32
|
+
"SKILLS/",
|
|
27
33
|
"modules/",
|
|
28
34
|
"LICENSE",
|
|
29
35
|
"README.md"
|
|
@@ -32,9 +38,24 @@
|
|
|
32
38
|
"engines": {
|
|
33
39
|
"node": ">=18"
|
|
34
40
|
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"postinstall": "node scripts/postinstall.js",
|
|
43
|
+
"import:pi-mono": "node scripts/import-pi-mono.js",
|
|
44
|
+
"test": "jest",
|
|
45
|
+
"test:watch": "jest --watch",
|
|
46
|
+
"test:coverage": "jest --coverage"
|
|
47
|
+
},
|
|
35
48
|
"dependencies": {
|
|
36
49
|
"blessed": "^0.1.81",
|
|
37
50
|
"chalk": "^4.1.2",
|
|
38
|
-
"commander": "^13.1.0"
|
|
51
|
+
"commander": "^13.1.0",
|
|
52
|
+
"gray-matter": "^4.0.3",
|
|
53
|
+
"node-pty": "^1.1.0",
|
|
54
|
+
"ws": "^8.19.0",
|
|
55
|
+
"xterm-addon-serialize": "^0.11.0",
|
|
56
|
+
"xterm-headless": "^5.3.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"jest": "^30.2.0"
|
|
39
60
|
}
|
|
40
61
|
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const { spawnSync } = require("child_process");
|
|
6
|
+
|
|
7
|
+
function usage() {
|
|
8
|
+
console.log("Usage: node scripts/import-pi-mono.js <pi-mono-source-path> [--target <target-path>]");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function shouldSkip(name = "") {
|
|
12
|
+
return name === ".git" || name === "node_modules";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function copyRecursive(source, target) {
|
|
16
|
+
const stat = fs.statSync(source);
|
|
17
|
+
if (stat.isDirectory()) {
|
|
18
|
+
fs.mkdirSync(target, { recursive: true });
|
|
19
|
+
const entries = fs.readdirSync(source);
|
|
20
|
+
for (const entry of entries) {
|
|
21
|
+
if (shouldSkip(entry)) continue;
|
|
22
|
+
copyRecursive(path.join(source, entry), path.join(target, entry));
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
27
|
+
fs.copyFileSync(source, target);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function parseArgs(argv = []) {
|
|
31
|
+
const args = Array.isArray(argv) ? argv : [];
|
|
32
|
+
const parsed = {
|
|
33
|
+
source: "",
|
|
34
|
+
target: "",
|
|
35
|
+
help: false,
|
|
36
|
+
};
|
|
37
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
38
|
+
const item = String(args[i] || "").trim();
|
|
39
|
+
if (!item) continue;
|
|
40
|
+
if (item === "--help" || item === "-h") {
|
|
41
|
+
parsed.help = true;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (item === "--target" || item === "-t") {
|
|
45
|
+
const next = String(args[i + 1] || "").trim();
|
|
46
|
+
if (next) parsed.target = next;
|
|
47
|
+
i += 1;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (!parsed.source) parsed.source = item;
|
|
51
|
+
}
|
|
52
|
+
return parsed;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function readGitValue(sourceRoot = "", gitArgs = []) {
|
|
56
|
+
try {
|
|
57
|
+
const res = spawnSync("git", ["-C", sourceRoot, ...gitArgs], {
|
|
58
|
+
encoding: "utf8",
|
|
59
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
60
|
+
});
|
|
61
|
+
if (res.error || res.status !== 0) return "";
|
|
62
|
+
return String(res.stdout || "").trim();
|
|
63
|
+
} catch {
|
|
64
|
+
return "";
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function readGitMetadata(sourceRoot = "") {
|
|
69
|
+
return {
|
|
70
|
+
commit: readGitValue(sourceRoot, ["rev-parse", "HEAD"]),
|
|
71
|
+
branch: readGitValue(sourceRoot, ["rev-parse", "--abbrev-ref", "HEAD"]),
|
|
72
|
+
remote: readGitValue(sourceRoot, ["config", "--get", "remote.origin.url"]),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function main() {
|
|
77
|
+
const parsedArgs = parseArgs(process.argv.slice(2));
|
|
78
|
+
if (parsedArgs.help) {
|
|
79
|
+
usage();
|
|
80
|
+
process.exit(0);
|
|
81
|
+
}
|
|
82
|
+
const sourceArg = parsedArgs.source || "";
|
|
83
|
+
if (!sourceArg) {
|
|
84
|
+
usage();
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const sourceRoot = path.resolve(sourceArg);
|
|
89
|
+
const sourcePackage = path.join(sourceRoot, "package.json");
|
|
90
|
+
if (!fs.existsSync(sourcePackage)) {
|
|
91
|
+
console.error(`Invalid source: missing package.json at ${sourceRoot}`);
|
|
92
|
+
process.exit(2);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const repoRoot = path.resolve(__dirname, "..");
|
|
96
|
+
const targetRoot = path.resolve(parsedArgs.target || path.join(repoRoot, "src", "code", "pi-mono"));
|
|
97
|
+
const backupRoot = `${targetRoot}.backup-${Date.now()}`;
|
|
98
|
+
|
|
99
|
+
if (fs.existsSync(targetRoot)) {
|
|
100
|
+
fs.renameSync(targetRoot, backupRoot);
|
|
101
|
+
console.log(`Backed up existing fork to ${backupRoot}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
copyRecursive(sourceRoot, targetRoot);
|
|
105
|
+
const upstream = readGitMetadata(sourceRoot);
|
|
106
|
+
|
|
107
|
+
const metadata = {
|
|
108
|
+
imported_at: new Date().toISOString(),
|
|
109
|
+
source_root: sourceRoot,
|
|
110
|
+
target: targetRoot,
|
|
111
|
+
upstream_commit: upstream.commit,
|
|
112
|
+
upstream_branch: upstream.branch,
|
|
113
|
+
upstream_remote: upstream.remote,
|
|
114
|
+
};
|
|
115
|
+
fs.writeFileSync(
|
|
116
|
+
path.join(targetRoot, ".ufoo-import.json"),
|
|
117
|
+
`${JSON.stringify(metadata, null, 2)}\n`,
|
|
118
|
+
"utf8",
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
console.log(`Imported pi-mono into ${targetRoot}${upstream.commit ? ` @ ${upstream.commit}` : ""}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
main();
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
|
|
5
|
+
// Fix node-pty spawn-helper permissions on macOS (both arm64 and x64)
|
|
6
|
+
const platforms = ["darwin-arm64", "darwin-x64"];
|
|
7
|
+
|
|
8
|
+
for (const platform of platforms) {
|
|
9
|
+
try {
|
|
10
|
+
const spawnHelperPath = path.join(
|
|
11
|
+
__dirname,
|
|
12
|
+
"..",
|
|
13
|
+
"node_modules",
|
|
14
|
+
"node-pty",
|
|
15
|
+
"prebuilds",
|
|
16
|
+
platform,
|
|
17
|
+
"spawn-helper"
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
if (fs.existsSync(spawnHelperPath)) {
|
|
21
|
+
const stats = fs.statSync(spawnHelperPath);
|
|
22
|
+
if ((stats.mode & 0o111) === 0) {
|
|
23
|
+
fs.chmodSync(spawnHelperPath, 0o755);
|
|
24
|
+
console.log(`[postinstall] Fixed node-pty spawn-helper permissions (${platform})`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
} catch {
|
|
28
|
+
// Silently ignore - not critical for non-macOS or if node-pty not installed
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Sync SKILLS to .claude/commands for Claude Code slash commands
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
SKILLS_DIR="SKILLS"
|
|
7
|
+
CLAUDE_COMMANDS_DIR=".claude/commands"
|
|
8
|
+
|
|
9
|
+
# Create commands directory if it doesn't exist
|
|
10
|
+
mkdir -p "$CLAUDE_COMMANDS_DIR"
|
|
11
|
+
|
|
12
|
+
# Copy all SKILL.md files to .claude/commands/
|
|
13
|
+
for skill_dir in "$SKILLS_DIR"/*; do
|
|
14
|
+
if [ -d "$skill_dir" ] && [ -f "$skill_dir/SKILL.md" ]; then
|
|
15
|
+
skill_name=$(basename "$skill_dir")
|
|
16
|
+
echo "Syncing $skill_name..."
|
|
17
|
+
cp "$skill_dir/SKILL.md" "$CLAUDE_COMMANDS_DIR/$skill_name.md"
|
|
18
|
+
fi
|
|
19
|
+
done
|
|
20
|
+
|
|
21
|
+
echo "Skills synced to Claude Code commands directory!"
|