@askalf/dario 3.9.0 → 3.9.2

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/dist/cli.js CHANGED
@@ -373,18 +373,13 @@ async function help() {
373
373
  Full IDs: claude-opus-4-6, claude-sonnet-4-6
374
374
  Default: passthrough (client decides)
375
375
  --passthrough, --thin Thin proxy — OAuth swap only, no injection
376
- --preserve-tools Keep client tool schemas (for agents with custom tools)
377
- --hybrid-tools Remap to CC tools AND inject request-context fields
378
- (sessionId, requestId, channelId, userId, timestamp)
379
- declared on the client's tool schema but missing
380
- from CC's. Preserves CC fingerprint. See #33.
376
+ --preserve-tools Forward client tool schemas unchanged
377
+ Loses subscription routing; use for custom agents
378
+ --hybrid-tools Remap to CC tools, inject sessionId/requestId/etc.
379
+ Keeps subscription routing for custom agents
381
380
  --port=PORT Port to listen on (default: 3456)
382
381
  --host=ADDRESS Address to bind to (default: 127.0.0.1)
383
- Use 0.0.0.0 to accept connections from other machines.
384
- Alternatively set DARIO_HOST env var.
385
- When binding non-loopback, also set DARIO_API_KEY
386
- so unauthenticated LAN hosts can't proxy through
387
- your OAuth subscription.
382
+ Use 0.0.0.0 for LAN; see README for DARIO_API_KEY
388
383
  --verbose, -v Log all requests
389
384
 
390
385
  Quick start:
package/dist/oauth.js CHANGED
@@ -52,8 +52,47 @@ function getClaudeCodeCredentialsPath() {
52
52
  * store instead of ~/.claude/.credentials.json:
53
53
  * - macOS: Keychain, service "Claude Code-credentials"
54
54
  * - Linux: libsecret / Secret Service D-Bus API via `secret-tool`
55
- * - Windows: Windows Credential Manager via `cmdkey` (not yet implemented)
55
+ * - Windows: Windows Credential Manager via PowerShell + Win32 CredEnumerate
56
56
  */
57
+ const WIN_CRED_SCRIPT = `
58
+ $ErrorActionPreference = 'Stop'
59
+ $sig = @"
60
+ using System;
61
+ using System.Runtime.InteropServices;
62
+ public class CM {
63
+ [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
64
+ public struct CRED {
65
+ public uint Flags; public uint Type; public string TargetName;
66
+ public string Comment; public System.Runtime.InteropServices.ComTypes.FILETIME LW;
67
+ public uint BlobSize; public IntPtr Blob;
68
+ public uint Persist; public uint AC; public IntPtr Attrs;
69
+ public string Alias; public string UN;
70
+ }
71
+ [DllImport("advapi32.dll", EntryPoint="CredEnumerateW", CharSet=CharSet.Unicode, SetLastError=true)]
72
+ public static extern bool CredEnumerate(string filter, uint flag, out uint count, out IntPtr pCredentials);
73
+ [DllImport("advapi32.dll", EntryPoint="CredFree")]
74
+ public static extern void CredFree(IntPtr cred);
75
+ }
76
+ "@
77
+ Add-Type -TypeDefinition $sig
78
+ $count = 0
79
+ $ptr = [IntPtr]::Zero
80
+ if ([CM]::CredEnumerate('Claude Code-credentials*', 0, [ref]$count, [ref]$ptr)) {
81
+ try {
82
+ for ($i = 0; $i -lt $count; $i++) {
83
+ $credPtr = [System.Runtime.InteropServices.Marshal]::ReadIntPtr($ptr, $i * [IntPtr]::Size)
84
+ $cred = [System.Runtime.InteropServices.Marshal]::PtrToStructure($credPtr, [type][CM+CRED])
85
+ if ($cred.BlobSize -gt 0) {
86
+ $bytes = New-Object byte[] $cred.BlobSize
87
+ [System.Runtime.InteropServices.Marshal]::Copy($cred.Blob, $bytes, 0, $cred.BlobSize)
88
+ Write-Output ([System.Text.Encoding]::Unicode.GetString($bytes))
89
+ }
90
+ }
91
+ } finally {
92
+ [CM]::CredFree($ptr)
93
+ }
94
+ }
95
+ `;
57
96
  async function loadKeychainCredentials() {
58
97
  try {
59
98
  if (platform() === 'darwin') {
@@ -74,6 +113,35 @@ async function loadKeychainCredentials() {
74
113
  return parsed;
75
114
  }
76
115
  }
116
+ else if (platform() === 'win32') {
117
+ // Windows Credential Manager via PowerShell + Win32 CredEnumerate.
118
+ // Claude Code on Windows (via Node keytar) stores OAuth tokens as
119
+ // Generic credentials with target prefix "Claude Code-credentials".
120
+ // We enumerate matching credentials and return the first one that
121
+ // parses as a valid CC credentials blob. The password field is
122
+ // stored as UTF-16LE bytes (keytar convention on Windows).
123
+ //
124
+ // PowerShell CredEnumerate sets LastWin32Error=1168 (ERROR_NOT_FOUND)
125
+ // when the filter matches nothing — we catch the non-zero exit and
126
+ // return null so the caller falls back to the file-path checks.
127
+ const raw = await new Promise((resolve, reject) => {
128
+ execFile('powershell.exe', ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-Command', WIN_CRED_SCRIPT], { timeout: 5000, windowsHide: true }, (err, stdout) => (err ? reject(err) : resolve(stdout)));
129
+ });
130
+ // Script emits one JSON blob per matching credential, newline-separated.
131
+ // Return the first one that parses with the expected CC shape.
132
+ for (const line of raw.split(/\r?\n/)) {
133
+ const s = line.trim();
134
+ if (!s)
135
+ continue;
136
+ try {
137
+ const parsed = JSON.parse(s);
138
+ if (parsed?.claudeAiOauth?.accessToken && parsed?.claudeAiOauth?.refreshToken) {
139
+ return parsed;
140
+ }
141
+ }
142
+ catch { /* not a valid JSON credential blob — try next */ }
143
+ }
144
+ }
77
145
  }
78
146
  catch { /* keychain not available or no entry */ }
79
147
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askalf/dario",
3
- "version": "3.9.0",
3
+ "version": "3.9.2",
4
4
  "description": "A local LLM router. One endpoint, every provider — Claude subscriptions, OpenAI, OpenRouter, Groq, local LiteLLM, any OpenAI-compat endpoint — your tools don't need to change.",
5
5
  "type": "module",
6
6
  "bin": {