agentplugged 1.0.0 → 1.0.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/agent-commands.js +11 -3
- package/dist/main.js +544 -19
- package/dist/method/doctor.yaml +18 -2
- package/package.json +8 -8
package/dist/agent-commands.js
CHANGED
|
@@ -19775,9 +19775,9 @@ const syncCommand = defineCommand({
|
|
|
19775
19775
|
flavor: claudeFlavor(loaded.config.permissions?.mode),
|
|
19776
19776
|
current: claudeSettings
|
|
19777
19777
|
}, has("claude-code") ? {
|
|
19778
|
-
deny: unique([...denyRules(permissionInputs), ...claudeRules.deny]),
|
|
19779
|
-
allow: claudeRules.allow,
|
|
19780
|
-
ask: claudeRules.ask
|
|
19778
|
+
deny: claudeWritable(unique([...denyRules(permissionInputs), ...claudeRules.deny])),
|
|
19779
|
+
allow: claudeWritable(claudeRules.allow),
|
|
19780
|
+
ask: claudeWritable(claudeRules.ask)
|
|
19781
19781
|
} : {}, {
|
|
19782
19782
|
deny: manifest.permissions,
|
|
19783
19783
|
...previousLists[CLAUDE_SETTINGS_PATH]
|
|
@@ -19878,6 +19878,14 @@ const CODEX_HOME_DENY = [
|
|
|
19878
19878
|
function unique(rules) {
|
|
19879
19879
|
return [...new Set(rules)];
|
|
19880
19880
|
}
|
|
19881
|
+
/**
|
|
19882
|
+
* The rules Claude Code's settings can hold: a backslash before the closing parenthesis escapes it
|
|
19883
|
+
* there, so such a rule would be malformed (the `C:/` spelling of the same root stays). The
|
|
19884
|
+
* engine's own guards keep them: they read the rules themselves.
|
|
19885
|
+
*/
|
|
19886
|
+
function claudeWritable(rules) {
|
|
19887
|
+
return rules.filter((rule) => !rule.endsWith("\\)"));
|
|
19888
|
+
}
|
|
19881
19889
|
/** The tool a generated path belongs to, for the summary. */
|
|
19882
19890
|
function groupOf(path) {
|
|
19883
19891
|
if (path.startsWith(".claude/") || path === "CLAUDE.md") return "claude-code";
|
package/dist/main.js
CHANGED
|
@@ -510,6 +510,48 @@ function withoutPart(files, part) {
|
|
|
510
510
|
};
|
|
511
511
|
}
|
|
512
512
|
//#endregion
|
|
513
|
+
//#region ../../packages/adapters-git/dist/atomic-rename.js
|
|
514
|
+
/** The pauses, in milliseconds, before each new try: about a second and a half in all. */
|
|
515
|
+
const RETRY_DELAYS_MS = [
|
|
516
|
+
25,
|
|
517
|
+
50,
|
|
518
|
+
100,
|
|
519
|
+
200,
|
|
520
|
+
400,
|
|
521
|
+
700
|
|
522
|
+
];
|
|
523
|
+
/** The errors Windows gives when another program (an AI tool, an editor, an antivirus) holds a file. */
|
|
524
|
+
const HELD_CODES = /* @__PURE__ */ new Set([
|
|
525
|
+
"EPERM",
|
|
526
|
+
"EBUSY",
|
|
527
|
+
"EACCES"
|
|
528
|
+
]);
|
|
529
|
+
/**
|
|
530
|
+
* Renames `from` over `to`, as the last step of an atomic write. On Windows a file another program
|
|
531
|
+
* holds open cannot be replaced, and that is most often brief: the rename is tried again a few times
|
|
532
|
+
* with growing pauses (about a second and a half in all). When the file stays held, the error names
|
|
533
|
+
* the file and says that another program holds it. Elsewhere, and for any other error, the first
|
|
534
|
+
* error is the answer.
|
|
535
|
+
*/
|
|
536
|
+
async function renameWithRetry(from, to, options = {}) {
|
|
537
|
+
const move = options.rename ?? rename;
|
|
538
|
+
const windows = (options.platform ?? process.platform) === "win32";
|
|
539
|
+
const wait = options.wait ?? ((ms) => new Promise((done) => setTimeout(done, ms)));
|
|
540
|
+
for (let attempt = 0;; attempt++) try {
|
|
541
|
+
await move(from, to);
|
|
542
|
+
return;
|
|
543
|
+
} catch (error) {
|
|
544
|
+
const code = error?.code;
|
|
545
|
+
if (!windows || code === void 0 || !HELD_CODES.has(code)) throw error;
|
|
546
|
+
const pause = RETRY_DELAYS_MS[attempt];
|
|
547
|
+
if (pause === void 0) throw new AgentPluggedError(ErrorCode.UNEXPECTED, "error.file_in_use", {
|
|
548
|
+
path: to,
|
|
549
|
+
code
|
|
550
|
+
});
|
|
551
|
+
await wait(pause);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
//#endregion
|
|
513
555
|
//#region ../../packages/adapters-git/dist/git-process.js
|
|
514
556
|
/** Variables that would point `git` at another repository, index or object store. */
|
|
515
557
|
const REPOSITORY_VARIABLES = [
|
|
@@ -3943,7 +3985,7 @@ var GitStateStore = class {
|
|
|
3943
3985
|
this.#memoryWrites += 1;
|
|
3944
3986
|
const temporary = `${target}.${process.pid}.${this.#memoryWrites}.tmp`;
|
|
3945
3987
|
await writeFile(temporary, `${text}\n`, "utf8");
|
|
3946
|
-
await
|
|
3988
|
+
await renameWithRetry(temporary, target);
|
|
3947
3989
|
}
|
|
3948
3990
|
async backupRemote(options) {
|
|
3949
3991
|
await this.#repository();
|
|
@@ -6095,7 +6137,7 @@ var NodeCodexUserConfig = class {
|
|
|
6095
6137
|
encoding: "utf8",
|
|
6096
6138
|
mode: 384
|
|
6097
6139
|
});
|
|
6098
|
-
await
|
|
6140
|
+
await renameWithRetry(temporary, target);
|
|
6099
6141
|
} finally {
|
|
6100
6142
|
await rm(temporary, { force: true }).catch(() => void 0);
|
|
6101
6143
|
}
|
|
@@ -6163,7 +6205,7 @@ var NodeCommonMemory = class {
|
|
|
6163
6205
|
mode: 384,
|
|
6164
6206
|
flag: "wx"
|
|
6165
6207
|
});
|
|
6166
|
-
await
|
|
6208
|
+
await renameWithRetry(temporary, target);
|
|
6167
6209
|
} catch (error) {
|
|
6168
6210
|
await rm(temporary, { force: true });
|
|
6169
6211
|
throw error;
|
|
@@ -6278,7 +6320,7 @@ var NodeWorkspaceFiles = class {
|
|
|
6278
6320
|
encoding: "utf8",
|
|
6279
6321
|
flag: "wx"
|
|
6280
6322
|
} : { flag: "wx" });
|
|
6281
|
-
await
|
|
6323
|
+
await renameWithRetry(temp, target);
|
|
6282
6324
|
} catch (error) {
|
|
6283
6325
|
await rm(temp, { force: true });
|
|
6284
6326
|
throw error;
|
|
@@ -6405,6 +6447,415 @@ var NodeFolderReader = class {
|
|
|
6405
6447
|
return new NodeWorkspaceFiles(path);
|
|
6406
6448
|
}
|
|
6407
6449
|
};
|
|
6450
|
+
/**
|
|
6451
|
+
* The helper's script: compiles the C#, says it is ready (or why it cannot be), then answers one
|
|
6452
|
+
* JSON line per request line until its input closes. Constrained language mode forbids `Add-Type`,
|
|
6453
|
+
* which is said before trying.
|
|
6454
|
+
*/
|
|
6455
|
+
const HELPER_SCRIPT = `
|
|
6456
|
+
$ErrorActionPreference = 'Stop'
|
|
6457
|
+
$out = [Console]::Out
|
|
6458
|
+
try {
|
|
6459
|
+
$mode = [string]$ExecutionContext.SessionState.LanguageMode
|
|
6460
|
+
if ($mode -ne 'FullLanguage') { throw ('PowerShell is in ' + $mode + ' mode, which forbids compiling code') }
|
|
6461
|
+
Add-Type -ReferencedAssemblies 'System.Web.Extensions' -TypeDefinition @'
|
|
6462
|
+
${String.raw`
|
|
6463
|
+
using System;
|
|
6464
|
+
using System.Runtime.InteropServices;
|
|
6465
|
+
using System.Text;
|
|
6466
|
+
using System.Collections.Generic;
|
|
6467
|
+
using System.Web.Script.Serialization;
|
|
6468
|
+
|
|
6469
|
+
public static class ApCredentials {
|
|
6470
|
+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
6471
|
+
struct CREDENTIAL {
|
|
6472
|
+
public uint Flags;
|
|
6473
|
+
public uint Type;
|
|
6474
|
+
public string TargetName;
|
|
6475
|
+
public string Comment;
|
|
6476
|
+
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
|
|
6477
|
+
public uint CredentialBlobSize;
|
|
6478
|
+
public IntPtr CredentialBlob;
|
|
6479
|
+
public uint Persist;
|
|
6480
|
+
public uint AttributeCount;
|
|
6481
|
+
public IntPtr Attributes;
|
|
6482
|
+
public string TargetAlias;
|
|
6483
|
+
public string UserName;
|
|
6484
|
+
}
|
|
6485
|
+
|
|
6486
|
+
[DllImport("advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
6487
|
+
static extern bool CredRead(string target, uint type, uint flags, out IntPtr credential);
|
|
6488
|
+
[DllImport("advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
6489
|
+
static extern bool CredWrite(ref CREDENTIAL credential, uint flags);
|
|
6490
|
+
[DllImport("advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
6491
|
+
static extern bool CredDelete(string target, uint type, uint flags);
|
|
6492
|
+
[DllImport("advapi32.dll", EntryPoint = "CredEnumerateW", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
6493
|
+
static extern bool CredEnumerate(string filter, uint flags, out uint count, out IntPtr credentials);
|
|
6494
|
+
[DllImport("advapi32.dll", EntryPoint = "CredFree")]
|
|
6495
|
+
static extern void CredFree(IntPtr buffer);
|
|
6496
|
+
|
|
6497
|
+
const uint Generic = 1;
|
|
6498
|
+
const uint PersistEnterprise = 3;
|
|
6499
|
+
const int NotFound = 1168;
|
|
6500
|
+
|
|
6501
|
+
static string Text(string b64) {
|
|
6502
|
+
return b64 == null ? null : Encoding.UTF8.GetString(Convert.FromBase64String(b64));
|
|
6503
|
+
}
|
|
6504
|
+
static string B64(string text) {
|
|
6505
|
+
return Convert.ToBase64String(Encoding.UTF8.GetBytes(text == null ? "" : text));
|
|
6506
|
+
}
|
|
6507
|
+
public static string Failure(int code, string message) {
|
|
6508
|
+
return "{\"ok\":false,\"code\":" + code + ",\"message\":\"" + B64(message) + "\"}";
|
|
6509
|
+
}
|
|
6510
|
+
static string Win32Failure(int code) {
|
|
6511
|
+
string message;
|
|
6512
|
+
try { message = new System.ComponentModel.Win32Exception(code).Message; } catch (Exception) { message = ""; }
|
|
6513
|
+
return Failure(code, message);
|
|
6514
|
+
}
|
|
6515
|
+
|
|
6516
|
+
// One request line in, one answer line out. The line is parsed here, not by a cmdlet, so that
|
|
6517
|
+
// PowerShell module logging (when a policy turns it on) never records a secret.
|
|
6518
|
+
public static string HandleLine(string line) {
|
|
6519
|
+
int id = 0;
|
|
6520
|
+
try {
|
|
6521
|
+
Dictionary<string, object> request =
|
|
6522
|
+
(Dictionary<string, object>)new JavaScriptSerializer().DeserializeObject(line);
|
|
6523
|
+
id = Convert.ToInt32(request["id"]);
|
|
6524
|
+
string answer = Handle(Field(request, "op"), Field(request, "target"), Field(request, "user"), Field(request, "secret"));
|
|
6525
|
+
return "{\"id\":" + id + "," + answer.Substring(1);
|
|
6526
|
+
} catch (Exception) {
|
|
6527
|
+
return "{\"id\":" + id + "," + Failure(0, "the credential helper could not read a request").Substring(1);
|
|
6528
|
+
}
|
|
6529
|
+
}
|
|
6530
|
+
static string Field(Dictionary<string, object> request, string name) {
|
|
6531
|
+
object value;
|
|
6532
|
+
return request.TryGetValue(name, out value) && value != null ? value.ToString() : "";
|
|
6533
|
+
}
|
|
6534
|
+
|
|
6535
|
+
public static string Handle(string op, string targetB64, string userB64, string secretB64) {
|
|
6536
|
+
try {
|
|
6537
|
+
string target = Text(targetB64);
|
|
6538
|
+
if (op == "read") return Read(target);
|
|
6539
|
+
if (op == "write") return Write(target, Text(userB64), Convert.FromBase64String(secretB64));
|
|
6540
|
+
if (op == "delete") return Delete(target);
|
|
6541
|
+
if (op == "list") return List(target);
|
|
6542
|
+
return Failure(0, "unknown operation");
|
|
6543
|
+
} catch (Exception) {
|
|
6544
|
+
return Failure(0, "the credential helper failed");
|
|
6545
|
+
}
|
|
6546
|
+
}
|
|
6547
|
+
|
|
6548
|
+
static string Read(string target) {
|
|
6549
|
+
IntPtr pointer;
|
|
6550
|
+
if (!CredRead(target, Generic, 0, out pointer)) {
|
|
6551
|
+
int error = Marshal.GetLastWin32Error();
|
|
6552
|
+
return error == NotFound ? "{\"ok\":true,\"found\":false}" : Win32Failure(error);
|
|
6553
|
+
}
|
|
6554
|
+
try {
|
|
6555
|
+
CREDENTIAL credential = (CREDENTIAL)Marshal.PtrToStructure(pointer, typeof(CREDENTIAL));
|
|
6556
|
+
byte[] blob = new byte[credential.CredentialBlobSize];
|
|
6557
|
+
if (blob.Length > 0) Marshal.Copy(credential.CredentialBlob, blob, 0, blob.Length);
|
|
6558
|
+
string answer = "{\"ok\":true,\"found\":true,\"secret\":\"" + Convert.ToBase64String(blob) + "\"}";
|
|
6559
|
+
Array.Clear(blob, 0, blob.Length);
|
|
6560
|
+
return answer;
|
|
6561
|
+
} finally {
|
|
6562
|
+
CredFree(pointer);
|
|
6563
|
+
}
|
|
6564
|
+
}
|
|
6565
|
+
|
|
6566
|
+
static string Write(string target, string user, byte[] blob) {
|
|
6567
|
+
IntPtr memory = Marshal.AllocHGlobal(blob.Length == 0 ? 1 : blob.Length);
|
|
6568
|
+
try {
|
|
6569
|
+
if (blob.Length > 0) Marshal.Copy(blob, 0, memory, blob.Length);
|
|
6570
|
+
CREDENTIAL credential = new CREDENTIAL();
|
|
6571
|
+
credential.Type = Generic;
|
|
6572
|
+
credential.TargetName = target;
|
|
6573
|
+
credential.CredentialBlobSize = (uint)blob.Length;
|
|
6574
|
+
credential.CredentialBlob = memory;
|
|
6575
|
+
credential.Persist = PersistEnterprise;
|
|
6576
|
+
credential.UserName = user;
|
|
6577
|
+
if (!CredWrite(ref credential, 0)) return Win32Failure(Marshal.GetLastWin32Error());
|
|
6578
|
+
return "{\"ok\":true}";
|
|
6579
|
+
} finally {
|
|
6580
|
+
byte[] zeros = new byte[blob.Length];
|
|
6581
|
+
if (zeros.Length > 0) Marshal.Copy(zeros, 0, memory, zeros.Length);
|
|
6582
|
+
Marshal.FreeHGlobal(memory);
|
|
6583
|
+
Array.Clear(blob, 0, blob.Length);
|
|
6584
|
+
}
|
|
6585
|
+
}
|
|
6586
|
+
|
|
6587
|
+
static string Delete(string target) {
|
|
6588
|
+
if (CredDelete(target, Generic, 0)) return "{\"ok\":true,\"found\":true}";
|
|
6589
|
+
int error = Marshal.GetLastWin32Error();
|
|
6590
|
+
return error == NotFound ? "{\"ok\":true,\"found\":false}" : Win32Failure(error);
|
|
6591
|
+
}
|
|
6592
|
+
|
|
6593
|
+
// The accounts of a service: every generic credential whose target is "<user>.<service>".
|
|
6594
|
+
static string List(string service) {
|
|
6595
|
+
uint count;
|
|
6596
|
+
IntPtr array;
|
|
6597
|
+
if (!CredEnumerate(null, 0, out count, out array)) {
|
|
6598
|
+
int error = Marshal.GetLastWin32Error();
|
|
6599
|
+
return error == NotFound ? "{\"ok\":true,\"users\":[]}" : Win32Failure(error);
|
|
6600
|
+
}
|
|
6601
|
+
try {
|
|
6602
|
+
List<string> users = new List<string>();
|
|
6603
|
+
for (int index = 0; index < count; index++) {
|
|
6604
|
+
IntPtr pointer = Marshal.ReadIntPtr(array, index * IntPtr.Size);
|
|
6605
|
+
CREDENTIAL credential = (CREDENTIAL)Marshal.PtrToStructure(pointer, typeof(CREDENTIAL));
|
|
6606
|
+
if (credential.Type == Generic && credential.UserName != null
|
|
6607
|
+
&& credential.TargetName == credential.UserName + "." + service) {
|
|
6608
|
+
users.Add("\"" + B64(credential.UserName) + "\"");
|
|
6609
|
+
}
|
|
6610
|
+
}
|
|
6611
|
+
return "{\"ok\":true,\"users\":[" + string.Join(",", users.ToArray()) + "]}";
|
|
6612
|
+
} finally {
|
|
6613
|
+
CredFree(array);
|
|
6614
|
+
}
|
|
6615
|
+
}
|
|
6616
|
+
}
|
|
6617
|
+
`}
|
|
6618
|
+
'@
|
|
6619
|
+
$out.WriteLine('{"ready":true}')
|
|
6620
|
+
} catch {
|
|
6621
|
+
# Constrained language mode forbids method calls: the reason goes out as plain ASCII text,
|
|
6622
|
+
# through a cmdlet.
|
|
6623
|
+
$reason = ([string]$_) -replace '[^ -~]', ' ' -replace '["\\\\]', ' '
|
|
6624
|
+
Write-Output ('{"ready":false,"message":"' + $reason + '"}')
|
|
6625
|
+
exit 0
|
|
6626
|
+
}
|
|
6627
|
+
while ($null -ne ($line = [Console]::In.ReadLine())) {
|
|
6628
|
+
if ($line.Trim().Length -eq 0) { continue }
|
|
6629
|
+
$out.WriteLine([ApCredentials]::HandleLine($line))
|
|
6630
|
+
}
|
|
6631
|
+
`;
|
|
6632
|
+
/** Windows PowerShell 5.1 by its full path: never a `powershell` found on the PATH. */
|
|
6633
|
+
function windowsPowerShellPath() {
|
|
6634
|
+
const root = process.env.SystemRoot ?? process.env.windir;
|
|
6635
|
+
if (root === void 0) return void 0;
|
|
6636
|
+
const path = join(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
|
|
6637
|
+
return existsSync(path) ? path : void 0;
|
|
6638
|
+
}
|
|
6639
|
+
/** The helper cannot be used on this machine (no PowerShell, constrained language, a crash...). */
|
|
6640
|
+
var PowerShellUnavailableError = class extends Error {
|
|
6641
|
+
name = "PowerShellUnavailableError";
|
|
6642
|
+
};
|
|
6643
|
+
const decode = (text) => Buffer.from(text ?? "", "base64").toString("utf8");
|
|
6644
|
+
/** One running helper process. */
|
|
6645
|
+
var Session = class Session {
|
|
6646
|
+
#child;
|
|
6647
|
+
#pending = /* @__PURE__ */ new Map();
|
|
6648
|
+
#nextId = 1;
|
|
6649
|
+
#buffer = "";
|
|
6650
|
+
#alive = true;
|
|
6651
|
+
#onReady;
|
|
6652
|
+
constructor(child) {
|
|
6653
|
+
this.#child = child;
|
|
6654
|
+
child.stdout?.setEncoding("utf8");
|
|
6655
|
+
child.stdout?.on("data", (chunk) => this.#receive(chunk));
|
|
6656
|
+
child.stdin?.on("error", () => {});
|
|
6657
|
+
child.on("error", () => this.#end("PowerShell could not be started"));
|
|
6658
|
+
child.on("close", () => this.#end("the PowerShell credential helper stopped"));
|
|
6659
|
+
}
|
|
6660
|
+
/** Starts a helper and waits until it is ready, or says why it cannot be. */
|
|
6661
|
+
static start(powershell, startupTimeoutMs) {
|
|
6662
|
+
const script = Buffer.from(HELPER_SCRIPT, "utf16le").toString("base64");
|
|
6663
|
+
const child = spawn(powershell, [
|
|
6664
|
+
"-NoLogo",
|
|
6665
|
+
"-NoProfile",
|
|
6666
|
+
"-NonInteractive",
|
|
6667
|
+
"-EncodedCommand",
|
|
6668
|
+
script
|
|
6669
|
+
], {
|
|
6670
|
+
stdio: [
|
|
6671
|
+
"pipe",
|
|
6672
|
+
"pipe",
|
|
6673
|
+
"ignore"
|
|
6674
|
+
],
|
|
6675
|
+
windowsHide: true
|
|
6676
|
+
});
|
|
6677
|
+
const session = new Session(child);
|
|
6678
|
+
return new Promise((resolve, reject) => {
|
|
6679
|
+
const timer = setTimeout(() => {
|
|
6680
|
+
session.close();
|
|
6681
|
+
reject(new PowerShellUnavailableError("PowerShell did not answer in time"));
|
|
6682
|
+
}, startupTimeoutMs);
|
|
6683
|
+
session.#onReady = (answer) => {
|
|
6684
|
+
clearTimeout(timer);
|
|
6685
|
+
if (answer.ready === true) {
|
|
6686
|
+
session.#idle();
|
|
6687
|
+
resolve(session);
|
|
6688
|
+
} else {
|
|
6689
|
+
session.close();
|
|
6690
|
+
reject(new PowerShellUnavailableError(answer.message || "PowerShell refused"));
|
|
6691
|
+
}
|
|
6692
|
+
};
|
|
6693
|
+
child.once("error", (error) => {
|
|
6694
|
+
clearTimeout(timer);
|
|
6695
|
+
reject(new PowerShellUnavailableError(error.message));
|
|
6696
|
+
});
|
|
6697
|
+
child.once("close", () => {
|
|
6698
|
+
clearTimeout(timer);
|
|
6699
|
+
reject(new PowerShellUnavailableError("PowerShell stopped before it was ready"));
|
|
6700
|
+
});
|
|
6701
|
+
});
|
|
6702
|
+
}
|
|
6703
|
+
get alive() {
|
|
6704
|
+
return this.#alive;
|
|
6705
|
+
}
|
|
6706
|
+
/** Stops the helper; its input closing also ends it if the kill fails. */
|
|
6707
|
+
close() {
|
|
6708
|
+
this.#alive = false;
|
|
6709
|
+
this.#child.stdin?.end();
|
|
6710
|
+
this.#child.kill();
|
|
6711
|
+
}
|
|
6712
|
+
/** Sends one request and waits for its answer (a failure of the Credential Manager is thrown). */
|
|
6713
|
+
request(fields, timeoutMs) {
|
|
6714
|
+
if (!this.#alive) return Promise.reject(/* @__PURE__ */ new Error("the PowerShell credential helper is not running"));
|
|
6715
|
+
const id = this.#nextId;
|
|
6716
|
+
this.#nextId += 1;
|
|
6717
|
+
return new Promise((resolve, reject) => {
|
|
6718
|
+
const timer = setTimeout(() => {
|
|
6719
|
+
this.#pending.delete(id);
|
|
6720
|
+
this.close();
|
|
6721
|
+
reject(/* @__PURE__ */ new Error("the PowerShell credential helper did not answer in time"));
|
|
6722
|
+
}, timeoutMs);
|
|
6723
|
+
this.#pending.set(id, {
|
|
6724
|
+
resolve,
|
|
6725
|
+
reject,
|
|
6726
|
+
timer
|
|
6727
|
+
});
|
|
6728
|
+
this.#busy();
|
|
6729
|
+
const line = JSON.stringify({
|
|
6730
|
+
id,
|
|
6731
|
+
op: fields.op,
|
|
6732
|
+
target: Buffer.from(fields.target, "utf8").toString("base64"),
|
|
6733
|
+
user: Buffer.from(fields.user ?? "", "utf8").toString("base64"),
|
|
6734
|
+
secret: fields.secret
|
|
6735
|
+
});
|
|
6736
|
+
this.#child.stdin?.write(`${line}\n`);
|
|
6737
|
+
});
|
|
6738
|
+
}
|
|
6739
|
+
#receive(chunk) {
|
|
6740
|
+
this.#buffer += chunk;
|
|
6741
|
+
for (let end = this.#buffer.indexOf("\n"); end >= 0; end = this.#buffer.indexOf("\n")) {
|
|
6742
|
+
const line = this.#buffer.slice(0, end).trim();
|
|
6743
|
+
this.#buffer = this.#buffer.slice(end + 1);
|
|
6744
|
+
if (line === "") continue;
|
|
6745
|
+
let answer;
|
|
6746
|
+
try {
|
|
6747
|
+
answer = JSON.parse(line);
|
|
6748
|
+
} catch {
|
|
6749
|
+
continue;
|
|
6750
|
+
}
|
|
6751
|
+
if (answer.ready !== void 0) this.#onReady?.(answer);
|
|
6752
|
+
else if (answer.id !== void 0) {
|
|
6753
|
+
const pending = this.#pending.get(answer.id);
|
|
6754
|
+
if (pending === void 0) continue;
|
|
6755
|
+
this.#pending.delete(answer.id);
|
|
6756
|
+
clearTimeout(pending.timer);
|
|
6757
|
+
pending.resolve(answer);
|
|
6758
|
+
if (this.#pending.size === 0) this.#idle();
|
|
6759
|
+
}
|
|
6760
|
+
}
|
|
6761
|
+
}
|
|
6762
|
+
#end(reason) {
|
|
6763
|
+
this.#alive = false;
|
|
6764
|
+
for (const pending of this.#pending.values()) {
|
|
6765
|
+
clearTimeout(pending.timer);
|
|
6766
|
+
pending.reject(new Error(reason));
|
|
6767
|
+
}
|
|
6768
|
+
this.#pending.clear();
|
|
6769
|
+
}
|
|
6770
|
+
/** While a request is in flight, Node must wait for the answer. */
|
|
6771
|
+
#busy() {
|
|
6772
|
+
for (const handle of this.#handles()) handle.ref?.();
|
|
6773
|
+
}
|
|
6774
|
+
/** With nothing in flight, the helper never keeps Node from exiting. */
|
|
6775
|
+
#idle() {
|
|
6776
|
+
for (const handle of this.#handles()) handle.unref?.();
|
|
6777
|
+
}
|
|
6778
|
+
#handles() {
|
|
6779
|
+
return [
|
|
6780
|
+
this.#child,
|
|
6781
|
+
this.#child.stdin,
|
|
6782
|
+
this.#child.stdout
|
|
6783
|
+
];
|
|
6784
|
+
}
|
|
6785
|
+
};
|
|
6786
|
+
const STARTUP_TIMEOUT_MS = 3e4;
|
|
6787
|
+
const REQUEST_TIMEOUT_MS = 3e4;
|
|
6788
|
+
/** `CredentialBackend` through a PowerShell helper, started on the first request. */
|
|
6789
|
+
var PowerShellCredentials = class PowerShellCredentials {
|
|
6790
|
+
#powershell;
|
|
6791
|
+
#session;
|
|
6792
|
+
constructor(powershell) {
|
|
6793
|
+
this.#powershell = powershell;
|
|
6794
|
+
}
|
|
6795
|
+
/**
|
|
6796
|
+
* Starts the helper now. Rejects with `PowerShellUnavailableError` when PowerShell is absent, in
|
|
6797
|
+
* constrained language mode, or otherwise unable to compile the helper.
|
|
6798
|
+
*/
|
|
6799
|
+
static async open(options = {}) {
|
|
6800
|
+
const powershell = options.powershell ?? windowsPowerShellPath();
|
|
6801
|
+
if (powershell === void 0) throw new PowerShellUnavailableError("Windows PowerShell was not found");
|
|
6802
|
+
const backend = new PowerShellCredentials(powershell);
|
|
6803
|
+
await backend.#ensure();
|
|
6804
|
+
return backend;
|
|
6805
|
+
}
|
|
6806
|
+
/** The running helper; a new one when the last stopped. */
|
|
6807
|
+
async #ensure() {
|
|
6808
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
6809
|
+
this.#session ??= Session.start(this.#powershell, STARTUP_TIMEOUT_MS).catch((error) => {
|
|
6810
|
+
this.#session = void 0;
|
|
6811
|
+
throw error;
|
|
6812
|
+
});
|
|
6813
|
+
const pending = this.#session;
|
|
6814
|
+
const session = await pending;
|
|
6815
|
+
if (session.alive) return session;
|
|
6816
|
+
if (this.#session === pending) this.#session = void 0;
|
|
6817
|
+
}
|
|
6818
|
+
throw new Error("the PowerShell credential helper keeps stopping");
|
|
6819
|
+
}
|
|
6820
|
+
async #ask(fields) {
|
|
6821
|
+
const answer = await (await this.#ensure()).request(fields, REQUEST_TIMEOUT_MS);
|
|
6822
|
+
if (answer.ok !== true) {
|
|
6823
|
+
const message = decode(answer.message) || "the Credential Manager refused";
|
|
6824
|
+
throw new Error(`Windows Credential Manager failed: ${message} (Windows error code ${answer.code ?? 0})`);
|
|
6825
|
+
}
|
|
6826
|
+
return answer;
|
|
6827
|
+
}
|
|
6828
|
+
async read(service, account) {
|
|
6829
|
+
const answer = await this.#ask({
|
|
6830
|
+
op: "read",
|
|
6831
|
+
target: `${account}.${service}`,
|
|
6832
|
+
user: account
|
|
6833
|
+
});
|
|
6834
|
+
if (answer.found !== true) return void 0;
|
|
6835
|
+
return Buffer.from(answer.secret ?? "", "base64").toString("utf16le");
|
|
6836
|
+
}
|
|
6837
|
+
async write(service, account, secret) {
|
|
6838
|
+
await this.#ask({
|
|
6839
|
+
op: "write",
|
|
6840
|
+
target: `${account}.${service}`,
|
|
6841
|
+
user: account,
|
|
6842
|
+
secret: Buffer.from(secret, "utf16le").toString("base64")
|
|
6843
|
+
});
|
|
6844
|
+
}
|
|
6845
|
+
async remove(service, account) {
|
|
6846
|
+
return (await this.#ask({
|
|
6847
|
+
op: "delete",
|
|
6848
|
+
target: `${account}.${service}`,
|
|
6849
|
+
user: account
|
|
6850
|
+
})).found === true;
|
|
6851
|
+
}
|
|
6852
|
+
async accounts(service) {
|
|
6853
|
+
return ((await this.#ask({
|
|
6854
|
+
op: "list",
|
|
6855
|
+
target: service
|
|
6856
|
+
})).users ?? []).map(decode);
|
|
6857
|
+
}
|
|
6858
|
+
};
|
|
6408
6859
|
//#endregion
|
|
6409
6860
|
//#region ../../packages/adapters-git/dist/node-key-store.js
|
|
6410
6861
|
/**
|
|
@@ -6467,6 +6918,78 @@ function explainKeychainError(error, platform = process.platform) {
|
|
|
6467
6918
|
if (platform !== "linux" || !/secret.?service|d-?bus|platform secure storage/i.test(message)) return error;
|
|
6468
6919
|
return new Error(`the Secret Service of this Linux session could not be used: start one and unlock its default keyring (GNOME Keyring, KWallet or KeePassXC; on a machine without a desktop, gnome-keyring-daemon --unlock in a dbus-run-session), then run the command again. The system said: ${message}`, { cause: error });
|
|
6469
6920
|
}
|
|
6921
|
+
/** What Windows says when it refuses a file under Smart App Control or an application control policy. */
|
|
6922
|
+
const BLOCKED_BY_POLICY = /application control|blocked this file|smart app control|signing level|code integrity|contr.le d.application|bloqu. ce fichier|error 4551|0x800711c7/i;
|
|
6923
|
+
/** The message of `error` and of the errors under its `cause`, outermost first. */
|
|
6924
|
+
function messageChain(error) {
|
|
6925
|
+
const messages = [];
|
|
6926
|
+
let current = error;
|
|
6927
|
+
for (let depth = 0; depth < 20 && current !== void 0 && current !== null; depth += 1) {
|
|
6928
|
+
messages.push(current instanceof Error ? current.message : String(current));
|
|
6929
|
+
current = current instanceof Error ? current.cause : void 0;
|
|
6930
|
+
}
|
|
6931
|
+
return messages;
|
|
6932
|
+
}
|
|
6933
|
+
/**
|
|
6934
|
+
* The error for a keychain that cannot be reached at all: `native` is why `@napi-rs/keyring` did
|
|
6935
|
+
* not load and, on Windows, `powershell` why the PowerShell helper could not be used. Says what
|
|
6936
|
+
* blocks, in plain words: the generic "npm has a bug" of the module's loader never stands alone,
|
|
6937
|
+
* and a Windows policy blocking the module is named, with the file.
|
|
6938
|
+
*/
|
|
6939
|
+
function unavailableKeychainError(native, powershell) {
|
|
6940
|
+
const real = messageChain(native).filter((message) => !/cannot find native binding|npm has a bug/i.test(message));
|
|
6941
|
+
const blocked = real.find((message) => BLOCKED_BY_POLICY.test(message));
|
|
6942
|
+
const file = blocked === void 0 ? void 0 : /[A-Za-z]:\\[^\r\n"']*?\.node/.exec(blocked)?.[0];
|
|
6943
|
+
const viaPowerShell = powershell === void 0 ? "" : ` The keys could not be reached through Windows PowerShell either (${messageChain(powershell)[0]}).`;
|
|
6944
|
+
if (blocked !== void 0) {
|
|
6945
|
+
const said = blocked.split(/\r?\n/).find((line) => line.trim() !== "") ?? blocked;
|
|
6946
|
+
return new Error(`Windows blocked the system keychain module${file === void 0 ? "" : ` (${file})`}: Smart App Control or an application control policy refuses this unsigned file ("${said.trim()}").${viaPowerShell} Turn off Smart App Control (Windows Security, App & browser control) or allow this file in your application control policy, make sure Windows PowerShell can run in full language mode, then run the command again.`, { cause: native });
|
|
6947
|
+
}
|
|
6948
|
+
const why = real.length > 0 ? real.join("; ") : "Node gave no further reason";
|
|
6949
|
+
return new Error(`the system keychain module could not be loaded: ${why}.${viaPowerShell}`, { cause: native });
|
|
6950
|
+
}
|
|
6951
|
+
/** The keychain through `@napi-rs/keyring`. */
|
|
6952
|
+
async function nativeBackend() {
|
|
6953
|
+
const { AsyncEntry, findCredentialsAsync } = await load().catch((error) => {
|
|
6954
|
+
throw unavailableKeychainError(error);
|
|
6955
|
+
});
|
|
6956
|
+
const entry = (service, account) => new AsyncEntry(service, account, KEYCHAIN_ENTRY_OPTIONS);
|
|
6957
|
+
return {
|
|
6958
|
+
read: async (service, account) => await entry(service, account).getPassword() ?? void 0,
|
|
6959
|
+
write: (service, account, secret) => entry(service, account).setPassword(secret),
|
|
6960
|
+
remove: (service, account) => entry(service, account).deleteCredential(),
|
|
6961
|
+
accounts: async (service) => (await findCredentialsAsync(service)).map((found) => found.account)
|
|
6962
|
+
};
|
|
6963
|
+
}
|
|
6964
|
+
let system;
|
|
6965
|
+
/**
|
|
6966
|
+
* The system keychain of this machine. On Windows, the PowerShell helper first (no native module
|
|
6967
|
+
* to load, which Smart App Control may refuse), then `@napi-rs/keyring` when PowerShell cannot be
|
|
6968
|
+
* used; elsewhere `@napi-rs/keyring`. Chosen once per process, kept once it works.
|
|
6969
|
+
*/
|
|
6970
|
+
function systemCredentials() {
|
|
6971
|
+
system ??= (async () => {
|
|
6972
|
+
let powershell;
|
|
6973
|
+
if (process.platform === "win32") try {
|
|
6974
|
+
return await PowerShellCredentials.open();
|
|
6975
|
+
} catch (error) {
|
|
6976
|
+
powershell = error;
|
|
6977
|
+
}
|
|
6978
|
+
try {
|
|
6979
|
+
return await nativeBackend();
|
|
6980
|
+
} catch (error) {
|
|
6981
|
+
throw powershell === void 0 ? error : unavailableKeychainError(nativeCause(error), powershell);
|
|
6982
|
+
}
|
|
6983
|
+
})().catch((error) => {
|
|
6984
|
+
system = void 0;
|
|
6985
|
+
throw error;
|
|
6986
|
+
});
|
|
6987
|
+
return system;
|
|
6988
|
+
}
|
|
6989
|
+
/** The error `@napi-rs/keyring` failed with, under the explained one `nativeBackend` throws. */
|
|
6990
|
+
function nativeCause(error) {
|
|
6991
|
+
return error instanceof Error && error.cause !== void 0 ? error.cause : error;
|
|
6992
|
+
}
|
|
6470
6993
|
/** `operation`, its failure explained by `explainKeychainError`. */
|
|
6471
6994
|
async function explained(operation) {
|
|
6472
6995
|
try {
|
|
@@ -6477,8 +7000,9 @@ async function explained(operation) {
|
|
|
6477
7000
|
}
|
|
6478
7001
|
/**
|
|
6479
7002
|
* `KeyStore` in the system keychain (Windows Credential Manager, macOS Keychain, the Secret
|
|
6480
|
-
* Service on Linux)
|
|
6481
|
-
*
|
|
7003
|
+
* Service on Linux): through a PowerShell helper on Windows (`systemCredentials`) and
|
|
7004
|
+
* `@napi-rs/keyring` elsewhere, or when PowerShell cannot be used. Tests pass their own service
|
|
7005
|
+
* name and delete their entries afterwards: the machine's real entries are never touched.
|
|
6482
7006
|
*/
|
|
6483
7007
|
var NodeKeyStore = class {
|
|
6484
7008
|
service;
|
|
@@ -6491,11 +7015,13 @@ var NodeKeyStore = class {
|
|
|
6491
7015
|
* answering empty under concurrent access: elsewhere, none (no wait added to a first `init`).
|
|
6492
7016
|
*/
|
|
6493
7017
|
settleDelays;
|
|
7018
|
+
#engine;
|
|
6494
7019
|
constructor(options = {}) {
|
|
6495
7020
|
this.service = options.service ?? "agentplugged";
|
|
6496
7021
|
this.account = options.account ?? "machine";
|
|
6497
7022
|
this.humanAccount = options.humanAccount ?? "human";
|
|
6498
7023
|
this.presenceAccount = options.presenceAccount ?? "human-presence";
|
|
7024
|
+
this.#engine = options.engine ?? "system";
|
|
6499
7025
|
this.settleDelays = options.settleDelays ?? (process.platform === "win32" ? KEYCHAIN_SETTLE_DELAYS_MS : []);
|
|
6500
7026
|
}
|
|
6501
7027
|
/** Waits `settleDelays[attempt]`; false once they are all spent. */
|
|
@@ -6505,21 +7031,17 @@ var NodeKeyStore = class {
|
|
|
6505
7031
|
await setTimeout$1(delay);
|
|
6506
7032
|
return true;
|
|
6507
7033
|
}
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
const { AsyncEntry } = await load();
|
|
6511
|
-
return new AsyncEntry(this.service, account, KEYCHAIN_ENTRY_OPTIONS);
|
|
7034
|
+
#backend() {
|
|
7035
|
+
return this.#engine === "native" ? nativeBackend() : systemCredentials();
|
|
6512
7036
|
}
|
|
6513
7037
|
#read(account) {
|
|
6514
|
-
return explained(async () =>
|
|
6515
|
-
return await (await this.#entry(account)).getPassword() ?? void 0;
|
|
6516
|
-
});
|
|
7038
|
+
return explained(async () => (await this.#backend()).read(this.service, account));
|
|
6517
7039
|
}
|
|
6518
7040
|
/** A full keychain gives `KEYCHAIN_FULL`; any other failure is thrown, explained. */
|
|
6519
7041
|
async #write(account, value) {
|
|
6520
|
-
const
|
|
7042
|
+
const backend = await explained(() => this.#backend());
|
|
6521
7043
|
try {
|
|
6522
|
-
await
|
|
7044
|
+
await backend.write(this.service, account, value);
|
|
6523
7045
|
} catch (error) {
|
|
6524
7046
|
if (isKeychainFullError(error)) throw keychainFull(error instanceof Error ? error.message : String(error));
|
|
6525
7047
|
throw explainKeychainError(error);
|
|
@@ -6554,7 +7076,7 @@ var NodeKeyStore = class {
|
|
|
6554
7076
|
}
|
|
6555
7077
|
/** Deletes the machine key's entry; true when there was one. */
|
|
6556
7078
|
deleteMachineSecret() {
|
|
6557
|
-
return explained(async () => (await this.#
|
|
7079
|
+
return explained(async () => (await this.#backend()).remove(this.service, this.account));
|
|
6558
7080
|
}
|
|
6559
7081
|
/**
|
|
6560
7082
|
* Deletes the entries of this service, product keys included (tests: a service of their own).
|
|
@@ -6564,13 +7086,14 @@ var NodeKeyStore = class {
|
|
|
6564
7086
|
async deleteAll() {
|
|
6565
7087
|
if (this.service === "agentplugged") throw new Error(`deleteAll refuses the real keychain service ${KEYCHAIN_SERVICE}`);
|
|
6566
7088
|
let deleted = false;
|
|
6567
|
-
const
|
|
7089
|
+
const backend = await explained(() => this.#backend());
|
|
7090
|
+
const products = await backend.accounts(this.service).then((found) => found.filter((name) => name.startsWith(PRODUCT_ACCOUNT))).catch(() => []);
|
|
6568
7091
|
for (const account of [
|
|
6569
7092
|
this.account,
|
|
6570
7093
|
this.humanAccount,
|
|
6571
7094
|
this.presenceAccount,
|
|
6572
7095
|
...products
|
|
6573
|
-
]) deleted = await (
|
|
7096
|
+
]) deleted = await backend.remove(this.service, account) || deleted;
|
|
6574
7097
|
return deleted;
|
|
6575
7098
|
}
|
|
6576
7099
|
};
|
|
@@ -6936,7 +7459,7 @@ var NodeRootPinStore = class {
|
|
|
6936
7459
|
} finally {
|
|
6937
7460
|
await handle.close();
|
|
6938
7461
|
}
|
|
6939
|
-
await
|
|
7462
|
+
await renameWithRetry(temporary, target);
|
|
6940
7463
|
await syncFolder(folder);
|
|
6941
7464
|
this.#onFlush?.("folder");
|
|
6942
7465
|
} catch (error) {
|
|
@@ -7208,6 +7731,7 @@ const en = {
|
|
|
7208
7731
|
"error.unknown_command": "Unknown command \"{command}\".",
|
|
7209
7732
|
"error.invalid_arguments": "Invalid arguments: {reason}",
|
|
7210
7733
|
"error.unexpected": "Unexpected error: {reason}",
|
|
7734
|
+
"error.file_in_use": "{path} is held open by another program (your AI tool, your editor or your antivirus): nothing was changed. Close it or wait a moment, then run the command again.",
|
|
7211
7735
|
"error.engine_version_mismatch": "{path} pins engine {pinned}, and this engine is {engine_version}: nothing was written. Run `npx agentplugged@{pinned} {command}`, or `npx agentplugged init --upgrade-engine` to pin {engine_version}, or add `--engine-any` to run anyway.",
|
|
7212
7736
|
"error.upgrade_required": "{path} uses format {format_version}, newer than this engine knows (format {supported}, engine {engine_version}): nothing was written. Run `npx agentplugged@{version} {command}`.",
|
|
7213
7737
|
"cli.warning.engine_any": "Warning: {path} pins engine {pinned}, but engine {engine_version} runs anyway (--engine-any). Run `npx agentplugged init --upgrade-engine` to pin it.",
|
|
@@ -9127,6 +9651,7 @@ const fr = {
|
|
|
9127
9651
|
"error.unknown_command": "Commande inconnue « {command} ».",
|
|
9128
9652
|
"error.invalid_arguments": "Arguments invalides : {reason}",
|
|
9129
9653
|
"error.unexpected": "Erreur inattendue : {reason}",
|
|
9654
|
+
"error.file_in_use": "{path} est tenu ouvert par un autre programme (ton outil d'IA, ton éditeur ou ton antivirus) : rien n'a été modifié. Ferme-le ou attends un instant, puis relance la commande.",
|
|
9130
9655
|
"error.engine_version_mismatch": "{path} épingle le moteur {pinned}, et ce moteur est en {engine_version} : rien n'a été écrit. Lance `npx agentplugged@{pinned} {command}`, ou `npx agentplugged init --upgrade-engine` pour épingler {engine_version}, ou ajoute `--engine-any` pour passer outre.",
|
|
9131
9656
|
"error.upgrade_required": "{path} utilise le format {format_version}, plus récent que celui que connaît ce moteur (format {supported}, moteur {engine_version}) : rien n'a été écrit. Lance `npx agentplugged@{version} {command}`.",
|
|
9132
9657
|
"cli.warning.engine_any": "Attention : {path} épingle le moteur {pinned}, mais le moteur {engine_version} s'exécute quand même (--engine-any). Lance `npx agentplugged init --upgrade-engine` pour l'épingler.",
|
package/dist/method/doctor.yaml
CHANGED
|
@@ -454,10 +454,12 @@ checks:
|
|
|
454
454
|
- steps:
|
|
455
455
|
en:
|
|
456
456
|
- "On Linux, install and unlock a secret service (GNOME Keyring or KWallet), then run: npx agentplugged doctor"
|
|
457
|
-
- "On Windows or
|
|
457
|
+
- "On Windows, if the message says Smart App Control or an application control policy blocked a file: turn off Smart App Control (Windows Security, App & browser control) or allow that file in your policy, check that Windows PowerShell is not in constrained language mode, then run: npx agentplugged doctor"
|
|
458
|
+
- "On Windows or macOS otherwise, the system keychain is part of the system: restart the session and try again."
|
|
458
459
|
fr:
|
|
459
460
|
- "Sous Linux, installe et déverrouille un service de secrets (GNOME Keyring ou KWallet), puis lance : npx agentplugged doctor"
|
|
460
|
-
- "Sous Windows ou
|
|
461
|
+
- "Sous Windows, si le message dit que Smart App Control ou une stratégie de contrôle des applications a bloqué un fichier : désactive Smart App Control (Sécurité Windows, Contrôle des applications et du navigateur) ou autorise ce fichier, vérifie que Windows PowerShell n'est pas en mode de langage restreint, puis lance : npx agentplugged doctor"
|
|
462
|
+
- "Sous Windows ou macOS sinon, le trousseau fait partie du système : redémarre la session et réessaie."
|
|
461
463
|
|
|
462
464
|
- id: presence
|
|
463
465
|
group: keys
|
|
@@ -1027,3 +1029,17 @@ signatures:
|
|
|
1027
1029
|
en: "A write failed for lack of room"
|
|
1028
1030
|
fr: "Une écriture a échoué faute de place"
|
|
1029
1031
|
read: [disk.space]
|
|
1032
|
+
- id: keychain-blocked
|
|
1033
|
+
when:
|
|
1034
|
+
output:
|
|
1035
|
+
- "smart app control"
|
|
1036
|
+
- "application control policy"
|
|
1037
|
+
- "blocked the system keychain module"
|
|
1038
|
+
- "stratégie de contrôle d'application"
|
|
1039
|
+
say:
|
|
1040
|
+
en: "Windows refused to load the keychain's module (Smart App Control or an application control policy)"
|
|
1041
|
+
fr: "Windows a refusé de charger le module du trousseau (Smart App Control ou une stratégie de contrôle des applications)"
|
|
1042
|
+
read: [keychain]
|
|
1043
|
+
assumed:
|
|
1044
|
+
en: "The message names the blocked file; whether turning off Smart App Control or adding an allow rule is right for this machine is your call, I only checked that the keychain does not answer"
|
|
1045
|
+
fr: "Le message nomme le fichier bloqué ; désactiver Smart App Control ou ajouter une règle d'autorisation, c'est à toi de décider pour cette machine, je n'ai vérifié que le fait que le trousseau ne répond pas"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentplugged",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Install the AgentPlugged method in a repository and make its agents callable from Claude Code, Codex, Antigravity/Gemini CLI and Cursor.",
|
|
5
5
|
"releaseSummary": "The engine updates itself: your session moves to a newer version between two calls, with nothing to reconnect.",
|
|
6
6
|
"license": "FSL-1.1-MIT",
|
|
@@ -47,14 +47,14 @@
|
|
|
47
47
|
"koffi": "~3.3.2"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@agentplugged/adapters-git": "1.0.
|
|
51
|
-
"@agentplugged/adapters-tools": "1.0.
|
|
52
|
-
"@agentplugged/core": "1.0.
|
|
53
|
-
"@agentplugged/crypto": "1.0.
|
|
54
|
-
"@agentplugged/i18n": "1.0.
|
|
55
|
-
"@agentplugged/mcp": "1.0.
|
|
50
|
+
"@agentplugged/adapters-git": "1.0.2",
|
|
51
|
+
"@agentplugged/adapters-tools": "1.0.2",
|
|
52
|
+
"@agentplugged/core": "1.0.2",
|
|
53
|
+
"@agentplugged/crypto": "1.0.2",
|
|
54
|
+
"@agentplugged/i18n": "1.0.2",
|
|
55
|
+
"@agentplugged/mcp": "1.0.2",
|
|
56
56
|
"@agentplugged/method": "0.0.0",
|
|
57
|
-
"@agentplugged/protocol": "1.0.
|
|
57
|
+
"@agentplugged/protocol": "1.0.2",
|
|
58
58
|
"@biomejs/biome": "~2.5.15",
|
|
59
59
|
"@modelcontextprotocol/client": "~2.3.0",
|
|
60
60
|
"@types/node": "^24.19.1",
|