runsignal 0.1.4 → 0.1.5
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 +26 -10
- package/bin/runsignal.js +102 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,22 +16,31 @@ npx runsignal --help
|
|
|
16
16
|
|
|
17
17
|
## Commands
|
|
18
18
|
|
|
19
|
-
- `runsignal login`
|
|
19
|
+
- `runsignal login`
|
|
20
20
|
- `runsignal init`
|
|
21
|
-
- `runsignal
|
|
21
|
+
- `runsignal setup`
|
|
22
|
+
- `runsignal wrap -- <command>`
|
|
22
23
|
- `runsignal send --message "..."`
|
|
23
24
|
- `runsignal status <eventId>`
|
|
24
25
|
- `runsignal logout`
|
|
25
|
-
- `runsignal hooks install
|
|
26
|
-
- `runsignal hooks doctor
|
|
27
|
-
- `runsignal hooks uninstall
|
|
26
|
+
- `runsignal hooks install`
|
|
27
|
+
- `runsignal hooks doctor`
|
|
28
|
+
- `runsignal hooks uninstall`
|
|
28
29
|
|
|
29
30
|
## Quickstart
|
|
30
31
|
|
|
32
|
+
Canonical zero-friction onboarding:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx --yes runsignal@latest setup
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Equivalent manual flow:
|
|
39
|
+
|
|
31
40
|
```bash
|
|
32
|
-
npx runsignal@latest login
|
|
33
|
-
npx runsignal@latest init
|
|
34
|
-
npx runsignal@latest
|
|
41
|
+
npx --yes runsignal@latest login
|
|
42
|
+
npx --yes runsignal@latest init
|
|
43
|
+
npx --yes runsignal@latest hooks install
|
|
35
44
|
```
|
|
36
45
|
|
|
37
46
|
## Environment
|
|
@@ -43,12 +52,19 @@ npx runsignal@latest wrap -- claude "refactor auth flow"
|
|
|
43
52
|
To keep using `claude ...` / `codex ...` normally while routing through RunSignal:
|
|
44
53
|
|
|
45
54
|
```bash
|
|
46
|
-
runsignal hooks install
|
|
55
|
+
runsignal hooks install
|
|
47
56
|
```
|
|
48
57
|
|
|
49
58
|
Then restart terminal and verify:
|
|
50
59
|
|
|
51
60
|
```bash
|
|
52
|
-
runsignal hooks doctor
|
|
61
|
+
runsignal hooks doctor
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
After that, use your CLI agents normally:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
claude
|
|
68
|
+
codex
|
|
53
69
|
```
|
|
54
70
|
|
package/bin/runsignal.js
CHANGED
|
@@ -128,7 +128,12 @@ function RunSignal-Resolve-NativeCommand {
|
|
|
128
128
|
}
|
|
129
129
|
function claude {
|
|
130
130
|
$native = RunSignal-Resolve-NativeCommand "claude"
|
|
131
|
-
if (-not $native) {
|
|
131
|
+
if (-not $native) {
|
|
132
|
+
$home = [Environment]::GetFolderPath("UserProfile")
|
|
133
|
+
$fallback = Join-Path $home ".local\\bin\\claude.exe"
|
|
134
|
+
if (Test-Path $fallback) { $native = $fallback }
|
|
135
|
+
}
|
|
136
|
+
if (-not $native) { Write-Error "RunSignal hook: native claude executable not found. Add your native installer path to PATH (example: %USERPROFILE%\\.local\\bin)."; return }
|
|
132
137
|
if ($args.Count -eq 0) { & $native; return }
|
|
133
138
|
runsignal wrap -- $native @args
|
|
134
139
|
}
|
|
@@ -162,7 +167,17 @@ ${HOOK_END}
|
|
|
162
167
|
|
|
163
168
|
return `${HOOK_START}
|
|
164
169
|
runsignal_resolve_native() {
|
|
165
|
-
|
|
170
|
+
local name
|
|
171
|
+
name="$1"
|
|
172
|
+
if type -P "$name" >/dev/null 2>&1; then
|
|
173
|
+
type -P "$name"
|
|
174
|
+
return 0
|
|
175
|
+
fi
|
|
176
|
+
if [ -x "$HOME/.local/bin/$name" ]; then
|
|
177
|
+
printf '%s\n' "$HOME/.local/bin/$name"
|
|
178
|
+
return 0
|
|
179
|
+
fi
|
|
180
|
+
return 1
|
|
166
181
|
}
|
|
167
182
|
claude() {
|
|
168
183
|
local native
|
|
@@ -320,6 +335,21 @@ async function runHooksDoctor(options) {
|
|
|
320
335
|
}
|
|
321
336
|
}
|
|
322
337
|
|
|
338
|
+
async function areHooksInstalled(shellOption) {
|
|
339
|
+
const targets = resolveHookTargets(shellOption);
|
|
340
|
+
if (!targets.length) {
|
|
341
|
+
throw new Error('hooks_shell_not_supported');
|
|
342
|
+
}
|
|
343
|
+
for (const target of targets) {
|
|
344
|
+
const existing = await readTextFile(target.path);
|
|
345
|
+
const hasHooks = existing.includes(HOOK_START) && existing.includes(HOOK_END);
|
|
346
|
+
if (!hasHooks) {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return true;
|
|
351
|
+
}
|
|
352
|
+
|
|
323
353
|
function getMachineName() {
|
|
324
354
|
return process.env.COMPUTERNAME || os.hostname() || 'machine';
|
|
325
355
|
}
|
|
@@ -857,9 +887,78 @@ async function runLogout() {
|
|
|
857
887
|
console.log('Logged out.');
|
|
858
888
|
}
|
|
859
889
|
|
|
890
|
+
async function runSetup(options) {
|
|
891
|
+
const shell = String(options.shell || 'auto');
|
|
892
|
+
let config = await readConfig();
|
|
893
|
+
const baseUrl = String(options.appUrl || config.app_url || DEFAULT_APP_URL).replace(/\/$/, '');
|
|
894
|
+
|
|
895
|
+
if (config.app_url !== baseUrl) {
|
|
896
|
+
await writeConfig(mergeConfig(config, {app_url: baseUrl}));
|
|
897
|
+
config = await readConfig();
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
const summary = {
|
|
901
|
+
login: 'skipped',
|
|
902
|
+
init: 'skipped',
|
|
903
|
+
hooks: 'skipped'
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
if (!config.access_token) {
|
|
907
|
+
await runLogin({appUrl: baseUrl});
|
|
908
|
+
summary.login = 'ok';
|
|
909
|
+
config = await readConfig();
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
if (!config.machine_api_key) {
|
|
913
|
+
await runInit({
|
|
914
|
+
appUrl: baseUrl,
|
|
915
|
+
machineName: options.machineName,
|
|
916
|
+
provider: options.provider,
|
|
917
|
+
botToken: options.botToken,
|
|
918
|
+
chatId: options.chatId,
|
|
919
|
+
webhookUrl: options.webhookUrl
|
|
920
|
+
});
|
|
921
|
+
summary.init = 'ok';
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
const hooksInstalled = await areHooksInstalled(shell);
|
|
925
|
+
if (!hooksInstalled) {
|
|
926
|
+
await runHooksInstall({shell});
|
|
927
|
+
summary.hooks = 'ok';
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
console.log(
|
|
931
|
+
JSON.stringify(
|
|
932
|
+
{
|
|
933
|
+
setup: 'ok',
|
|
934
|
+
login: summary.login,
|
|
935
|
+
init: summary.init,
|
|
936
|
+
hooks: summary.hooks,
|
|
937
|
+
next: 'Open a new terminal, then run claude or codex normally.'
|
|
938
|
+
},
|
|
939
|
+
null,
|
|
940
|
+
2
|
|
941
|
+
)
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
|
|
860
945
|
const program = new Command();
|
|
861
946
|
|
|
862
|
-
program.name('runsignal').description('RunSignal CLI').version('0.1.
|
|
947
|
+
program.name('runsignal').description('RunSignal CLI').version('0.1.5');
|
|
948
|
+
|
|
949
|
+
program
|
|
950
|
+
.command('setup')
|
|
951
|
+
.description('Zero-friction onboarding: login + init + hooks install')
|
|
952
|
+
.option('--app-url <url>', 'RunSignal app base URL')
|
|
953
|
+
.option('--shell <shell>', 'auto|powershell|bash|zsh|all', 'auto')
|
|
954
|
+
.option('--provider <provider>', 'telegram or slack (optional)')
|
|
955
|
+
.option('--machine-name <name>', 'Machine name override')
|
|
956
|
+
.option('--bot-token <token>', 'Telegram bot token')
|
|
957
|
+
.option('--chat-id <id>', 'Telegram chat id')
|
|
958
|
+
.option('--webhook-url <url>', 'Slack webhook URL')
|
|
959
|
+
.action(async (options) => {
|
|
960
|
+
await runSetup(options);
|
|
961
|
+
});
|
|
863
962
|
|
|
864
963
|
program
|
|
865
964
|
.command('login')
|