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.
Files changed (3) hide show
  1. package/README.md +26 -10
  2. package/bin/runsignal.js +102 -3
  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 wrap -- <command>`
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 --shell powershell`
26
- - `runsignal hooks doctor --shell powershell`
27
- - `runsignal hooks uninstall --shell powershell`
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 wrap -- claude "refactor auth flow"
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 --shell powershell
55
+ runsignal hooks install
47
56
  ```
48
57
 
49
58
  Then restart terminal and verify:
50
59
 
51
60
  ```bash
52
- runsignal hooks doctor --shell powershell
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) { Write-Error "RunSignal hook: native claude executable not found."; return }
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
- type -P "$1" 2>/dev/null
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.4');
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')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runsignal",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "RunSignal CLI for wrapping AI agent runs and handling approvals",
5
5
  "type": "module",
6
6
  "license": "MIT",