@coworker-jp/aidr 0.1.11 → 0.1.75

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 CHANGED
@@ -1,17 +1,63 @@
1
1
  # aidr
2
2
 
3
- CLI installer for [ai-scanner](https://github.com/coworker-jp/ai-scanner) hooks across 19+ AI coding agents.
3
+ Hook installer CLI for [ai-scanner](https://github.com/coworker-jp/ai-scanner):
4
+ wires the scanner into AI coding agents (Claude Code, Cursor, Windsurf, …) via
5
+ their hook mechanisms and fetches the scanner binary.
4
6
 
5
7
  ## Quick start
6
8
 
9
+ ai-scanner is protection you put **in the repository**: its hooks target
10
+ cloud coding-agent environments (cloud Claude Code, CI, devcontainers) that
11
+ the repository travels into. Your own PC is protected by coworker-sentinel
12
+ (see below), not by these hooks.
13
+
7
14
  ```bash
8
- npx @coworker-jp/aidr install --agent claude --key ak_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
15
+ # Recommended: run inside the repository, then commit the generated config
16
+ # (.claude/ etc.). The scanner binary self-bootstraps in cloud sessions.
17
+ npx @coworker-jp/aidr install --agent claude --scope project --key ak_xxx...
18
+ git add .claude && git commit -m "add ai-scanner hooks"
19
+
20
+ # multiple agents, or auto-detect everything under $HOME:
21
+ npx @coworker-jp/aidr install --agent claude,cursor --scope project --key ak_xxx...
22
+ npx @coworker-jp/aidr install --all --key ak_xxx...
9
23
  ```
10
24
 
25
+ Running `install` interactively on a machine with no cloud/CI/remote
26
+ indicators (= your own PC) stops with a pointer to the coworker-sentinel
27
+ installer; pass `--local` to proceed deliberately (see `--local` below).
28
+
29
+ ## coworker-sentinel (host EDR + DLP) is installed separately
30
+
31
+ aidr does **not** install the coworker-sentinel daemon. Use the OS-native
32
+ installer for your platform — all are available from the user portal's
33
+ Download page:
34
+
35
+ - **Windows**: run `coworker-sentinel-setup.exe` and paste your access key
36
+ when prompted. Uninstall via Add/Remove Programs.
37
+ - **macOS**: open `CoworkerSentinel.dmg`, drag the app to Applications,
38
+ launch it, and enter your access key (one admin-password prompt).
39
+ - **Linux**:
40
+ ```bash
41
+ sudo apt install ./coworker-sentinel.deb
42
+ sudo coworker-sentinel activate --key ak_xxx...
43
+ ```
44
+
45
+ Endpoint-info snapshots are collected by the sentinel daemon itself every
46
+ 6 hours (Pro / Trial plans). On macOS the menu-bar app has a toggle for this;
47
+ on Linux/Windows edit `/etc/aidr/sentinel-settings.json`
48
+ (`%ProgramData%\coworker\sentinel-settings.json`).
49
+
50
+ The old npx install paths are retired: `--scheduled` (cron/launchd
51
+ endpoint-info) and `--with-sentinel` (daemon install) both exit with a
52
+ migration message. `aidr install` / `aidr uninstall` still clean up leftovers
53
+ that older aidr versions wrote (cron/launchd entries; the legacy npx-installed
54
+ sentinel daemon on Linux). Deb-installed sentinels are never touched — their
55
+ cleanup belongs to the package manager.
56
+
11
57
  ## Commands
12
58
 
13
59
  ```bash
14
- aidr install --agent <list|--all> --key <ak_...>
60
+ aidr install --agent <list|standalone|--all> --key <ak_...>
15
61
  [--dry-run] [--force] [--binary-only]
16
62
  [--no-verify] [--skip-binary]
17
63
  aidr uninstall [--agent <list>]
@@ -21,25 +67,31 @@ aidr list-agents
21
67
 
22
68
  Options:
23
69
 
24
- - `--agent <list>`: comma-separated names (`claude,cursor`).
25
- - `--all`: install for every agent detected in `$HOME`.
70
+ - `--agent <list>`: comma-separated agent names (`claude,cursor`), or `standalone` for a hook-less binary-only install into `~/.aidr/bin`, or `--all`.
26
71
  - `--key <ak_...>`: access key (format `ak_` + 43 urlsafe chars).
27
72
  - `--dry-run`: print planned writes, do not touch disk.
28
73
  - `--force`: overwrite existing files.
29
- - `--binary-only`: fetch only the scanner binary.
74
+ - `--binary-only` / `--skip-binary`: only / never fetch the scanner binary.
30
75
  - `--no-verify`: skip the server-side access-key check.
31
- - `--skip-binary`: skip the scanner binary download.
76
+ - `--local`: proceed on a personal PC. By default `aidr install` stops when it
77
+ detects an interactive terminal with no cloud/CI/remote indicators (that
78
+ machine should run coworker-sentinel instead) and prints the sentinel
79
+ installer link. Non-interactive environments (CI, cloud sandboxes,
80
+ agent-executed shells) are never gated. `AIDR_ALLOW_LOCAL_INSTALL=1` is the
81
+ env-var equivalent for scripted local installs.
82
+
83
+ ## Platforms
84
+
85
+ | component | Linux | macOS | Windows |
86
+ |---|---|---|---|
87
+ | ai-scanner agent hooks (this package) | ✅ | ✅ | — |
88
+ | coworker-sentinel (EDR + DLP) | `.deb` installer | DMG | `setup.exe` |
32
89
 
33
- ## Supported agents
90
+ ## Supported agents (hooks)
34
91
 
35
92
  | name | status |
36
93
  |---|---|
37
- | claude | full |
38
- | cursor | full |
39
- | windsurf | full |
40
- | kiro | full |
41
- | gemini | full |
42
- | codex | full |
94
+ | claude, cursor, windsurf, kiro, gemini, codex | full |
43
95
  | cline, roo, copilot, qwen, trae, amazonq, jetbrains, opencode, aider, amp, crush, antigravity, continue | stub (Phase 2) |
44
96
 
45
97
  ## Developing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coworker-jp/aidr",
3
- "version": "0.1.11",
3
+ "version": "0.1.75",
4
4
  "description": "AIDR setup CLI - installs ai-scanner hooks for 19+ AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,9 +12,9 @@ export const meta = {
12
12
  };
13
13
 
14
14
  // Standalone mode has no hook scripts and no settings.json. The CLI's
15
- // shared binary-fetch step drops ai-scanner + opengrep into
16
- // ~/.aidr/bin/, and the scheduled installer wires up
17
- // systemd/launchd/cron to invoke the binary periodically.
15
+ // shared binary-fetch step drops ai-scanner + opengrep into ~/.aidr/bin/.
16
+ // (The coworker-sentinel daemon — installed via the OS-native installers
17
+ // self-downloads its own ai-scanner copy; aidr is not involved.)
18
18
  export async function install() {
19
19
  return { installed: [], backupPath: null, backupPaths: [] };
20
20
  }
@@ -13,11 +13,13 @@ export function detectPlatform() {
13
13
  const arch = process.arch;
14
14
  if (os === "linux" && arch === "x64") return "linux-x86_64";
15
15
  if (os === "linux" && arch === "arm64") return "linux-aarch64";
16
- if (os === "darwin" && arch === "arm64") return "darwin-aarch64";
16
+ // Both macOS arches resolve to the SAME key on purpose. The object under
17
+ // `darwin-aarch64` is a universal (fat) Mach-O carrying an arm64 AND an
18
+ // x86_64 slice, so one download serves Apple Silicon and Intel alike. The key
19
+ // name is a wire contract with the verify Lambda's SCANNER_PLATFORMS — only
20
+ // its contents became universal, never its name.
21
+ if (os === "darwin" && (arch === "arm64" || arch === "x64")) return "darwin-aarch64";
17
22
  if (os === "win32" && arch === "x64") return "windows-x86_64";
18
- if (os === "darwin" && arch === "x64") {
19
- throw new Error("Intel Mac (darwin-x86_64) is not supported. Apple Silicon only.");
20
- }
21
23
  throw new Error(`Unsupported platform: ${os}/${arch}`);
22
24
  }
23
25
 
@@ -156,57 +158,3 @@ export async function fetchOpengrep(destPath) {
156
158
 
157
159
  return { path: destPath, platform, sha256, verified: true };
158
160
  }
159
-
160
- /**
161
- * Download coworker-sentinel for the current platform into `destPath`.
162
- * Uses the presigned S3 URL from the verify response when available,
163
- * otherwise falls back to the licensed download endpoint.
164
- * Returns { path, platform, sha256, verified }.
165
- */
166
- export async function fetchSentinel(
167
- destPath,
168
- { accessKey, presignedUrl, dllPresignedUrl, env = "prod" } = {},
169
- ) {
170
- const platform = detectPlatform();
171
-
172
- let binUrl;
173
- let binAuthKey = accessKey;
174
- if (presignedUrl) {
175
- // Use presigned URL from verify response (no auth header needed)
176
- binUrl = presignedUrl;
177
- binAuthKey = undefined;
178
- } else {
179
- const base = downloadBase(env);
180
- binUrl = `${base}/sentinel/${platform}`;
181
- }
182
-
183
- await fsp.mkdir(path.dirname(destPath), { recursive: true });
184
- const buf = await fetchBuffer(binUrl, binAuthKey);
185
- const sha256 = crypto.createHash("sha256").update(buf).digest("hex");
186
-
187
- const tmp = `${destPath}.tmp-${process.pid}`;
188
- await fsp.writeFile(tmp, buf);
189
- await fsp.chmod(tmp, 0o755); // no-op on Windows; harmless
190
- await fsp.rename(tmp, destPath);
191
- await clearQuarantine(destPath);
192
-
193
- // Windows also needs the sibling WinDivert.dll — a PE import the loader
194
- // resolves before the exe's own code runs, so it can't be embedded (unlike
195
- // WinDivert64.sys, which is embedded and self-extracts at first run).
196
- if (platform === "windows-x86_64") {
197
- const dllPath = path.join(path.dirname(destPath), "WinDivert.dll");
198
- let dllUrl = dllPresignedUrl;
199
- let dllAuthKey;
200
- if (dllUrl) {
201
- dllAuthKey = undefined;
202
- } else {
203
- const base = downloadBase(env);
204
- dllUrl = `${base}/sentinel/${platform}/WinDivert.dll`;
205
- dllAuthKey = accessKey;
206
- }
207
- const dllBuf = await fetchBuffer(dllUrl, dllAuthKey);
208
- await fsp.writeFile(dllPath, dllBuf);
209
- }
210
-
211
- return { path: destPath, platform, sha256, verified: false };
212
- }