lody 0.67.2 → 0.68.0
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/index.js
CHANGED
|
@@ -4188,7 +4188,7 @@ let __tla = Promise.all([
|
|
|
4188
4188
|
}
|
|
4189
4189
|
}
|
|
4190
4190
|
const name$1 = "lody";
|
|
4191
|
-
const version$3 = "0.
|
|
4191
|
+
const version$3 = "0.68.0";
|
|
4192
4192
|
const description$1 = "Lody Agent CLI tool for managing remote command execution";
|
|
4193
4193
|
const type$2 = "module";
|
|
4194
4194
|
const main$4 = "dist/index.js";
|
|
@@ -4534,6 +4534,274 @@ let __tla = Promise.all([
|
|
|
4534
4534
|
return void 0;
|
|
4535
4535
|
};
|
|
4536
4536
|
const isBuiltinAgentType = (agentType) => agentType === "claude" || agentType === "codex";
|
|
4537
|
+
const CODEX_STATIC_MODES = [
|
|
4538
|
+
{
|
|
4539
|
+
id: "read-only",
|
|
4540
|
+
name: "Read-only",
|
|
4541
|
+
description: "Requires approval to edit files and run commands."
|
|
4542
|
+
},
|
|
4543
|
+
{
|
|
4544
|
+
id: "agent",
|
|
4545
|
+
name: "Agent",
|
|
4546
|
+
description: "Read and edit files, and run commands."
|
|
4547
|
+
},
|
|
4548
|
+
{
|
|
4549
|
+
id: "agent-full-access",
|
|
4550
|
+
name: "Agent (full access)",
|
|
4551
|
+
description: "Codex can edit files outside this workspace and run commands with network access. Exercise caution when using."
|
|
4552
|
+
}
|
|
4553
|
+
];
|
|
4554
|
+
const CODEX_STATIC_MODELS = [
|
|
4555
|
+
{
|
|
4556
|
+
modelId: "gpt-5.5",
|
|
4557
|
+
name: "gpt-5.5",
|
|
4558
|
+
description: "Latest frontier Codex model"
|
|
4559
|
+
},
|
|
4560
|
+
{
|
|
4561
|
+
modelId: "gpt-5.4",
|
|
4562
|
+
name: "gpt-5.4",
|
|
4563
|
+
description: "Frontier Codex model"
|
|
4564
|
+
},
|
|
4565
|
+
{
|
|
4566
|
+
modelId: "gpt-5.4-mini",
|
|
4567
|
+
name: "gpt-5.4-mini",
|
|
4568
|
+
description: "Smaller, faster Codex model"
|
|
4569
|
+
}
|
|
4570
|
+
];
|
|
4571
|
+
const CODEX_REASONING_OPTIONS = [
|
|
4572
|
+
{
|
|
4573
|
+
value: "low",
|
|
4574
|
+
name: "low",
|
|
4575
|
+
description: "Fastest responses"
|
|
4576
|
+
},
|
|
4577
|
+
{
|
|
4578
|
+
value: "medium",
|
|
4579
|
+
name: "medium",
|
|
4580
|
+
description: "Balanced reasoning"
|
|
4581
|
+
},
|
|
4582
|
+
{
|
|
4583
|
+
value: "high",
|
|
4584
|
+
name: "high",
|
|
4585
|
+
description: "More reasoning for difficult tasks"
|
|
4586
|
+
},
|
|
4587
|
+
{
|
|
4588
|
+
value: "xhigh",
|
|
4589
|
+
name: "xhigh",
|
|
4590
|
+
description: "Extra reasoning for complex tasks"
|
|
4591
|
+
}
|
|
4592
|
+
];
|
|
4593
|
+
const CODEX_STATIC_CONFIG_OPTIONS = [
|
|
4594
|
+
{
|
|
4595
|
+
id: "mode",
|
|
4596
|
+
name: "Mode",
|
|
4597
|
+
description: "Approval and sandboxing preset for the session",
|
|
4598
|
+
category: "mode",
|
|
4599
|
+
type: "select",
|
|
4600
|
+
currentValue: "agent",
|
|
4601
|
+
options: CODEX_STATIC_MODES.map((mode2) => ({
|
|
4602
|
+
value: mode2.id,
|
|
4603
|
+
name: mode2.name,
|
|
4604
|
+
description: mode2.description ?? void 0
|
|
4605
|
+
}))
|
|
4606
|
+
},
|
|
4607
|
+
{
|
|
4608
|
+
id: "model",
|
|
4609
|
+
name: "Model",
|
|
4610
|
+
description: "Model Codex uses for the session",
|
|
4611
|
+
category: "model",
|
|
4612
|
+
type: "select",
|
|
4613
|
+
currentValue: "gpt-5.5",
|
|
4614
|
+
options: CODEX_STATIC_MODELS.map((model) => ({
|
|
4615
|
+
value: model.modelId,
|
|
4616
|
+
name: model.name,
|
|
4617
|
+
description: model.description ?? void 0
|
|
4618
|
+
}))
|
|
4619
|
+
},
|
|
4620
|
+
{
|
|
4621
|
+
id: "reasoning_effort",
|
|
4622
|
+
name: "Reasoning effort",
|
|
4623
|
+
description: "How much reasoning effort the model should use",
|
|
4624
|
+
category: "thought_level",
|
|
4625
|
+
type: "select",
|
|
4626
|
+
currentValue: "medium",
|
|
4627
|
+
options: CODEX_REASONING_OPTIONS
|
|
4628
|
+
},
|
|
4629
|
+
{
|
|
4630
|
+
id: "fast-mode",
|
|
4631
|
+
name: "Fast mode",
|
|
4632
|
+
description: "1.5x speed, increased usage",
|
|
4633
|
+
category: "fast-mode",
|
|
4634
|
+
type: "select",
|
|
4635
|
+
currentValue: "off",
|
|
4636
|
+
options: [
|
|
4637
|
+
{
|
|
4638
|
+
value: "off",
|
|
4639
|
+
name: "Off",
|
|
4640
|
+
description: "Default speed, normal usage"
|
|
4641
|
+
},
|
|
4642
|
+
{
|
|
4643
|
+
value: "on",
|
|
4644
|
+
name: "On",
|
|
4645
|
+
description: "1.5x speed, increased usage"
|
|
4646
|
+
}
|
|
4647
|
+
]
|
|
4648
|
+
},
|
|
4649
|
+
{
|
|
4650
|
+
id: "plan-mode",
|
|
4651
|
+
name: "Plan mode",
|
|
4652
|
+
description: "Plan without modifying files; switch off to implement the approved plan",
|
|
4653
|
+
category: "plan-mode",
|
|
4654
|
+
type: "select",
|
|
4655
|
+
currentValue: "off",
|
|
4656
|
+
options: [
|
|
4657
|
+
{
|
|
4658
|
+
value: "off",
|
|
4659
|
+
name: "Off",
|
|
4660
|
+
description: "Implement changes normally"
|
|
4661
|
+
},
|
|
4662
|
+
{
|
|
4663
|
+
value: "on",
|
|
4664
|
+
name: "On",
|
|
4665
|
+
description: "Plan without modifying files; switch off to implement the approved plan"
|
|
4666
|
+
}
|
|
4667
|
+
]
|
|
4668
|
+
}
|
|
4669
|
+
];
|
|
4670
|
+
const CLAUDE_STATIC_MODES = [
|
|
4671
|
+
{
|
|
4672
|
+
id: "auto",
|
|
4673
|
+
name: "Auto",
|
|
4674
|
+
description: "Use a model classifier to approve/deny permission prompts"
|
|
4675
|
+
},
|
|
4676
|
+
{
|
|
4677
|
+
id: "default",
|
|
4678
|
+
name: "Default",
|
|
4679
|
+
description: "Standard behavior, prompts for dangerous operations"
|
|
4680
|
+
},
|
|
4681
|
+
{
|
|
4682
|
+
id: "acceptEdits",
|
|
4683
|
+
name: "Accept Edits",
|
|
4684
|
+
description: "Auto-accept file edit operations"
|
|
4685
|
+
},
|
|
4686
|
+
{
|
|
4687
|
+
id: "plan",
|
|
4688
|
+
name: "Plan Mode",
|
|
4689
|
+
description: "Planning mode, no actual tool execution"
|
|
4690
|
+
},
|
|
4691
|
+
{
|
|
4692
|
+
id: "dontAsk",
|
|
4693
|
+
name: "Don't Ask",
|
|
4694
|
+
description: "Don't prompt for permissions, deny if not pre-approved"
|
|
4695
|
+
}
|
|
4696
|
+
];
|
|
4697
|
+
const CLAUDE_STATIC_MODELS = [
|
|
4698
|
+
{
|
|
4699
|
+
modelId: "default",
|
|
4700
|
+
name: "Default",
|
|
4701
|
+
description: "Claude Code default model"
|
|
4702
|
+
},
|
|
4703
|
+
{
|
|
4704
|
+
modelId: "opus",
|
|
4705
|
+
name: "Opus",
|
|
4706
|
+
description: "Claude Opus"
|
|
4707
|
+
},
|
|
4708
|
+
{
|
|
4709
|
+
modelId: "sonnet",
|
|
4710
|
+
name: "Sonnet",
|
|
4711
|
+
description: "Claude Sonnet"
|
|
4712
|
+
},
|
|
4713
|
+
{
|
|
4714
|
+
modelId: "haiku",
|
|
4715
|
+
name: "Haiku",
|
|
4716
|
+
description: "Claude Haiku"
|
|
4717
|
+
}
|
|
4718
|
+
];
|
|
4719
|
+
const CLAUDE_STATIC_CONFIG_OPTIONS = [
|
|
4720
|
+
{
|
|
4721
|
+
id: "mode",
|
|
4722
|
+
name: "Mode",
|
|
4723
|
+
description: "Session permission mode",
|
|
4724
|
+
category: "mode",
|
|
4725
|
+
type: "select",
|
|
4726
|
+
currentValue: "default",
|
|
4727
|
+
options: CLAUDE_STATIC_MODES.map((mode2) => ({
|
|
4728
|
+
value: mode2.id,
|
|
4729
|
+
name: mode2.name,
|
|
4730
|
+
description: mode2.description ?? void 0
|
|
4731
|
+
}))
|
|
4732
|
+
},
|
|
4733
|
+
{
|
|
4734
|
+
id: "model",
|
|
4735
|
+
name: "Model",
|
|
4736
|
+
description: "AI model to use",
|
|
4737
|
+
category: "model",
|
|
4738
|
+
type: "select",
|
|
4739
|
+
currentValue: "default",
|
|
4740
|
+
options: CLAUDE_STATIC_MODELS.map((model) => ({
|
|
4741
|
+
value: model.modelId,
|
|
4742
|
+
name: model.name,
|
|
4743
|
+
description: model.description ?? void 0
|
|
4744
|
+
}))
|
|
4745
|
+
},
|
|
4746
|
+
{
|
|
4747
|
+
id: "effort",
|
|
4748
|
+
name: "Effort",
|
|
4749
|
+
description: "Available effort levels for this model",
|
|
4750
|
+
category: "thought_level",
|
|
4751
|
+
type: "select",
|
|
4752
|
+
currentValue: "default",
|
|
4753
|
+
options: [
|
|
4754
|
+
{
|
|
4755
|
+
value: "default",
|
|
4756
|
+
name: "Default"
|
|
4757
|
+
},
|
|
4758
|
+
{
|
|
4759
|
+
value: "low",
|
|
4760
|
+
name: "Low"
|
|
4761
|
+
},
|
|
4762
|
+
{
|
|
4763
|
+
value: "medium",
|
|
4764
|
+
name: "Medium"
|
|
4765
|
+
},
|
|
4766
|
+
{
|
|
4767
|
+
value: "high",
|
|
4768
|
+
name: "High"
|
|
4769
|
+
}
|
|
4770
|
+
]
|
|
4771
|
+
}
|
|
4772
|
+
];
|
|
4773
|
+
const cloneConfigOption = (option2) => ({
|
|
4774
|
+
...option2,
|
|
4775
|
+
options: option2.options.map((value) => ({
|
|
4776
|
+
...value
|
|
4777
|
+
}))
|
|
4778
|
+
});
|
|
4779
|
+
const cloneStaticCapabilities = (capabilities) => ({
|
|
4780
|
+
modes: capabilities.modes.map((mode2) => ({
|
|
4781
|
+
...mode2
|
|
4782
|
+
})),
|
|
4783
|
+
models: capabilities.models.map((model) => ({
|
|
4784
|
+
...model
|
|
4785
|
+
})),
|
|
4786
|
+
configOptions: capabilities.configOptions.map(cloneConfigOption)
|
|
4787
|
+
});
|
|
4788
|
+
const getStaticBuiltinAcpCapabilities = (cliType, agentType, runtimeOverrides) => {
|
|
4789
|
+
if (cliType !== "builtin" || !agentType || !isBuiltinAgentType(agentType)) {
|
|
4790
|
+
return void 0;
|
|
4791
|
+
}
|
|
4792
|
+
if (hasBuiltinRuntimeOverrideValues(runtimeOverrides)) {
|
|
4793
|
+
return void 0;
|
|
4794
|
+
}
|
|
4795
|
+
return cloneStaticCapabilities(agentType === "claude" ? {
|
|
4796
|
+
modes: CLAUDE_STATIC_MODES,
|
|
4797
|
+
models: CLAUDE_STATIC_MODELS,
|
|
4798
|
+
configOptions: CLAUDE_STATIC_CONFIG_OPTIONS
|
|
4799
|
+
} : {
|
|
4800
|
+
modes: CODEX_STATIC_MODES,
|
|
4801
|
+
models: CODEX_STATIC_MODELS,
|
|
4802
|
+
configOptions: CODEX_STATIC_CONFIG_OPTIONS
|
|
4803
|
+
});
|
|
4804
|
+
};
|
|
4537
4805
|
const leastPermissionModeRank = (value, name2) => {
|
|
4538
4806
|
const normalized = `${value} ${name2}`.toLowerCase().replace(/[\s_-]+/g, "-");
|
|
4539
4807
|
if (normalized.includes("read-only") || normalized.includes("readonly")) return 0;
|
|
@@ -12100,12 +12368,12 @@ Task description:
|
|
|
12100
12368
|
{
|
|
12101
12369
|
id: "auggie",
|
|
12102
12370
|
name: "Auggie CLI",
|
|
12103
|
-
version: "0.
|
|
12371
|
+
version: "0.32.0",
|
|
12104
12372
|
description: "Augment Code's powerful software agent, backed by industry-leading context engine",
|
|
12105
12373
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/auggie.svg",
|
|
12106
12374
|
distribution: {
|
|
12107
12375
|
npx: {
|
|
12108
|
-
package: "@augmentcode/auggie@0.
|
|
12376
|
+
package: "@augmentcode/auggie@0.32.0",
|
|
12109
12377
|
args: [
|
|
12110
12378
|
"--acp"
|
|
12111
12379
|
],
|
|
@@ -12130,12 +12398,12 @@ Task description:
|
|
|
12130
12398
|
{
|
|
12131
12399
|
id: "cline",
|
|
12132
12400
|
name: "Cline",
|
|
12133
|
-
version: "3.0.
|
|
12401
|
+
version: "3.0.38",
|
|
12134
12402
|
description: "Autonomous coding agent CLI - capable of creating/editing files, running commands, using the browser, and more",
|
|
12135
12403
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/cline.svg",
|
|
12136
12404
|
distribution: {
|
|
12137
12405
|
npx: {
|
|
12138
|
-
package: "cline@3.0.
|
|
12406
|
+
package: "cline@3.0.38",
|
|
12139
12407
|
args: [
|
|
12140
12408
|
"--acp"
|
|
12141
12409
|
]
|
|
@@ -12292,7 +12560,7 @@ Task description:
|
|
|
12292
12560
|
{
|
|
12293
12561
|
id: "cursor",
|
|
12294
12562
|
name: "Cursor",
|
|
12295
|
-
version: "2026.
|
|
12563
|
+
version: "2026.07.01",
|
|
12296
12564
|
description: "Cursor's coding agent",
|
|
12297
12565
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/cursor.svg",
|
|
12298
12566
|
distribution: {
|
|
@@ -12322,48 +12590,48 @@ Task description:
|
|
|
12322
12590
|
{
|
|
12323
12591
|
id: "devin",
|
|
12324
12592
|
name: "Devin",
|
|
12325
|
-
version: "
|
|
12593
|
+
version: "3000.1.27",
|
|
12326
12594
|
description: "Devin CLI coding agent by Cognition",
|
|
12327
12595
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/devin.svg",
|
|
12328
12596
|
distribution: {
|
|
12329
12597
|
binary: {
|
|
12330
12598
|
"darwin-aarch64": {
|
|
12331
|
-
archive: "https://static.devin.ai/cli/
|
|
12599
|
+
archive: "https://static.devin.ai/cli/3000.1.27/devin-3000.1.27-aarch64-apple-darwin.tar.gz",
|
|
12332
12600
|
cmd: "./bin/devin",
|
|
12333
12601
|
args: [
|
|
12334
12602
|
"acp"
|
|
12335
12603
|
]
|
|
12336
12604
|
},
|
|
12337
12605
|
"darwin-x86_64": {
|
|
12338
|
-
archive: "https://static.devin.ai/cli/
|
|
12606
|
+
archive: "https://static.devin.ai/cli/3000.1.27/devin-3000.1.27-x86_64-apple-darwin.tar.gz",
|
|
12339
12607
|
cmd: "./bin/devin",
|
|
12340
12608
|
args: [
|
|
12341
12609
|
"acp"
|
|
12342
12610
|
]
|
|
12343
12611
|
},
|
|
12344
12612
|
"linux-aarch64": {
|
|
12345
|
-
archive: "https://static.devin.ai/cli/
|
|
12613
|
+
archive: "https://static.devin.ai/cli/3000.1.27/devin-3000.1.27-aarch64-unknown-linux.tar.gz",
|
|
12346
12614
|
cmd: "./bin/devin",
|
|
12347
12615
|
args: [
|
|
12348
12616
|
"acp"
|
|
12349
12617
|
]
|
|
12350
12618
|
},
|
|
12351
12619
|
"linux-x86_64": {
|
|
12352
|
-
archive: "https://static.devin.ai/cli/
|
|
12620
|
+
archive: "https://static.devin.ai/cli/3000.1.27/devin-3000.1.27-x86_64-unknown-linux.tar.gz",
|
|
12353
12621
|
cmd: "./bin/devin",
|
|
12354
12622
|
args: [
|
|
12355
12623
|
"acp"
|
|
12356
12624
|
]
|
|
12357
12625
|
},
|
|
12358
12626
|
"windows-aarch64": {
|
|
12359
|
-
archive: "https://static.devin.ai/cli/
|
|
12627
|
+
archive: "https://static.devin.ai/cli/3000.1.27/devin-3000.1.27-aarch64-pc-windows.zip",
|
|
12360
12628
|
cmd: "./bin\\devin.exe",
|
|
12361
12629
|
args: [
|
|
12362
12630
|
"acp"
|
|
12363
12631
|
]
|
|
12364
12632
|
},
|
|
12365
12633
|
"windows-x86_64": {
|
|
12366
|
-
archive: "https://static.devin.ai/cli/
|
|
12634
|
+
archive: "https://static.devin.ai/cli/3000.1.27/devin-3000.1.27-x86_64-pc-windows.zip",
|
|
12367
12635
|
cmd: "./bin\\devin.exe",
|
|
12368
12636
|
args: [
|
|
12369
12637
|
"acp"
|
|
@@ -12375,12 +12643,12 @@ Task description:
|
|
|
12375
12643
|
{
|
|
12376
12644
|
id: "dimcode",
|
|
12377
12645
|
name: "DimCode",
|
|
12378
|
-
version: "0.2.
|
|
12646
|
+
version: "0.2.21",
|
|
12379
12647
|
description: "A coding agent that puts leading models at your command.",
|
|
12380
12648
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/dimcode.svg",
|
|
12381
12649
|
distribution: {
|
|
12382
12650
|
npx: {
|
|
12383
|
-
package: "dimcode@0.2.
|
|
12651
|
+
package: "dimcode@0.2.21",
|
|
12384
12652
|
args: [
|
|
12385
12653
|
"acp"
|
|
12386
12654
|
]
|
|
@@ -12390,12 +12658,12 @@ Task description:
|
|
|
12390
12658
|
{
|
|
12391
12659
|
id: "dirac",
|
|
12392
12660
|
name: "Dirac",
|
|
12393
|
-
version: "0.4.
|
|
12661
|
+
version: "0.4.13",
|
|
12394
12662
|
description: "Reduces API costs by more than 50%, produces better and faster work. Uses Hash anchored parallel edits, AST manipulation and a whole lot of neat optimizations. Fully Open Source.",
|
|
12395
12663
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/dirac.svg",
|
|
12396
12664
|
distribution: {
|
|
12397
12665
|
npx: {
|
|
12398
|
-
package: "dirac-cli@0.4.
|
|
12666
|
+
package: "dirac-cli@0.4.13",
|
|
12399
12667
|
args: [
|
|
12400
12668
|
"--acp"
|
|
12401
12669
|
]
|
|
@@ -12405,12 +12673,12 @@ Task description:
|
|
|
12405
12673
|
{
|
|
12406
12674
|
id: "factory-droid",
|
|
12407
12675
|
name: "Factory Droid",
|
|
12408
|
-
version: "0.
|
|
12676
|
+
version: "0.164.1",
|
|
12409
12677
|
description: "Factory Droid - AI coding agent powered by Factory AI",
|
|
12410
12678
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/factory-droid.svg",
|
|
12411
12679
|
distribution: {
|
|
12412
12680
|
npx: {
|
|
12413
|
-
package: "droid@0.
|
|
12681
|
+
package: "droid@0.164.1",
|
|
12414
12682
|
args: [
|
|
12415
12683
|
"exec",
|
|
12416
12684
|
"--output-format",
|
|
@@ -12426,12 +12694,12 @@ Task description:
|
|
|
12426
12694
|
{
|
|
12427
12695
|
id: "fast-agent",
|
|
12428
12696
|
name: "fast-agent",
|
|
12429
|
-
version: "0.
|
|
12697
|
+
version: "0.9.2",
|
|
12430
12698
|
description: "Code and build agents with comprehensive multi-provider support",
|
|
12431
12699
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/fast-agent.svg",
|
|
12432
12700
|
distribution: {
|
|
12433
12701
|
uvx: {
|
|
12434
|
-
package: "fast-agent-acp==0.
|
|
12702
|
+
package: "fast-agent-acp==0.9.2",
|
|
12435
12703
|
args: [
|
|
12436
12704
|
"-x"
|
|
12437
12705
|
]
|
|
@@ -12456,12 +12724,12 @@ Task description:
|
|
|
12456
12724
|
{
|
|
12457
12725
|
id: "github-copilot-cli",
|
|
12458
12726
|
name: "GitHub Copilot",
|
|
12459
|
-
version: "1.0.
|
|
12727
|
+
version: "1.0.68",
|
|
12460
12728
|
description: "GitHub's AI pair programmer",
|
|
12461
12729
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/github-copilot-cli.svg",
|
|
12462
12730
|
distribution: {
|
|
12463
12731
|
npx: {
|
|
12464
|
-
package: "@github/copilot@1.0.
|
|
12732
|
+
package: "@github/copilot@1.0.68",
|
|
12465
12733
|
args: [
|
|
12466
12734
|
"--acp"
|
|
12467
12735
|
]
|
|
@@ -12483,7 +12751,7 @@ Task description:
|
|
|
12483
12751
|
{
|
|
12484
12752
|
id: "goose",
|
|
12485
12753
|
name: "goose",
|
|
12486
|
-
version: "1.
|
|
12754
|
+
version: "1.41.0",
|
|
12487
12755
|
description: "A local, extensible, open source AI agent that automates engineering tasks",
|
|
12488
12756
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/goose.svg",
|
|
12489
12757
|
distribution: {
|
|
@@ -12501,12 +12769,12 @@ Task description:
|
|
|
12501
12769
|
{
|
|
12502
12770
|
id: "grok-build",
|
|
12503
12771
|
name: "Grok Build",
|
|
12504
|
-
version: "0.2.
|
|
12772
|
+
version: "0.2.89",
|
|
12505
12773
|
description: "xAI's coding agent and CLI",
|
|
12506
12774
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/grok-build.svg",
|
|
12507
12775
|
distribution: {
|
|
12508
12776
|
npx: {
|
|
12509
|
-
package: "@xai-official/grok@0.2.
|
|
12777
|
+
package: "@xai-official/grok@0.2.89",
|
|
12510
12778
|
args: [
|
|
12511
12779
|
"agent",
|
|
12512
12780
|
"stdio"
|
|
@@ -12514,10 +12782,61 @@ Task description:
|
|
|
12514
12782
|
}
|
|
12515
12783
|
}
|
|
12516
12784
|
},
|
|
12785
|
+
{
|
|
12786
|
+
id: "harn",
|
|
12787
|
+
name: "Harn",
|
|
12788
|
+
version: "0.10.0",
|
|
12789
|
+
description: "Harn runs .harn agent pipelines as a native ACP coding agent over stdio.",
|
|
12790
|
+
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/harn.svg",
|
|
12791
|
+
distribution: {
|
|
12792
|
+
binary: {
|
|
12793
|
+
"darwin-aarch64": {
|
|
12794
|
+
archive: "https://github.com/burin-labs/harn/releases/download/v0.10.0/harn-aarch64-apple-darwin.tar.gz",
|
|
12795
|
+
cmd: "./harn",
|
|
12796
|
+
args: [
|
|
12797
|
+
"serve",
|
|
12798
|
+
"acp"
|
|
12799
|
+
]
|
|
12800
|
+
},
|
|
12801
|
+
"darwin-x86_64": {
|
|
12802
|
+
archive: "https://github.com/burin-labs/harn/releases/download/v0.10.0/harn-x86_64-apple-darwin.tar.gz",
|
|
12803
|
+
cmd: "./harn",
|
|
12804
|
+
args: [
|
|
12805
|
+
"serve",
|
|
12806
|
+
"acp"
|
|
12807
|
+
]
|
|
12808
|
+
},
|
|
12809
|
+
"linux-aarch64": {
|
|
12810
|
+
archive: "https://github.com/burin-labs/harn/releases/download/v0.10.0/harn-aarch64-unknown-linux-gnu.tar.gz",
|
|
12811
|
+
cmd: "./harn",
|
|
12812
|
+
args: [
|
|
12813
|
+
"serve",
|
|
12814
|
+
"acp"
|
|
12815
|
+
]
|
|
12816
|
+
},
|
|
12817
|
+
"linux-x86_64": {
|
|
12818
|
+
archive: "https://github.com/burin-labs/harn/releases/download/v0.10.0/harn-x86_64-unknown-linux-gnu.tar.gz",
|
|
12819
|
+
cmd: "./harn",
|
|
12820
|
+
args: [
|
|
12821
|
+
"serve",
|
|
12822
|
+
"acp"
|
|
12823
|
+
]
|
|
12824
|
+
},
|
|
12825
|
+
"windows-x86_64": {
|
|
12826
|
+
archive: "https://github.com/burin-labs/harn/releases/download/v0.10.0/harn-x86_64-pc-windows-msvc.zip",
|
|
12827
|
+
cmd: "harn.exe",
|
|
12828
|
+
args: [
|
|
12829
|
+
"serve",
|
|
12830
|
+
"acp"
|
|
12831
|
+
]
|
|
12832
|
+
}
|
|
12833
|
+
}
|
|
12834
|
+
}
|
|
12835
|
+
},
|
|
12517
12836
|
{
|
|
12518
12837
|
id: "junie",
|
|
12519
12838
|
name: "Junie",
|
|
12520
|
-
version: "
|
|
12839
|
+
version: "2144.7.0",
|
|
12521
12840
|
description: "AI Coding Agent by JetBrains",
|
|
12522
12841
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/junie.svg",
|
|
12523
12842
|
distribution: {
|
|
@@ -12535,47 +12854,47 @@ Task description:
|
|
|
12535
12854
|
{
|
|
12536
12855
|
id: "kilo",
|
|
12537
12856
|
name: "Kilo",
|
|
12538
|
-
version: "7.
|
|
12857
|
+
version: "7.4.1",
|
|
12539
12858
|
description: "The open source coding agent",
|
|
12540
12859
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/kilo.svg",
|
|
12541
12860
|
distribution: {
|
|
12542
12861
|
npx: {
|
|
12543
|
-
package: "@kilocode/cli@7.
|
|
12862
|
+
package: "@kilocode/cli@7.4.1",
|
|
12544
12863
|
args: [
|
|
12545
12864
|
"acp"
|
|
12546
12865
|
]
|
|
12547
12866
|
},
|
|
12548
12867
|
binary: {
|
|
12549
12868
|
"darwin-aarch64": {
|
|
12550
|
-
archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.
|
|
12869
|
+
archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.1/kilo-darwin-arm64.zip",
|
|
12551
12870
|
cmd: "./kilo",
|
|
12552
12871
|
args: [
|
|
12553
12872
|
"acp"
|
|
12554
12873
|
]
|
|
12555
12874
|
},
|
|
12556
12875
|
"darwin-x86_64": {
|
|
12557
|
-
archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.
|
|
12876
|
+
archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.1/kilo-darwin-x64.zip",
|
|
12558
12877
|
cmd: "./kilo",
|
|
12559
12878
|
args: [
|
|
12560
12879
|
"acp"
|
|
12561
12880
|
]
|
|
12562
12881
|
},
|
|
12563
12882
|
"linux-aarch64": {
|
|
12564
|
-
archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.
|
|
12883
|
+
archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.1/kilo-linux-arm64.tar.gz",
|
|
12565
12884
|
cmd: "./kilo",
|
|
12566
12885
|
args: [
|
|
12567
12886
|
"acp"
|
|
12568
12887
|
]
|
|
12569
12888
|
},
|
|
12570
12889
|
"linux-x86_64": {
|
|
12571
|
-
archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.
|
|
12890
|
+
archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.1/kilo-linux-x64.tar.gz",
|
|
12572
12891
|
cmd: "./kilo",
|
|
12573
12892
|
args: [
|
|
12574
12893
|
"acp"
|
|
12575
12894
|
]
|
|
12576
12895
|
},
|
|
12577
12896
|
"windows-x86_64": {
|
|
12578
|
-
archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.
|
|
12897
|
+
archive: "https://github.com/Kilo-Org/kilocode/releases/download/v7.4.1/kilo-windows-x64.zip",
|
|
12579
12898
|
cmd: "./kilo.exe",
|
|
12580
12899
|
args: [
|
|
12581
12900
|
"acp"
|
|
@@ -12641,7 +12960,7 @@ Task description:
|
|
|
12641
12960
|
{
|
|
12642
12961
|
id: "mistral-vibe",
|
|
12643
12962
|
name: "Mistral Vibe",
|
|
12644
|
-
version: "2.
|
|
12963
|
+
version: "2.19.0",
|
|
12645
12964
|
description: "Mistral's open-source coding assistant",
|
|
12646
12965
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/mistral-vibe.svg",
|
|
12647
12966
|
distribution: {
|
|
@@ -12657,12 +12976,12 @@ Task description:
|
|
|
12657
12976
|
{
|
|
12658
12977
|
id: "nova",
|
|
12659
12978
|
name: "Nova",
|
|
12660
|
-
version: "1.1.
|
|
12979
|
+
version: "1.1.24",
|
|
12661
12980
|
description: "Nova by Compass AI - a fully-fledged software engineer at your command",
|
|
12662
12981
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/nova.svg",
|
|
12663
12982
|
distribution: {
|
|
12664
12983
|
npx: {
|
|
12665
|
-
package: "@compass-ai/nova@1.1.
|
|
12984
|
+
package: "@compass-ai/nova@1.1.24",
|
|
12666
12985
|
args: [
|
|
12667
12986
|
"acp"
|
|
12668
12987
|
]
|
|
@@ -12672,7 +12991,7 @@ Task description:
|
|
|
12672
12991
|
{
|
|
12673
12992
|
id: "opencode",
|
|
12674
12993
|
name: "OpenCode",
|
|
12675
|
-
version: "1.17.
|
|
12994
|
+
version: "1.17.14",
|
|
12676
12995
|
description: "The open source coding agent",
|
|
12677
12996
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/opencode.svg",
|
|
12678
12997
|
distribution: {
|
|
@@ -12702,48 +13021,48 @@ Task description:
|
|
|
12702
13021
|
{
|
|
12703
13022
|
id: "poolside",
|
|
12704
13023
|
name: "Poolside",
|
|
12705
|
-
version: "1.0.
|
|
13024
|
+
version: "1.0.8",
|
|
12706
13025
|
description: "Poolside's coding agent",
|
|
12707
13026
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/poolside.svg",
|
|
12708
13027
|
distribution: {
|
|
12709
13028
|
binary: {
|
|
12710
13029
|
"darwin-aarch64": {
|
|
12711
|
-
archive: "https://downloads.poolside.ai/pool/v1.0.
|
|
13030
|
+
archive: "https://downloads.poolside.ai/pool/v1.0.8/pool-darwin-arm64.tar.gz",
|
|
12712
13031
|
cmd: "./pool-darwin-arm64",
|
|
12713
13032
|
args: [
|
|
12714
13033
|
"acp"
|
|
12715
13034
|
]
|
|
12716
13035
|
},
|
|
12717
13036
|
"darwin-x86_64": {
|
|
12718
|
-
archive: "https://downloads.poolside.ai/pool/v1.0.
|
|
13037
|
+
archive: "https://downloads.poolside.ai/pool/v1.0.8/pool-darwin-amd64.tar.gz",
|
|
12719
13038
|
cmd: "./pool-darwin-amd64",
|
|
12720
13039
|
args: [
|
|
12721
13040
|
"acp"
|
|
12722
13041
|
]
|
|
12723
13042
|
},
|
|
12724
13043
|
"linux-aarch64": {
|
|
12725
|
-
archive: "https://downloads.poolside.ai/pool/v1.0.
|
|
13044
|
+
archive: "https://downloads.poolside.ai/pool/v1.0.8/pool-linux-arm64.tar.gz",
|
|
12726
13045
|
cmd: "./pool-linux-arm64",
|
|
12727
13046
|
args: [
|
|
12728
13047
|
"acp"
|
|
12729
13048
|
]
|
|
12730
13049
|
},
|
|
12731
13050
|
"linux-x86_64": {
|
|
12732
|
-
archive: "https://downloads.poolside.ai/pool/v1.0.
|
|
13051
|
+
archive: "https://downloads.poolside.ai/pool/v1.0.8/pool-linux-amd64.tar.gz",
|
|
12733
13052
|
cmd: "./pool-linux-amd64",
|
|
12734
13053
|
args: [
|
|
12735
13054
|
"acp"
|
|
12736
13055
|
]
|
|
12737
13056
|
},
|
|
12738
13057
|
"windows-aarch64": {
|
|
12739
|
-
archive: "https://downloads.poolside.ai/pool/v1.0.
|
|
13058
|
+
archive: "https://downloads.poolside.ai/pool/v1.0.8/pool-windows-arm64.tar.gz",
|
|
12740
13059
|
cmd: "./pool-windows-arm64.exe",
|
|
12741
13060
|
args: [
|
|
12742
13061
|
"acp"
|
|
12743
13062
|
]
|
|
12744
13063
|
},
|
|
12745
13064
|
"windows-x86_64": {
|
|
12746
|
-
archive: "https://downloads.poolside.ai/pool/v1.0.
|
|
13065
|
+
archive: "https://downloads.poolside.ai/pool/v1.0.8/pool-windows-amd64.tar.gz",
|
|
12747
13066
|
cmd: "./pool-windows-amd64.exe",
|
|
12748
13067
|
args: [
|
|
12749
13068
|
"acp"
|
|
@@ -12770,12 +13089,12 @@ Task description:
|
|
|
12770
13089
|
{
|
|
12771
13090
|
id: "qwen-code",
|
|
12772
13091
|
name: "Qwen Code",
|
|
12773
|
-
version: "0.19.
|
|
13092
|
+
version: "0.19.6",
|
|
12774
13093
|
description: "Alibaba's Qwen coding assistant",
|
|
12775
13094
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/qwen-code.svg",
|
|
12776
13095
|
distribution: {
|
|
12777
13096
|
npx: {
|
|
12778
|
-
package: "@qwen-code/qwen-code@0.19.
|
|
13097
|
+
package: "@qwen-code/qwen-code@0.19.6",
|
|
12779
13098
|
args: [
|
|
12780
13099
|
"--acp",
|
|
12781
13100
|
"--experimental-skills"
|
|
@@ -12800,36 +13119,36 @@ Task description:
|
|
|
12800
13119
|
{
|
|
12801
13120
|
id: "sigit",
|
|
12802
13121
|
name: "siGit Code",
|
|
12803
|
-
version: "1.
|
|
13122
|
+
version: "1.3.2",
|
|
12804
13123
|
description: "Local-first coding agent. Runs entirely on your machine with optional on-device LLM inference via Onde.",
|
|
12805
13124
|
icon: "https://cdn.agentclientprotocol.com/registry/v1/latest/sigit.svg",
|
|
12806
13125
|
distribution: {
|
|
12807
13126
|
npx: {
|
|
12808
|
-
package: "@smbcloud/sigit@1.
|
|
13127
|
+
package: "@smbcloud/sigit@1.3.2"
|
|
12809
13128
|
},
|
|
12810
13129
|
binary: {
|
|
12811
13130
|
"darwin-aarch64": {
|
|
12812
|
-
archive: "https://github.com/getsigit/sigit/releases/download/v1.
|
|
13131
|
+
archive: "https://github.com/getsigit/sigit/releases/download/v1.3.2/sigit-macos-arm64.tar.gz",
|
|
12813
13132
|
cmd: "./sigit"
|
|
12814
13133
|
},
|
|
12815
13134
|
"darwin-x86_64": {
|
|
12816
|
-
archive: "https://github.com/getsigit/sigit/releases/download/v1.
|
|
13135
|
+
archive: "https://github.com/getsigit/sigit/releases/download/v1.3.2/sigit-macos-amd64.tar.gz",
|
|
12817
13136
|
cmd: "./sigit"
|
|
12818
13137
|
},
|
|
12819
13138
|
"linux-aarch64": {
|
|
12820
|
-
archive: "https://github.com/getsigit/sigit/releases/download/v1.
|
|
13139
|
+
archive: "https://github.com/getsigit/sigit/releases/download/v1.3.2/sigit-linux-arm64",
|
|
12821
13140
|
cmd: "./sigit-linux-arm64"
|
|
12822
13141
|
},
|
|
12823
13142
|
"linux-x86_64": {
|
|
12824
|
-
archive: "https://github.com/getsigit/sigit/releases/download/v1.
|
|
13143
|
+
archive: "https://github.com/getsigit/sigit/releases/download/v1.3.2/sigit-linux-amd64",
|
|
12825
13144
|
cmd: "./sigit-linux-amd64"
|
|
12826
13145
|
},
|
|
12827
13146
|
"windows-aarch64": {
|
|
12828
|
-
archive: "https://github.com/getsigit/sigit/releases/download/v1.
|
|
13147
|
+
archive: "https://github.com/getsigit/sigit/releases/download/v1.3.2/sigit-win-arm64.exe",
|
|
12829
13148
|
cmd: "./sigit-win-arm64.exe"
|
|
12830
13149
|
},
|
|
12831
13150
|
"windows-x86_64": {
|
|
12832
|
-
archive: "https://github.com/getsigit/sigit/releases/download/v1.
|
|
13151
|
+
archive: "https://github.com/getsigit/sigit/releases/download/v1.3.2/sigit-win-amd64.exe",
|
|
12833
13152
|
cmd: "./sigit-win-amd64.exe"
|
|
12834
13153
|
}
|
|
12835
13154
|
}
|
|
@@ -78904,6 +79223,252 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
78904
79223
|
}
|
|
78905
79224
|
}
|
|
78906
79225
|
}
|
|
79226
|
+
const isRecoverableMachineFlockRoomStatus = (status) => status === "disconnected" || status === "error";
|
|
79227
|
+
class MachineFlockSyncCoordinator {
|
|
79228
|
+
repo;
|
|
79229
|
+
workspaceId;
|
|
79230
|
+
logger;
|
|
79231
|
+
random;
|
|
79232
|
+
retryBaseDelayMs;
|
|
79233
|
+
retryMaxDelayMs;
|
|
79234
|
+
states = /* @__PURE__ */ new Map();
|
|
79235
|
+
cleanedUp = false;
|
|
79236
|
+
constructor(options) {
|
|
79237
|
+
this.repo = options.repo;
|
|
79238
|
+
this.workspaceId = options.workspaceId;
|
|
79239
|
+
this.logger = options.logger;
|
|
79240
|
+
this.random = options.random ?? Math.random;
|
|
79241
|
+
this.retryBaseDelayMs = options.retryBaseDelayMs;
|
|
79242
|
+
this.retryMaxDelayMs = options.retryMaxDelayMs;
|
|
79243
|
+
}
|
|
79244
|
+
ensureJoined(machineId, options = {}) {
|
|
79245
|
+
const state2 = this.getState(machineId);
|
|
79246
|
+
return this.ensureStateJoined(state2, options.reason ?? "ensure-joined");
|
|
79247
|
+
}
|
|
79248
|
+
markDirty(machineId, options = {}) {
|
|
79249
|
+
if (this.cleanedUp) {
|
|
79250
|
+
return;
|
|
79251
|
+
}
|
|
79252
|
+
const state2 = this.getState(machineId);
|
|
79253
|
+
state2.dirty = true;
|
|
79254
|
+
state2.dirtyVersion += 1;
|
|
79255
|
+
if (options.resetBackoff) {
|
|
79256
|
+
state2.retryAttempt = 0;
|
|
79257
|
+
}
|
|
79258
|
+
const reason = options.reason ?? "dirty";
|
|
79259
|
+
void this.ensureStateJoined(state2, `dirty:${reason}`).catch((error2) => {
|
|
79260
|
+
this.logger.debug(`[${this.workspaceId}] Machine Flock room join failed before background sync (machine=${machineId} reason=${reason}): ${formatErrorMessage(error2)}`);
|
|
79261
|
+
});
|
|
79262
|
+
void this.syncNow(machineId, {
|
|
79263
|
+
...options,
|
|
79264
|
+
reason,
|
|
79265
|
+
scheduleRetry: options.scheduleRetry ?? true
|
|
79266
|
+
});
|
|
79267
|
+
}
|
|
79268
|
+
async syncNow(machineId, options = {}) {
|
|
79269
|
+
if (this.cleanedUp) {
|
|
79270
|
+
return false;
|
|
79271
|
+
}
|
|
79272
|
+
const state2 = this.getState(machineId);
|
|
79273
|
+
if (state2.activeSync) {
|
|
79274
|
+
return await state2.activeSync;
|
|
79275
|
+
}
|
|
79276
|
+
state2.activeSync = this.syncStateNow(state2, options).finally(() => {
|
|
79277
|
+
state2.activeSync = null;
|
|
79278
|
+
});
|
|
79279
|
+
return await state2.activeSync;
|
|
79280
|
+
}
|
|
79281
|
+
retryDirtyNow(reason) {
|
|
79282
|
+
if (this.cleanedUp) {
|
|
79283
|
+
return;
|
|
79284
|
+
}
|
|
79285
|
+
for (const state2 of this.states.values()) {
|
|
79286
|
+
if (!state2.dirty) {
|
|
79287
|
+
continue;
|
|
79288
|
+
}
|
|
79289
|
+
this.clearRetryTimer(state2);
|
|
79290
|
+
state2.retryAttempt = 0;
|
|
79291
|
+
void this.syncNow(state2.machineId, {
|
|
79292
|
+
reason,
|
|
79293
|
+
scheduleRetry: true,
|
|
79294
|
+
resetBackoff: true
|
|
79295
|
+
});
|
|
79296
|
+
}
|
|
79297
|
+
}
|
|
79298
|
+
async cleanUp() {
|
|
79299
|
+
this.cleanedUp = true;
|
|
79300
|
+
const pendingOperations = [];
|
|
79301
|
+
for (const state2 of this.states.values()) {
|
|
79302
|
+
this.clearRetryTimer(state2);
|
|
79303
|
+
if (state2.activeSync) {
|
|
79304
|
+
pendingOperations.push(state2.activeSync);
|
|
79305
|
+
}
|
|
79306
|
+
if (state2.joinPromise) {
|
|
79307
|
+
pendingOperations.push(state2.joinPromise);
|
|
79308
|
+
}
|
|
79309
|
+
this.releaseRoomSubscription(state2);
|
|
79310
|
+
}
|
|
79311
|
+
await Promise.allSettled(pendingOperations);
|
|
79312
|
+
this.states.clear();
|
|
79313
|
+
}
|
|
79314
|
+
async syncStateNow(state2, options) {
|
|
79315
|
+
const reason = options.reason ?? "sync-now";
|
|
79316
|
+
if (options.resetBackoff) {
|
|
79317
|
+
state2.retryAttempt = 0;
|
|
79318
|
+
}
|
|
79319
|
+
this.clearRetryTimer(state2);
|
|
79320
|
+
try {
|
|
79321
|
+
await this.ensureStateJoined(state2, `sync:${reason}`);
|
|
79322
|
+
} catch (error2) {
|
|
79323
|
+
this.logger.debug(`[${this.workspaceId}] Machine Flock room join failed before sync (machine=${state2.machineId} reason=${reason}): ${formatErrorMessage(error2)}`);
|
|
79324
|
+
}
|
|
79325
|
+
const syncVersion = state2.dirtyVersion;
|
|
79326
|
+
const timeoutMs = options.timeoutMs ?? readTimeoutEnv("LODY_LORO_SYNC_MACHINE_FLOCK_TIMEOUT_MS", 8e3);
|
|
79327
|
+
const timeoutMessage = `Timeout waiting for machine Flock doc sync (doc=${state2.docId})`;
|
|
79328
|
+
try {
|
|
79329
|
+
const handle = await this.repo.openFlockDoc(state2.docId);
|
|
79330
|
+
await withTimeout$3(handle.syncOnce(), timeoutMs, timeoutMessage);
|
|
79331
|
+
if (state2.dirtyVersion === syncVersion) {
|
|
79332
|
+
state2.dirty = false;
|
|
79333
|
+
state2.retryAttempt = 0;
|
|
79334
|
+
} else if (state2.dirty) {
|
|
79335
|
+
this.scheduleRetry(state2, `${reason}:new-writes`, true);
|
|
79336
|
+
}
|
|
79337
|
+
this.logger.debug(`[${this.workspaceId}] Machine Flock doc synced (machine=${state2.machineId} reason=${reason})`);
|
|
79338
|
+
return true;
|
|
79339
|
+
} catch (error2) {
|
|
79340
|
+
this.logger.debug(`[${this.workspaceId}] Machine Flock doc sync was not confirmed before continuing (machine=${state2.machineId} reason=${reason}): ${formatErrorMessage(error2)}`);
|
|
79341
|
+
if (options.scheduleRetry ?? true) {
|
|
79342
|
+
state2.dirty = true;
|
|
79343
|
+
this.scheduleRetry(state2, reason, false);
|
|
79344
|
+
}
|
|
79345
|
+
return false;
|
|
79346
|
+
}
|
|
79347
|
+
}
|
|
79348
|
+
async ensureStateJoined(state2, reason) {
|
|
79349
|
+
if (this.cleanedUp) {
|
|
79350
|
+
return;
|
|
79351
|
+
}
|
|
79352
|
+
if (state2.roomSub) {
|
|
79353
|
+
if (!isRecoverableMachineFlockRoomStatus(state2.roomSub.status)) {
|
|
79354
|
+
return;
|
|
79355
|
+
}
|
|
79356
|
+
this.releaseRoomSubscription(state2, state2.roomSub);
|
|
79357
|
+
}
|
|
79358
|
+
if (state2.joinPromise) {
|
|
79359
|
+
return await state2.joinPromise;
|
|
79360
|
+
}
|
|
79361
|
+
state2.joinPromise = (async () => {
|
|
79362
|
+
const handle = await this.repo.openFlockDoc(state2.docId);
|
|
79363
|
+
const sub = await handle.joinRoom();
|
|
79364
|
+
if (this.cleanedUp) {
|
|
79365
|
+
sub.unsubscribe();
|
|
79366
|
+
return;
|
|
79367
|
+
}
|
|
79368
|
+
state2.roomSub = sub;
|
|
79369
|
+
state2.detachRoomStatusListener = sub.onStatusChange((status) => {
|
|
79370
|
+
this.handleRoomStatusChange(state2, sub, status);
|
|
79371
|
+
});
|
|
79372
|
+
this.handleRoomStatusChange(state2, sub, sub.status);
|
|
79373
|
+
if (state2.roomSub !== sub) {
|
|
79374
|
+
return;
|
|
79375
|
+
}
|
|
79376
|
+
void sub.firstSyncedWithRemote.then(() => {
|
|
79377
|
+
if (this.cleanedUp || state2.roomSub !== sub) {
|
|
79378
|
+
return;
|
|
79379
|
+
}
|
|
79380
|
+
this.logger.debug(`[${this.workspaceId}] Machine Flock room first sync completed (machine=${state2.machineId} reason=${reason})`);
|
|
79381
|
+
}, (error2) => {
|
|
79382
|
+
if (this.cleanedUp || state2.roomSub !== sub) {
|
|
79383
|
+
return;
|
|
79384
|
+
}
|
|
79385
|
+
this.logger.debug(`[${this.workspaceId}] Machine Flock room first sync failed (machine=${state2.machineId} reason=${reason}): ${formatErrorMessage(error2)}`);
|
|
79386
|
+
});
|
|
79387
|
+
})();
|
|
79388
|
+
try {
|
|
79389
|
+
await state2.joinPromise;
|
|
79390
|
+
} finally {
|
|
79391
|
+
state2.joinPromise = null;
|
|
79392
|
+
}
|
|
79393
|
+
}
|
|
79394
|
+
handleRoomStatusChange(state2, sub, status) {
|
|
79395
|
+
if (this.cleanedUp || state2.roomSub !== sub) {
|
|
79396
|
+
return;
|
|
79397
|
+
}
|
|
79398
|
+
if (!isRecoverableMachineFlockRoomStatus(status)) {
|
|
79399
|
+
return;
|
|
79400
|
+
}
|
|
79401
|
+
this.logger.debug(`[${this.workspaceId}] Machine Flock room became ${status}; will rejoin before the next sync (machine=${state2.machineId})`);
|
|
79402
|
+
this.releaseRoomSubscription(state2, sub);
|
|
79403
|
+
if (state2.dirty) {
|
|
79404
|
+
this.scheduleRetry(state2, `room-${status}`, false);
|
|
79405
|
+
}
|
|
79406
|
+
}
|
|
79407
|
+
releaseRoomSubscription(state2, sub = state2.roomSub) {
|
|
79408
|
+
if (!sub || state2.roomSub !== sub) {
|
|
79409
|
+
return;
|
|
79410
|
+
}
|
|
79411
|
+
state2.detachRoomStatusListener?.();
|
|
79412
|
+
state2.detachRoomStatusListener = null;
|
|
79413
|
+
state2.roomSub = null;
|
|
79414
|
+
sub.unsubscribe();
|
|
79415
|
+
}
|
|
79416
|
+
scheduleRetry(state2, reason, resetBackoff) {
|
|
79417
|
+
if (this.cleanedUp || !state2.dirty) {
|
|
79418
|
+
return;
|
|
79419
|
+
}
|
|
79420
|
+
if (resetBackoff) {
|
|
79421
|
+
state2.retryAttempt = 0;
|
|
79422
|
+
}
|
|
79423
|
+
if (state2.retryTimer) {
|
|
79424
|
+
return;
|
|
79425
|
+
}
|
|
79426
|
+
const delayMs = computeLoroReconnectDelayMs(state2.retryAttempt, {
|
|
79427
|
+
baseDelayMs: this.retryBaseDelayMs ?? readTimeoutEnv("LODY_LORO_MACHINE_FLOCK_RETRY_BASE_DELAY_MS", 1e3),
|
|
79428
|
+
maxDelayMs: this.retryMaxDelayMs ?? readTimeoutEnv("LODY_LORO_MACHINE_FLOCK_RETRY_MAX_DELAY_MS", 6e4),
|
|
79429
|
+
random: this.random
|
|
79430
|
+
});
|
|
79431
|
+
state2.retryAttempt += 1;
|
|
79432
|
+
state2.retryTimer = setTimeout(() => {
|
|
79433
|
+
state2.retryTimer = null;
|
|
79434
|
+
if (this.cleanedUp || !state2.dirty) {
|
|
79435
|
+
return;
|
|
79436
|
+
}
|
|
79437
|
+
void this.syncNow(state2.machineId, {
|
|
79438
|
+
reason: `retry:${reason}`,
|
|
79439
|
+
scheduleRetry: true
|
|
79440
|
+
});
|
|
79441
|
+
}, delayMs);
|
|
79442
|
+
this.logger.debug(`[${this.workspaceId}] Scheduled Machine Flock doc sync retry in ${delayMs}ms (machine=${state2.machineId} reason=${reason})`);
|
|
79443
|
+
}
|
|
79444
|
+
clearRetryTimer(state2) {
|
|
79445
|
+
if (!state2.retryTimer) {
|
|
79446
|
+
return;
|
|
79447
|
+
}
|
|
79448
|
+
clearTimeout(state2.retryTimer);
|
|
79449
|
+
state2.retryTimer = null;
|
|
79450
|
+
}
|
|
79451
|
+
getState(machineId) {
|
|
79452
|
+
const existing = this.states.get(machineId);
|
|
79453
|
+
if (existing) {
|
|
79454
|
+
return existing;
|
|
79455
|
+
}
|
|
79456
|
+
const state2 = {
|
|
79457
|
+
machineId,
|
|
79458
|
+
docId: getMachineFlockDocId(this.workspaceId, machineId),
|
|
79459
|
+
dirty: false,
|
|
79460
|
+
dirtyVersion: 0,
|
|
79461
|
+
retryAttempt: 0,
|
|
79462
|
+
retryTimer: null,
|
|
79463
|
+
activeSync: null,
|
|
79464
|
+
joinPromise: null,
|
|
79465
|
+
roomSub: null,
|
|
79466
|
+
detachRoomStatusListener: null
|
|
79467
|
+
};
|
|
79468
|
+
this.states.set(machineId, state2);
|
|
79469
|
+
return state2;
|
|
79470
|
+
}
|
|
79471
|
+
}
|
|
78907
79472
|
const SENSITIVE_QUERY_KEYS = /* @__PURE__ */ new Set([
|
|
78908
79473
|
"token",
|
|
78909
79474
|
"access_token",
|
|
@@ -98466,7 +99031,7 @@ ${value}`;
|
|
|
98466
99031
|
]);
|
|
98467
99032
|
return mergeAgentConfigs(loroRepoMetaConfigs, machineFlockConfigs);
|
|
98468
99033
|
}
|
|
98469
|
-
async function upsertMachineAgentConfig(repo, workspaceId, config2) {
|
|
99034
|
+
async function upsertMachineAgentConfig(repo, workspaceId, config2, options = {}) {
|
|
98470
99035
|
const handle = await repo.openFlockDoc(getMachineFlockDocId(workspaceId, config2.machineId));
|
|
98471
99036
|
const changed = writeMachineFlockRowToFlock(handle.flock, {
|
|
98472
99037
|
key: machineFlockKeys.agentConfig(config2.id),
|
|
@@ -98477,10 +99042,16 @@ ${value}`;
|
|
|
98477
99042
|
return;
|
|
98478
99043
|
}
|
|
98479
99044
|
await repo.flush();
|
|
98480
|
-
|
|
99045
|
+
if (options.sync) {
|
|
99046
|
+
options.sync.markMachineFlockDocDirty(config2.machineId, {
|
|
99047
|
+
reason: options.reason ?? "agent-config-upsert"
|
|
99048
|
+
});
|
|
99049
|
+
} else {
|
|
99050
|
+
await handle.syncOnce().catch(() => void 0);
|
|
99051
|
+
}
|
|
98481
99052
|
await deleteLoroRepoMetaAgentConfigIfPresent(repo, config2.id);
|
|
98482
99053
|
}
|
|
98483
|
-
async function deleteMachineAgentConfig(repo, workspaceId, config2) {
|
|
99054
|
+
async function deleteMachineAgentConfig(repo, workspaceId, config2, options = {}) {
|
|
98484
99055
|
const handle = await repo.openFlockDoc(getMachineFlockDocId(workspaceId, config2.machineId));
|
|
98485
99056
|
const changed = deleteMachineFlockRowFromFlock(handle.flock, machineFlockKeys.agentConfig(config2.id));
|
|
98486
99057
|
if (!changed) {
|
|
@@ -98488,7 +99059,13 @@ ${value}`;
|
|
|
98488
99059
|
return;
|
|
98489
99060
|
}
|
|
98490
99061
|
await repo.flush();
|
|
98491
|
-
|
|
99062
|
+
if (options.sync) {
|
|
99063
|
+
options.sync.markMachineFlockDocDirty(config2.machineId, {
|
|
99064
|
+
reason: options.reason ?? "agent-config-delete"
|
|
99065
|
+
});
|
|
99066
|
+
} else {
|
|
99067
|
+
await handle.syncOnce().catch(() => void 0);
|
|
99068
|
+
}
|
|
98492
99069
|
await deleteLoroRepoMetaAgentConfigIfPresent(repo, config2.id);
|
|
98493
99070
|
}
|
|
98494
99071
|
async function listMachineAgentConfigs(repo, workspaceId, machineIds) {
|
|
@@ -98684,11 +99261,21 @@ ${value}`;
|
|
|
98684
99261
|
this.initialMetaSyncCompleted = true;
|
|
98685
99262
|
}
|
|
98686
99263
|
});
|
|
99264
|
+
this.machineFlockSync = new MachineFlockSyncCoordinator({
|
|
99265
|
+
repo,
|
|
99266
|
+
workspaceId,
|
|
99267
|
+
logger: logger2
|
|
99268
|
+
});
|
|
99269
|
+
this.detachMachineFlockMetaRoomSyncedListener = this.connectionRecovery.onMetaRoomSynced((reason) => {
|
|
99270
|
+
this.machineFlockSync.retryDirtyNow(`meta-room-synced:${reason}`);
|
|
99271
|
+
});
|
|
98687
99272
|
}
|
|
98688
99273
|
sessions = /* @__PURE__ */ new Map();
|
|
98689
99274
|
machine = null;
|
|
98690
99275
|
machineExistenceWatcher = null;
|
|
98691
99276
|
connectionRecovery;
|
|
99277
|
+
machineFlockSync;
|
|
99278
|
+
detachMachineFlockMetaRoomSyncedListener = null;
|
|
98692
99279
|
initialMetaSyncCompleted = false;
|
|
98693
99280
|
initialMetaSyncPromise;
|
|
98694
99281
|
presenceRuntime;
|
|
@@ -98875,6 +99462,70 @@ ${value}`;
|
|
|
98875
99462
|
async waitUntilMetaSynced(options = {}) {
|
|
98876
99463
|
return await this.connectionRecovery.waitUntilMetaSynced(options);
|
|
98877
99464
|
}
|
|
99465
|
+
async syncMetaOrThrow(options = {}) {
|
|
99466
|
+
const reason = options.reason ?? "explicit-sync";
|
|
99467
|
+
const timeoutMs = options.timeoutMs ?? readTimeoutEnv("LODY_LORO_SYNC_META_TIMEOUT_MS", 2e4);
|
|
99468
|
+
const timeoutMessage = `Timeout waiting for workspace metadata sync (workspace=${this.workspaceId})`;
|
|
99469
|
+
try {
|
|
99470
|
+
await withTimeout$3(this.repo.sync({
|
|
99471
|
+
scope: "meta"
|
|
99472
|
+
}), timeoutMs, timeoutMessage);
|
|
99473
|
+
this.initialMetaSyncCompleted = true;
|
|
99474
|
+
} catch (error2) {
|
|
99475
|
+
throw new Error(`Workspace metadata sync failed (${reason}): ${formatErrorMessage(error2)}`, {
|
|
99476
|
+
cause: error2
|
|
99477
|
+
});
|
|
99478
|
+
}
|
|
99479
|
+
}
|
|
99480
|
+
async syncDocOrThrow(docId, options = {}) {
|
|
99481
|
+
const reason = options.reason ?? "explicit-sync";
|
|
99482
|
+
const timeoutMs = options.timeoutMs ?? readTimeoutEnv("LODY_LORO_SYNC_DOC_TIMEOUT_MS", 8e3);
|
|
99483
|
+
const timeoutMessage = `Timeout waiting for document sync (doc=${docId})`;
|
|
99484
|
+
try {
|
|
99485
|
+
await withTimeout$3(this.repo.sync({
|
|
99486
|
+
scope: "doc",
|
|
99487
|
+
docIds: [
|
|
99488
|
+
docId
|
|
99489
|
+
]
|
|
99490
|
+
}), timeoutMs, timeoutMessage);
|
|
99491
|
+
} catch (error2) {
|
|
99492
|
+
throw new Error(`Document sync failed for ${docId} (${reason}): ${formatErrorMessage(error2)}`, {
|
|
99493
|
+
cause: error2
|
|
99494
|
+
});
|
|
99495
|
+
}
|
|
99496
|
+
}
|
|
99497
|
+
async syncFlockDocOrThrow(flockDocId, options = {}) {
|
|
99498
|
+
const reason = options.reason ?? "explicit-sync";
|
|
99499
|
+
const timeoutMs = options.timeoutMs ?? readTimeoutEnv("LODY_LORO_SYNC_MACHINE_FLOCK_TIMEOUT_MS", 8e3);
|
|
99500
|
+
const timeoutMessage = `Timeout waiting for Flock document sync (doc=${flockDocId})`;
|
|
99501
|
+
try {
|
|
99502
|
+
await withTimeout$3(this.repo.sync({
|
|
99503
|
+
scope: "doc",
|
|
99504
|
+
flockDocIds: [
|
|
99505
|
+
flockDocId
|
|
99506
|
+
]
|
|
99507
|
+
}), timeoutMs, timeoutMessage);
|
|
99508
|
+
} catch (error2) {
|
|
99509
|
+
throw new Error(`Flock document sync failed for ${flockDocId} (${reason}): ${formatErrorMessage(error2)}`, {
|
|
99510
|
+
cause: error2
|
|
99511
|
+
});
|
|
99512
|
+
}
|
|
99513
|
+
}
|
|
99514
|
+
async syncMachineFlockDoc(machineId, options = {}) {
|
|
99515
|
+
return await this.machineFlockSync.syncNow(machineId, {
|
|
99516
|
+
...options,
|
|
99517
|
+
reason: options.reason ?? "explicit-sync",
|
|
99518
|
+
scheduleRetry: options.scheduleRetry ?? true
|
|
99519
|
+
});
|
|
99520
|
+
}
|
|
99521
|
+
markMachineFlockDocDirty(machineId, options = {}) {
|
|
99522
|
+
this.machineFlockSync.markDirty(machineId, options);
|
|
99523
|
+
}
|
|
99524
|
+
ensureMachineFlockDocJoined(machineId, options = {}) {
|
|
99525
|
+
void this.machineFlockSync.ensureJoined(machineId, options).catch((error2) => {
|
|
99526
|
+
this.logger.debug(`[${this.workspaceId}] Failed to join Machine Flock room (machine=${machineId} reason=${options.reason ?? "ensure-joined"}): ${formatErrorMessage(error2)}`);
|
|
99527
|
+
});
|
|
99528
|
+
}
|
|
98878
99529
|
async destroyRepo(options) {
|
|
98879
99530
|
const repoDestroyPromise = this.repo.destroy();
|
|
98880
99531
|
if (!options.fast) {
|
|
@@ -98987,6 +99638,9 @@ ${value}`;
|
|
|
98987
99638
|
cliType,
|
|
98988
99639
|
agentType,
|
|
98989
99640
|
env: {}
|
|
99641
|
+
}, {
|
|
99642
|
+
sync: this,
|
|
99643
|
+
reason: "agent-config-upsert"
|
|
98990
99644
|
});
|
|
98991
99645
|
return agentConfigId;
|
|
98992
99646
|
}
|
|
@@ -98994,7 +99648,7 @@ ${value}`;
|
|
|
98994
99648
|
}
|
|
98995
99649
|
async registerMachine(machineId, machine) {
|
|
98996
99650
|
if (!this.machine) {
|
|
98997
|
-
this.machine =
|
|
99651
|
+
this.machine = this.createMachineDocument(machineId);
|
|
98998
99652
|
await this.machine.init();
|
|
98999
99653
|
}
|
|
99000
99654
|
await this.machine.setMetaState({
|
|
@@ -99005,25 +99659,32 @@ ${value}`;
|
|
|
99005
99659
|
}
|
|
99006
99660
|
async updateRateLimits(machineId, cliType, limits) {
|
|
99007
99661
|
if (!this.machine) {
|
|
99008
|
-
this.machine =
|
|
99662
|
+
this.machine = this.createMachineDocument(machineId);
|
|
99009
99663
|
await this.machine.init();
|
|
99010
99664
|
}
|
|
99011
99665
|
await this.machine.updateRateLimits(cliType, limits);
|
|
99012
99666
|
}
|
|
99013
99667
|
async updateAcpCapabilities(machineId, cliType, agentType, modes, models, configOptions, availableCommands, sourceVersion) {
|
|
99014
99668
|
if (!this.machine) {
|
|
99015
|
-
this.machine =
|
|
99669
|
+
this.machine = this.createMachineDocument(machineId);
|
|
99016
99670
|
await this.machine.init();
|
|
99017
99671
|
}
|
|
99018
99672
|
await this.machine.updateAcpCapabilities(cliType, agentType, modes, models, configOptions, availableCommands, sourceVersion);
|
|
99019
99673
|
}
|
|
99020
99674
|
async getAcpCapabilities(machineId, cliType, agentType) {
|
|
99021
99675
|
if (!this.machine) {
|
|
99022
|
-
this.machine =
|
|
99676
|
+
this.machine = this.createMachineDocument(machineId);
|
|
99023
99677
|
await this.machine.init();
|
|
99024
99678
|
}
|
|
99025
99679
|
return this.machine.getAcpCapabilities(cliType, agentType);
|
|
99026
99680
|
}
|
|
99681
|
+
createMachineDocument(machineId) {
|
|
99682
|
+
return new MachineDocument(this.repo, this.workspaceId, machineId, (reason) => {
|
|
99683
|
+
this.markMachineFlockDocDirty(machineId, {
|
|
99684
|
+
reason
|
|
99685
|
+
});
|
|
99686
|
+
});
|
|
99687
|
+
}
|
|
99027
99688
|
async restoreMachineDocument(machineId) {
|
|
99028
99689
|
const machineRoomId = getMachineRoomId(machineId);
|
|
99029
99690
|
await this.repo.restoreDoc(machineRoomId);
|
|
@@ -99053,6 +99714,9 @@ ${value}`;
|
|
|
99053
99714
|
} catch (error2) {
|
|
99054
99715
|
this.logger.debug(`[${this.workspaceId}] Failed to stop Loro presence runtime: ${formatErrorMessage(error2)}`);
|
|
99055
99716
|
}
|
|
99717
|
+
this.detachMachineFlockMetaRoomSyncedListener?.();
|
|
99718
|
+
this.detachMachineFlockMetaRoomSyncedListener = null;
|
|
99719
|
+
await this.machineFlockSync.cleanUp();
|
|
99056
99720
|
await this.connectionRecovery.cleanUp();
|
|
99057
99721
|
for (const [sessionId, pending2] of this.pendingSessionDocs) {
|
|
99058
99722
|
try {
|
|
@@ -99937,10 +100601,11 @@ ${value}`;
|
|
|
99937
100601
|
return meta.meta;
|
|
99938
100602
|
};
|
|
99939
100603
|
class MachineDocument {
|
|
99940
|
-
constructor(repo, workspaceId, machineId) {
|
|
100604
|
+
constructor(repo, workspaceId, machineId, markMachineFlockDirty) {
|
|
99941
100605
|
this.repo = repo;
|
|
99942
100606
|
this.workspaceId = workspaceId;
|
|
99943
100607
|
this.machineId = machineId;
|
|
100608
|
+
this.markMachineFlockDirty = markMachineFlockDirty;
|
|
99944
100609
|
this.roomId = getMachineRoomId(this.machineId);
|
|
99945
100610
|
}
|
|
99946
100611
|
roomId;
|
|
@@ -99980,7 +100645,11 @@ ${value}`;
|
|
|
99980
100645
|
});
|
|
99981
100646
|
if (changed) {
|
|
99982
100647
|
await this.repo.flush();
|
|
99983
|
-
|
|
100648
|
+
if (this.markMachineFlockDirty) {
|
|
100649
|
+
this.markMachineFlockDirty("rate-limit-update");
|
|
100650
|
+
} else {
|
|
100651
|
+
await handle.syncOnce().catch(() => void 0);
|
|
100652
|
+
}
|
|
99984
100653
|
}
|
|
99985
100654
|
});
|
|
99986
100655
|
}
|
|
@@ -100013,7 +100682,11 @@ ${value}`;
|
|
|
100013
100682
|
});
|
|
100014
100683
|
if (changed) {
|
|
100015
100684
|
await this.repo.flush();
|
|
100016
|
-
|
|
100685
|
+
if (this.markMachineFlockDirty) {
|
|
100686
|
+
this.markMachineFlockDirty("acp-capability-update");
|
|
100687
|
+
} else {
|
|
100688
|
+
await handle.syncOnce().catch(() => void 0);
|
|
100689
|
+
}
|
|
100017
100690
|
}
|
|
100018
100691
|
}
|
|
100019
100692
|
async getAcpCapabilities(cliType, agentType) {
|
|
@@ -102105,7 +102778,9 @@ The file is not available yet and could not be downloaded; ask the user to resen
|
|
|
102105
102778
|
return remoteName;
|
|
102106
102779
|
}
|
|
102107
102780
|
async function probeGitHubRemoteAtRootPath(rootPath) {
|
|
102108
|
-
await
|
|
102781
|
+
if (!await isGitRepository(rootPath)) {
|
|
102782
|
+
return null;
|
|
102783
|
+
}
|
|
102109
102784
|
const remotes = await listGitRemotes(rootPath);
|
|
102110
102785
|
if (remotes.length === 0) return null;
|
|
102111
102786
|
const currentBranchRemote = await resolveCurrentBranchRemote(rootPath, remotes);
|
|
@@ -117714,18 +118389,6 @@ ${fallbackStderrTail}` : errorMessage;
|
|
|
117714
118389
|
function shouldScrubClaudeAuthEnv(cliType, agentType) {
|
|
117715
118390
|
return cliType === "builtin" && agentType === "claude" || cliType === "registry" && agentType === "claude-p";
|
|
117716
118391
|
}
|
|
117717
|
-
async function getStaticBuiltinAcpCapabilities(agentType) {
|
|
117718
|
-
if (!isBuiltinAgentType(agentType)) {
|
|
117719
|
-
return void 0;
|
|
117720
|
-
}
|
|
117721
|
-
const baseline = agentType === "claude" ? (await import("./chunks/baseline-config-CcYq1mUH.js")).getClaudeBaselineConfig() : (await import("./chunks/baseline-config-BPa_f3S0.js")).getCodexBaselineConfig();
|
|
117722
|
-
const configOptions = normalizeConfigOptions(baseline.configOptions);
|
|
117723
|
-
return {
|
|
117724
|
-
modes: baseline.modes,
|
|
117725
|
-
models: baseline.models,
|
|
117726
|
-
configOptions
|
|
117727
|
-
};
|
|
117728
|
-
}
|
|
117729
118392
|
function isSelectGroup$1(item) {
|
|
117730
118393
|
return typeof item === "object" && item !== null && "group" in item;
|
|
117731
118394
|
}
|
|
@@ -117803,7 +118466,7 @@ ${fallbackStderrTail}` : errorMessage;
|
|
|
117803
118466
|
async function fetchAcpCapabilities(cliType, agentType, logger2, env2, customAcp, runtimeOverrides, options = {}) {
|
|
117804
118467
|
const allowStaticBuiltinCapabilities = options.allowStaticBuiltinCapabilities ?? true;
|
|
117805
118468
|
if (allowStaticBuiltinCapabilities && cliType === "builtin" && !hasBuiltinRuntimeOverrideValues(runtimeOverrides)) {
|
|
117806
|
-
const staticCapabilities =
|
|
118469
|
+
const staticCapabilities = getStaticBuiltinAcpCapabilities(cliType, agentType, runtimeOverrides);
|
|
117807
118470
|
if (staticCapabilities) {
|
|
117808
118471
|
logger2.debug(`[acp-capabilities] Using static builtin capabilities (agentType=${agentType})`);
|
|
117809
118472
|
return staticCapabilities;
|
|
@@ -121326,7 +121989,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
121326
121989
|
...flockLocalProjects
|
|
121327
121990
|
};
|
|
121328
121991
|
}
|
|
121329
|
-
async function upsertMachineLocalProject(repo, workspaceId, machineId, project, nowMs2 = getServerNow()) {
|
|
121992
|
+
async function upsertMachineLocalProject(repo, workspaceId, machineId, project, nowMs2 = getServerNow(), options = {}) {
|
|
121330
121993
|
const handle = await repo.openFlockDoc(getMachineFlockDocId(workspaceId, machineId));
|
|
121331
121994
|
const changed = writeMachineFlockRowToFlock(handle.flock, {
|
|
121332
121995
|
key: machineFlockKeys.localProject(project.id),
|
|
@@ -121336,14 +121999,26 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
121336
121999
|
return;
|
|
121337
122000
|
}
|
|
121338
122001
|
await repo.flush();
|
|
121339
|
-
|
|
122002
|
+
if (options.sync) {
|
|
122003
|
+
options.sync.markMachineFlockDocDirty(machineId, {
|
|
122004
|
+
reason: options.reason ?? "local-project-upsert"
|
|
122005
|
+
});
|
|
122006
|
+
} else {
|
|
122007
|
+
await handle.syncOnce().catch(() => void 0);
|
|
122008
|
+
}
|
|
121340
122009
|
}
|
|
121341
|
-
async function removeMachineLocalProject(repo, workspaceId, machineId, localProjectId, nowMs2 = getServerNow()) {
|
|
122010
|
+
async function removeMachineLocalProject(repo, workspaceId, machineId, localProjectId, nowMs2 = getServerNow(), options = {}) {
|
|
121342
122011
|
const handle = await repo.openFlockDoc(getMachineFlockDocId(workspaceId, machineId));
|
|
121343
122012
|
const changed = deleteMachineFlockRowFromFlock(handle.flock, machineFlockKeys.localProject(localProjectId), nowMs2);
|
|
121344
122013
|
if (changed) {
|
|
121345
122014
|
await repo.flush();
|
|
121346
|
-
|
|
122015
|
+
if (options.sync) {
|
|
122016
|
+
options.sync.markMachineFlockDocDirty(machineId, {
|
|
122017
|
+
reason: options.reason ?? "local-project-remove"
|
|
122018
|
+
});
|
|
122019
|
+
} else {
|
|
122020
|
+
await handle.syncOnce().catch(() => void 0);
|
|
122021
|
+
}
|
|
121347
122022
|
}
|
|
121348
122023
|
const machineRoomId = getMachineRoomId(machineId);
|
|
121349
122024
|
const current2 = await repo.getDocMeta(machineRoomId);
|
|
@@ -133763,7 +134438,10 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
133763
134438
|
]))
|
|
133764
134439
|
}
|
|
133765
134440
|
}
|
|
133766
|
-
}, lastListedAt
|
|
134441
|
+
}, lastListedAt, {
|
|
134442
|
+
sync: this.manager,
|
|
134443
|
+
reason: "local-project-history-sync"
|
|
134444
|
+
});
|
|
133767
134445
|
});
|
|
133768
134446
|
return catalog;
|
|
133769
134447
|
}
|
|
@@ -139146,7 +139824,10 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
139146
139824
|
rootPath: entry.rootPath,
|
|
139147
139825
|
createdAtMs: previous?.createdAtMs ?? nowMs2,
|
|
139148
139826
|
lastOpenedAtMs: nowMs2
|
|
139149
|
-
}, nowMs2
|
|
139827
|
+
}, nowMs2, {
|
|
139828
|
+
sync: this.workspaceDocument,
|
|
139829
|
+
reason: "local-project-add"
|
|
139830
|
+
});
|
|
139150
139831
|
}
|
|
139151
139832
|
async authorizeLocalProjectRoot(args2) {
|
|
139152
139833
|
const access = await canUseMachineForCliToken({
|
|
@@ -148183,6 +148864,8 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
148183
148864
|
await next2;
|
|
148184
148865
|
}
|
|
148185
148866
|
}
|
|
148867
|
+
const BUILTIN_AGENT_CONFIG_INITIAL_RETRY_DELAY_MS = 1e4;
|
|
148868
|
+
const BUILTIN_AGENT_CONFIG_MAX_RETRY_DELAY_MS = 5 * 6e4;
|
|
148186
148869
|
class Lody {
|
|
148187
148870
|
constructor(options, documentManager) {
|
|
148188
148871
|
this.options = options;
|
|
@@ -148223,6 +148906,9 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
148223
148906
|
runtime;
|
|
148224
148907
|
supportRegistryAgentTypes;
|
|
148225
148908
|
cleanedUp = false;
|
|
148909
|
+
builtinAgentConfigRetryTimer;
|
|
148910
|
+
pendingBuiltinAgentConfigRetryCliTypes = /* @__PURE__ */ new Set();
|
|
148911
|
+
builtinAgentConfigRetryAttempt = 0;
|
|
148226
148912
|
static async create(options) {
|
|
148227
148913
|
const manager = await LoroDocumentManager.create(options.workspaceId, options.userId, () => options.token, options.logger);
|
|
148228
148914
|
return new Lody(options, manager);
|
|
@@ -148230,25 +148916,49 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
148230
148916
|
async start() {
|
|
148231
148917
|
void getLoginShellEnv();
|
|
148232
148918
|
await this.runtime.initialize();
|
|
148919
|
+
this.documentManager.ensureMachineFlockDocJoined(this.machineId, {
|
|
148920
|
+
reason: "lody-start"
|
|
148921
|
+
});
|
|
148233
148922
|
}
|
|
148234
148923
|
async registerAgent(cliTypes) {
|
|
148235
148924
|
await this.runtime.initialize();
|
|
148236
148925
|
if (this.documentManager.hasCompletedInitialMetaSync()) {
|
|
148237
|
-
await this.
|
|
148926
|
+
await this.ensureBuiltinAgentConfigsOrRetry(cliTypes);
|
|
148238
148927
|
} else {
|
|
148239
148928
|
this.logger.debug(`[agent-config] Initial meta sync is not complete for workspace ${this.workspaceId}; deferring builtin agent registration`);
|
|
148240
148929
|
void this.documentManager.waitForInitialMetaSync().then(async (completed) => {
|
|
148241
148930
|
if (!completed || this.cleanedUp) {
|
|
148242
148931
|
return;
|
|
148243
148932
|
}
|
|
148244
|
-
await this.
|
|
148933
|
+
await this.ensureBuiltinAgentConfigsOrRetry(cliTypes);
|
|
148245
148934
|
}).catch((error2) => {
|
|
148246
148935
|
this.logger.debug(`[agent-config] Deferred builtin agent registration failed: ${formatErrorMessage(error2)}`);
|
|
148247
148936
|
});
|
|
148248
148937
|
}
|
|
148249
148938
|
void this.refreshBuiltinCapabilities(cliTypes);
|
|
148250
148939
|
}
|
|
148940
|
+
async ensureBuiltinAgentConfigsOrRetry(cliTypes) {
|
|
148941
|
+
if (this.cleanedUp) {
|
|
148942
|
+
return;
|
|
148943
|
+
}
|
|
148944
|
+
const completed = await this.ensureBuiltinAgentConfigs(cliTypes);
|
|
148945
|
+
if (!completed) {
|
|
148946
|
+
this.scheduleBuiltinAgentConfigRetry(cliTypes);
|
|
148947
|
+
return;
|
|
148948
|
+
}
|
|
148949
|
+
this.builtinAgentConfigRetryAttempt = 0;
|
|
148950
|
+
}
|
|
148251
148951
|
async ensureBuiltinAgentConfigs(cliTypes) {
|
|
148952
|
+
if (cliTypes.length === 0) {
|
|
148953
|
+
return true;
|
|
148954
|
+
}
|
|
148955
|
+
const syncedMachineFlock = await this.documentManager.syncMachineFlockDoc(this.machineId, {
|
|
148956
|
+
reason: "builtin-agent-registration"
|
|
148957
|
+
});
|
|
148958
|
+
if (!syncedMachineFlock) {
|
|
148959
|
+
this.logger.debug(`[agent-config] Machine Flock sync is not complete for workspace ${this.workspaceId} machine ${this.machineId}; skipping builtin agent registration for this attempt`);
|
|
148960
|
+
return false;
|
|
148961
|
+
}
|
|
148252
148962
|
const builtinDisplayName = {
|
|
148253
148963
|
claude: "Claude Code",
|
|
148254
148964
|
codex: "Codex"
|
|
@@ -148259,6 +148969,40 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
148259
148969
|
await this.documentManager.createAgentConfig("builtin", cliType, this.machineId, builtinDisplayName[cliType]);
|
|
148260
148970
|
}
|
|
148261
148971
|
}
|
|
148972
|
+
return true;
|
|
148973
|
+
}
|
|
148974
|
+
scheduleBuiltinAgentConfigRetry(cliTypes) {
|
|
148975
|
+
if (cliTypes.length === 0 || this.cleanedUp) {
|
|
148976
|
+
return;
|
|
148977
|
+
}
|
|
148978
|
+
for (const cliType of cliTypes) {
|
|
148979
|
+
this.pendingBuiltinAgentConfigRetryCliTypes.add(cliType);
|
|
148980
|
+
}
|
|
148981
|
+
if (this.builtinAgentConfigRetryTimer) {
|
|
148982
|
+
return;
|
|
148983
|
+
}
|
|
148984
|
+
const delayMs = this.nextBuiltinAgentConfigRetryDelayMs();
|
|
148985
|
+
this.logger.debug(`[agent-config] Scheduling builtin agent registration retry in ${delayMs}ms for workspace ${this.workspaceId} machine ${this.machineId}`);
|
|
148986
|
+
this.builtinAgentConfigRetryTimer = setTimeout(() => {
|
|
148987
|
+
this.builtinAgentConfigRetryTimer = void 0;
|
|
148988
|
+
if (this.cleanedUp) {
|
|
148989
|
+
this.pendingBuiltinAgentConfigRetryCliTypes.clear();
|
|
148990
|
+
return;
|
|
148991
|
+
}
|
|
148992
|
+
const retryCliTypes = [
|
|
148993
|
+
...this.pendingBuiltinAgentConfigRetryCliTypes
|
|
148994
|
+
];
|
|
148995
|
+
this.pendingBuiltinAgentConfigRetryCliTypes.clear();
|
|
148996
|
+
void this.ensureBuiltinAgentConfigsOrRetry(retryCliTypes).catch((error2) => {
|
|
148997
|
+
this.logger.debug(`[agent-config] Retried builtin agent registration failed: ${formatErrorMessage(error2)}`);
|
|
148998
|
+
});
|
|
148999
|
+
}, delayMs);
|
|
149000
|
+
this.builtinAgentConfigRetryTimer.unref?.();
|
|
149001
|
+
}
|
|
149002
|
+
nextBuiltinAgentConfigRetryDelayMs() {
|
|
149003
|
+
const multiplier = 2 ** Math.min(this.builtinAgentConfigRetryAttempt, 5);
|
|
149004
|
+
this.builtinAgentConfigRetryAttempt += 1;
|
|
149005
|
+
return Math.min(BUILTIN_AGENT_CONFIG_INITIAL_RETRY_DELAY_MS * multiplier, BUILTIN_AGENT_CONFIG_MAX_RETRY_DELAY_MS);
|
|
148262
149006
|
}
|
|
148263
149007
|
async refreshBuiltinCapabilities(cliTypes) {
|
|
148264
149008
|
for (const cliType of cliTypes) {
|
|
@@ -148289,6 +149033,12 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
148289
149033
|
}
|
|
148290
149034
|
cleanup = async () => {
|
|
148291
149035
|
this.cleanedUp = true;
|
|
149036
|
+
if (this.builtinAgentConfigRetryTimer) {
|
|
149037
|
+
clearTimeout(this.builtinAgentConfigRetryTimer);
|
|
149038
|
+
this.builtinAgentConfigRetryTimer = void 0;
|
|
149039
|
+
}
|
|
149040
|
+
this.pendingBuiltinAgentConfigRetryCliTypes.clear();
|
|
149041
|
+
this.builtinAgentConfigRetryAttempt = 0;
|
|
148292
149042
|
return await this.runtime.cleanup();
|
|
148293
149043
|
};
|
|
148294
149044
|
async dispatchLocalControl(message) {
|
|
@@ -150498,10 +151248,16 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
150498
151248
|
rootPath: entry.rootPath,
|
|
150499
151249
|
createdAtMs: previous?.createdAtMs ?? nowMs2,
|
|
150500
151250
|
lastOpenedAtMs: nowMs2
|
|
150501
|
-
}, nowMs2
|
|
151251
|
+
}, nowMs2, {
|
|
151252
|
+
sync: runtime.lody.documentManager,
|
|
151253
|
+
reason: "local-project-add"
|
|
151254
|
+
});
|
|
150502
151255
|
}
|
|
150503
151256
|
async removeProjectMetaInWorkspace(runtime, localProjectId) {
|
|
150504
|
-
await removeMachineLocalProject(runtime.lody.documentManager.repo, runtime.workspace.id, this.machineId, localProjectId
|
|
151257
|
+
await removeMachineLocalProject(runtime.lody.documentManager.repo, runtime.workspace.id, this.machineId, localProjectId, void 0, {
|
|
151258
|
+
sync: runtime.lody.documentManager,
|
|
151259
|
+
reason: "local-project-delete"
|
|
151260
|
+
});
|
|
150505
151261
|
}
|
|
150506
151262
|
async listProjectsByWorkspace() {
|
|
150507
151263
|
const groups = [];
|
|
@@ -177371,6 +178127,29 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
177371
178127
|
throw new Error(`Workspace metadata changes were not confirmed by Loro Streams (${reason}). Retry the command after checking network connectivity.`);
|
|
177372
178128
|
}
|
|
177373
178129
|
}
|
|
178130
|
+
function buildOfflineHint(error2) {
|
|
178131
|
+
return new Error(`${formatErrorMessage(error2)} Use --offline to read the local cache without syncing.`, {
|
|
178132
|
+
cause: error2
|
|
178133
|
+
});
|
|
178134
|
+
}
|
|
178135
|
+
async function syncWorkspaceMetaForRead(manager, reason) {
|
|
178136
|
+
try {
|
|
178137
|
+
await manager.syncMetaOrThrow({
|
|
178138
|
+
reason
|
|
178139
|
+
});
|
|
178140
|
+
} catch (error2) {
|
|
178141
|
+
throw buildOfflineHint(error2);
|
|
178142
|
+
}
|
|
178143
|
+
}
|
|
178144
|
+
async function syncDocForRead(manager, docId, reason) {
|
|
178145
|
+
try {
|
|
178146
|
+
await manager.syncDocOrThrow(docId, {
|
|
178147
|
+
reason
|
|
178148
|
+
});
|
|
178149
|
+
} catch (error2) {
|
|
178150
|
+
throw buildOfflineHint(error2);
|
|
178151
|
+
}
|
|
178152
|
+
}
|
|
177374
178153
|
async function listAliveRoomIds(manager, predicate) {
|
|
177375
178154
|
const scanner = manager.repo.getMeta();
|
|
177376
178155
|
if (!scanner) {
|
|
@@ -177549,16 +178328,19 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
177549
178328
|
await action();
|
|
177550
178329
|
await exitOneShotCommand(0);
|
|
177551
178330
|
} catch (error2) {
|
|
178331
|
+
const commandError = error2 && typeof error2 === "object" ? error2 : void 0;
|
|
177552
178332
|
const message = formatErrorMessage(error2);
|
|
177553
|
-
if (
|
|
177554
|
-
|
|
177555
|
-
|
|
177556
|
-
|
|
177557
|
-
|
|
177558
|
-
|
|
177559
|
-
|
|
178333
|
+
if (commandError?.suppressCommandErrorOutput !== true) {
|
|
178334
|
+
if (options.json || options.jsonl) {
|
|
178335
|
+
printJson({
|
|
178336
|
+
ok: false,
|
|
178337
|
+
error: message
|
|
178338
|
+
});
|
|
178339
|
+
} else {
|
|
178340
|
+
getLogger(loggerName).error(message);
|
|
178341
|
+
}
|
|
177560
178342
|
}
|
|
177561
|
-
await exitOneShotCommand(1);
|
|
178343
|
+
await exitOneShotCommand(commandError?.exitCode ?? 1);
|
|
177562
178344
|
}
|
|
177563
178345
|
}
|
|
177564
178346
|
var debug_1;
|
|
@@ -180288,16 +181070,28 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
180288
181070
|
configOptionValues
|
|
180289
181071
|
};
|
|
180290
181072
|
}
|
|
180291
|
-
const agentConfigListCommand = new Command("list").description("List agent configs in a workspace").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--json", "Print JSON output").option("--debug", "Enable debug output").action(async (options) => {
|
|
181073
|
+
const agentConfigListCommand = new Command("list").description("List agent configs in a workspace").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--machine <idOrName>", "Only include configs for one machine").option("--json", "Print JSON output").option("--debug", "Enable debug output").action(async (options) => {
|
|
180292
181074
|
await runOneShotCommand("agent-config", options, async () => {
|
|
180293
181075
|
const auth = getAuthContextOrThrow$1("agent-config");
|
|
180294
181076
|
const workspace = await resolveWorkspaceOrThrow$1(auth, options.workspace);
|
|
180295
181077
|
await withWorkspaceManager$1(auth, workspace, "agent-config", async (manager) => {
|
|
180296
|
-
const
|
|
181078
|
+
const machineSelector = normalizeCliValue(options.machine);
|
|
181079
|
+
let machineId;
|
|
181080
|
+
if (machineSelector) {
|
|
181081
|
+
const machine = resolveMachineOrThrow(await listMachineMetasForWorkspace(manager), {
|
|
181082
|
+
selector: machineSelector,
|
|
181083
|
+
authMachineId: auth.machineId
|
|
181084
|
+
});
|
|
181085
|
+
machineId = machine.id;
|
|
181086
|
+
}
|
|
181087
|
+
const configs = (await listAgentConfigsForWorkspace$1(manager, workspace.id)).filter((config2) => machineId === void 0 || config2.machineId === machineId);
|
|
180297
181088
|
if (options.json) {
|
|
180298
181089
|
printJson({
|
|
180299
181090
|
ok: true,
|
|
180300
181091
|
workspaceId: workspace.id,
|
|
181092
|
+
...machineId ? {
|
|
181093
|
+
machineId
|
|
181094
|
+
} : {},
|
|
180301
181095
|
agentConfigs: configs.map(toAgentConfigOutput)
|
|
180302
181096
|
});
|
|
180303
181097
|
return;
|
|
@@ -180754,13 +181548,21 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
180754
181548
|
}
|
|
180755
181549
|
throw new Error(`Agent config not found: ${normalizedSelector}. Candidates: ${formatAgentConfigCandidates(configs)}`);
|
|
180756
181550
|
}
|
|
181551
|
+
function resolveCreateAgentSelector(options) {
|
|
181552
|
+
const agent2 = normalizeCliValue(options.agent);
|
|
181553
|
+
const agentConfig = normalizeCliValue(options.agentConfig);
|
|
181554
|
+
if (agent2 && agentConfig && agent2 !== agentConfig) {
|
|
181555
|
+
throw new Error("Pass either --agent or --agent-config, not both.");
|
|
181556
|
+
}
|
|
181557
|
+
return agentConfig ?? agent2;
|
|
181558
|
+
}
|
|
180757
181559
|
function buildAgentPrompt(prompt2, agentPrompt = "") {
|
|
180758
181560
|
return [
|
|
180759
181561
|
agentPrompt,
|
|
180760
181562
|
prompt2
|
|
180761
181563
|
].filter((part) => part?.trim()).join("\n\n");
|
|
180762
181564
|
}
|
|
180763
|
-
function parsePositiveIntOption(value) {
|
|
181565
|
+
function parsePositiveIntOption$1(value) {
|
|
180764
181566
|
const parsed = Number.parseInt(value, 10);
|
|
180765
181567
|
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
180766
181568
|
throw new Error(`Invalid numeric value: ${value}`);
|
|
@@ -180847,6 +181649,9 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
180847
181649
|
return entries.map((entry) => `[${entry.role}] ${entry.timestamp} ${entry.id}
|
|
180848
181650
|
${entry.text}`).join("\n\n");
|
|
180849
181651
|
}
|
|
181652
|
+
function renderAssistantTurnCompletion(content) {
|
|
181653
|
+
return extractTranscriptText(content, "assistant") ?? "No visible assistant reply found.";
|
|
181654
|
+
}
|
|
180850
181655
|
async function readStdinText() {
|
|
180851
181656
|
const chunks = [];
|
|
180852
181657
|
return await new Promise((resolve2, reject) => {
|
|
@@ -181147,15 +181952,22 @@ ${entry.text}`).join("\n\n");
|
|
|
181147
181952
|
const effectiveSelector = normalizeCliValue(selector) ?? normalizeCliValue(process.env.LODY_WORKSPACE_ID);
|
|
181148
181953
|
return selectWorkspaceSummary(workspaces, effectiveSelector);
|
|
181149
181954
|
}
|
|
181150
|
-
async function resolveWorkspaceForSessionOrThrow(auth, sessionId,
|
|
181955
|
+
async function resolveWorkspaceForSessionOrThrow(auth, sessionId, options) {
|
|
181151
181956
|
const workspaces = await listWorkspacesForToken(auth.token);
|
|
181957
|
+
const selector = typeof options === "string" ? options : options?.workspace;
|
|
181958
|
+
const shouldSync = typeof options === "object" && options.offline !== true;
|
|
181959
|
+
const syncReason = typeof options === "object" ? options.reason : void 0;
|
|
181152
181960
|
const effectiveSelector = normalizeCliValue(selector) ?? normalizeCliValue(process.env.LODY_WORKSPACE_ID);
|
|
181961
|
+
const sessionExistsInWorkspace = async (workspace) => await withWorkspaceManager(auth, workspace, async (manager) => {
|
|
181962
|
+
if (shouldSync) {
|
|
181963
|
+
await syncWorkspaceMetaForRead(manager, syncReason ?? `session.resolve:${sessionId}:${workspace.id}`);
|
|
181964
|
+
}
|
|
181965
|
+
const raw2 = await manager.repo.getDocMeta(getSessionRoomId(sessionId));
|
|
181966
|
+
return !!raw2?.meta && !isLoroRepoDocDeleted(raw2);
|
|
181967
|
+
});
|
|
181153
181968
|
if (effectiveSelector) {
|
|
181154
181969
|
const workspace = selectWorkspaceSummary(workspaces, effectiveSelector);
|
|
181155
|
-
const exists = await
|
|
181156
|
-
const raw2 = await manager.repo.getDocMeta(getSessionRoomId(sessionId));
|
|
181157
|
-
return !!raw2?.meta && !isLoroRepoDocDeleted(raw2);
|
|
181158
|
-
});
|
|
181970
|
+
const exists = await sessionExistsInWorkspace(workspace);
|
|
181159
181971
|
if (!exists) {
|
|
181160
181972
|
throw new Error(`Session not found in workspace ${workspace.id}: ${sessionId}`);
|
|
181161
181973
|
}
|
|
@@ -181163,10 +181975,7 @@ ${entry.text}`).join("\n\n");
|
|
|
181163
181975
|
}
|
|
181164
181976
|
if (workspaces.length === 1) {
|
|
181165
181977
|
const workspace = workspaces[0];
|
|
181166
|
-
const exists = await
|
|
181167
|
-
const raw2 = await manager.repo.getDocMeta(getSessionRoomId(sessionId));
|
|
181168
|
-
return !!raw2?.meta && !isLoroRepoDocDeleted(raw2);
|
|
181169
|
-
});
|
|
181978
|
+
const exists = await sessionExistsInWorkspace(workspace);
|
|
181170
181979
|
if (!exists) {
|
|
181171
181980
|
throw new Error(`Session not found: ${sessionId}`);
|
|
181172
181981
|
}
|
|
@@ -181174,10 +181983,7 @@ ${entry.text}`).join("\n\n");
|
|
|
181174
181983
|
}
|
|
181175
181984
|
const matches = [];
|
|
181176
181985
|
for (const workspace of workspaces) {
|
|
181177
|
-
const exists = await
|
|
181178
|
-
const raw2 = await manager.repo.getDocMeta(getSessionRoomId(sessionId));
|
|
181179
|
-
return !!raw2?.meta && !isLoroRepoDocDeleted(raw2);
|
|
181180
|
-
});
|
|
181986
|
+
const exists = await sessionExistsInWorkspace(workspace);
|
|
181181
181987
|
if (exists) {
|
|
181182
181988
|
matches.push(workspace);
|
|
181183
181989
|
}
|
|
@@ -181190,6 +181996,13 @@ ${entry.text}`).join("\n\n");
|
|
|
181190
181996
|
}
|
|
181191
181997
|
return matches[0];
|
|
181192
181998
|
}
|
|
181999
|
+
async function syncSessionReadData(manager, sessionId, offline, reason) {
|
|
182000
|
+
if (offline === true) {
|
|
182001
|
+
return;
|
|
182002
|
+
}
|
|
182003
|
+
await syncWorkspaceMetaForRead(manager, `${reason}:meta`);
|
|
182004
|
+
await syncDocForRead(manager, getSessionRoomId(sessionId), `${reason}:doc`);
|
|
182005
|
+
}
|
|
181193
182006
|
async function resolveSessionMetaOrThrow(manager, sessionId) {
|
|
181194
182007
|
const raw2 = await manager.repo.getDocMeta(getSessionRoomId(sessionId));
|
|
181195
182008
|
if (!raw2?.meta || isLoroRepoDocDeleted(raw2)) {
|
|
@@ -181524,6 +182337,37 @@ ${entry.text}`).join("\n\n");
|
|
|
181524
182337
|
messageQueueCount: docState?.mq?.length ?? 0
|
|
181525
182338
|
};
|
|
181526
182339
|
}
|
|
182340
|
+
async function buildSessionStatusResult(workspace, manager, sessionId) {
|
|
182341
|
+
const session = await resolveSessionMetaOrThrow(manager, sessionId);
|
|
182342
|
+
const sessionDoc = await manager.getOrCreateSessionDoc(sessionId);
|
|
182343
|
+
const history = await sessionDoc.getHistory();
|
|
182344
|
+
const assistantTurnId = resolveActiveAssistantTurnId(history);
|
|
182345
|
+
return {
|
|
182346
|
+
workspace,
|
|
182347
|
+
sessionId,
|
|
182348
|
+
status: session.status,
|
|
182349
|
+
machineId: session.machineId,
|
|
182350
|
+
agent: {
|
|
182351
|
+
cliType: session.cliType,
|
|
182352
|
+
agentType: session.agentType,
|
|
182353
|
+
...session.agentConfigId ? {
|
|
182354
|
+
agentConfigId: session.agentConfigId
|
|
182355
|
+
} : {}
|
|
182356
|
+
},
|
|
182357
|
+
archived: session.isArchived === true,
|
|
182358
|
+
...assistantTurnId ? {
|
|
182359
|
+
activeTurn: {
|
|
182360
|
+
assistantTurnId,
|
|
182361
|
+
...session.processingUserMsgId ? {
|
|
182362
|
+
processingUserMsgId: session.processingUserMsgId
|
|
182363
|
+
} : {},
|
|
182364
|
+
...session.latestUserMsgId ? {
|
|
182365
|
+
latestUserMsgId: session.latestUserMsgId
|
|
182366
|
+
} : {}
|
|
182367
|
+
}
|
|
182368
|
+
} : {}
|
|
182369
|
+
};
|
|
182370
|
+
}
|
|
181527
182371
|
function printHumanSessionList(sessions) {
|
|
181528
182372
|
if (sessions.length === 0) {
|
|
181529
182373
|
console.log("No sessions found.");
|
|
@@ -181571,6 +182415,16 @@ ${entry.text}`).join("\n\n");
|
|
|
181571
182415
|
console.log(`createdAt: ${session.createdAt}`);
|
|
181572
182416
|
console.log(`lastHistoryAt: ${result.latestHistoryAt ?? "-"}`);
|
|
181573
182417
|
}
|
|
182418
|
+
function printHumanSessionStatus(result) {
|
|
182419
|
+
console.log(`id: ${result.sessionId}`);
|
|
182420
|
+
console.log(`workspace: ${result.workspace.slug ?? result.workspace.id}`);
|
|
182421
|
+
console.log(`machine: ${result.machineId}`);
|
|
182422
|
+
console.log(`status: ${result.status?.type ?? "unknown"}`);
|
|
182423
|
+
console.log(`archived: ${result.archived ? "yes" : "no"}`);
|
|
182424
|
+
console.log(`agent: ${result.agent.cliType}/${result.agent.agentType}`);
|
|
182425
|
+
console.log(`agentConfigId: ${result.agent.agentConfigId ?? "-"}`);
|
|
182426
|
+
console.log(`activeTurn: ${result.activeTurn?.assistantTurnId ?? "-"}`);
|
|
182427
|
+
}
|
|
181574
182428
|
async function runSessionCommand(options, action) {
|
|
181575
182429
|
if (options.debug) {
|
|
181576
182430
|
rootLogger.setDebug(true);
|
|
@@ -181629,7 +182483,7 @@ ${entry.text}`).join("\n\n");
|
|
|
181629
182483
|
process.exit(code2);
|
|
181630
182484
|
}
|
|
181631
182485
|
}
|
|
181632
|
-
const sessionCreateCommand = new Command("create").description("Create a new session on the current machine").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--agent-config <idOrName>", "Agent config id or name").option("--title <title>", "Session title").option("--repo <owner/repo>", "GitHub repository to attach").option("--local-project <id|name|path>", "Local project id, name, or root path").option("--worktree", "Create an isolated git worktree for --local-project").option("--branch <name>", "Git branch to use for GitHub repos or local git projects").option("--mode <modeId>", "ACP mode override").option("--model <modelId>", "ACP model override").option("--env <keyValue>", "Deprecated per-session env override; configure env on the agent config instead", collectListOption, []).option("--prompt <text>", "Prompt text").option("--prompt-file <path>", "Read prompt text from file, or - for stdin").option("--json", "Print JSON output").option("--jsonl", "Print JSON Lines output").option("--timeout <seconds>", "Wait timeout in seconds for
|
|
182486
|
+
const sessionCreateCommand = new Command("create").description("Create a new session on the current machine").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--agent <idOrName>", "Agent config id or name").option("--agent-config <idOrName>", "Agent config id or name").option("--title <title>", "Session title").option("--repo <owner/repo>", "GitHub repository to attach").option("--local-project <id|name|path>", "Local project id, name, or root path").option("--worktree", "Create an isolated git worktree for --local-project").option("--branch <name>", "Git branch to use for GitHub repos or local git projects").option("--mode <modeId>", "ACP mode override").option("--model <modelId>", "ACP model override").option("--env <keyValue>", "Deprecated per-session env override; configure env on the agent config instead", collectListOption, []).option("--prompt <text>", "Prompt text").option("--prompt-file <path>", "Read prompt text from file, or - for stdin").option("--json", "Print JSON output").option("--jsonl", "Print JSON Lines output").option("--wait", "Wait for the assistant turn to complete before exiting").option("--timeout <seconds>", "Wait timeout in seconds for --wait, --json, and --jsonl", parsePositiveIntOption$1).option("--debug", "Enable debug output").argument("[prompt]", "Prompt text").action(async (promptArg, options) => {
|
|
181633
182487
|
await runSessionCommand(options, async () => {
|
|
181634
182488
|
const outputMode = resolveStructuredOutputMode(options);
|
|
181635
182489
|
const createStartMs = Date.now();
|
|
@@ -181642,12 +182496,16 @@ ${entry.text}`).join("\n\n");
|
|
|
181642
182496
|
const prompt2 = await readPromptText(options, promptArg);
|
|
181643
182497
|
await ensureLocalRuntimeAvailable(auth.machineId, workspace.id);
|
|
181644
182498
|
await withWorkspaceManager(auth, workspace, async (manager) => {
|
|
181645
|
-
const
|
|
182499
|
+
const agentSelector = resolveCreateAgentSelector(options);
|
|
182500
|
+
const agentConfig = await resolveAgentConfigOrThrow(manager, workspace.id, agentSelector);
|
|
181646
182501
|
const dispatchConfig = resolveTurnDispatchConfig({
|
|
181647
182502
|
mode: options.mode,
|
|
181648
182503
|
model: options.model
|
|
181649
182504
|
});
|
|
181650
|
-
const result = await createSessionResult(auth, workspace, manager, prompt2, options, agentConfig, dispatchConfig, outputMode === "human" ?
|
|
182505
|
+
const result = await createSessionResult(auth, workspace, manager, prompt2, options, agentConfig, dispatchConfig, outputMode === "human" ? options.wait === true ? {
|
|
182506
|
+
outputMode: "json",
|
|
182507
|
+
timeoutMs: resolveStructuredOutputTimeoutMs(options.timeout)
|
|
182508
|
+
} : void 0 : {
|
|
181651
182509
|
outputMode,
|
|
181652
182510
|
timeoutMs: resolveStructuredOutputTimeoutMs(options.timeout),
|
|
181653
182511
|
onEvent: outputMode === "jsonl" ? (event) => printJson(event) : void 0
|
|
@@ -181698,13 +182556,29 @@ ${entry.text}`).join("\n\n");
|
|
|
181698
182556
|
}
|
|
181699
182557
|
return;
|
|
181700
182558
|
}
|
|
182559
|
+
console.log(result.sessionId);
|
|
182560
|
+
if (options.wait === true) {
|
|
182561
|
+
const completionPromise = result.completionPromise;
|
|
182562
|
+
if (!completionPromise) {
|
|
182563
|
+
throw new Error("Missing completion promise for session create --wait output.");
|
|
182564
|
+
}
|
|
182565
|
+
const completedTurn = await completionPromise;
|
|
182566
|
+
captureSessionCommandEvent("session_create_succeeded", {
|
|
182567
|
+
output_mode: outputMode,
|
|
182568
|
+
turn_duration_ms: completedTurn.durationMs
|
|
182569
|
+
}, {
|
|
182570
|
+
distinctId: auth.machineId
|
|
182571
|
+
});
|
|
182572
|
+
console.log("");
|
|
182573
|
+
console.log(renderAssistantTurnCompletion(completedTurn.content));
|
|
182574
|
+
return;
|
|
182575
|
+
}
|
|
181701
182576
|
captureSessionCommandEvent("session_create_succeeded", {
|
|
181702
182577
|
output_mode: outputMode,
|
|
181703
182578
|
turn_duration_ms: Date.now() - createStartMs
|
|
181704
182579
|
}, {
|
|
181705
182580
|
distinctId: auth.machineId
|
|
181706
182581
|
});
|
|
181707
|
-
console.log(result.sessionId);
|
|
181708
182582
|
});
|
|
181709
182583
|
} catch (error2) {
|
|
181710
182584
|
captureSessionCommandEvent("session_create_failed", {
|
|
@@ -181715,7 +182589,7 @@ ${entry.text}`).join("\n\n");
|
|
|
181715
182589
|
}
|
|
181716
182590
|
});
|
|
181717
182591
|
});
|
|
181718
|
-
const sessionChatCommand = new Command("chat").description("Send a new user prompt to an existing session on the current machine").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--mode <modeId>", "ACP mode override").option("--model <modelId>", "ACP model override").option("--prompt <text>", "Prompt text").option("--prompt-file <path>", "Read prompt text from file, or - for stdin").option("--json", "Print JSON output").option("--jsonl", "Print JSON Lines output").option("--timeout <seconds>", "Wait timeout in seconds for
|
|
182592
|
+
const sessionChatCommand = new Command("chat").description("Send a new user prompt to an existing session on the current machine").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--mode <modeId>", "ACP mode override").option("--model <modelId>", "ACP model override").option("--prompt <text>", "Prompt text").option("--prompt-file <path>", "Read prompt text from file, or - for stdin").option("--json", "Print JSON output").option("--jsonl", "Print JSON Lines output").option("--wait", "Wait for the assistant turn to complete before exiting").option("--timeout <seconds>", "Wait timeout in seconds for --wait, --json, and --jsonl", parsePositiveIntOption$1).option("--debug", "Enable debug output").argument("[sessionId]", "Session ID; falls back to LODY_SESSION_ID").argument("[prompt]", "Prompt text").action(async (sessionIdArg, promptArg, options) => {
|
|
181719
182593
|
await runSessionCommand(options, async () => {
|
|
181720
182594
|
const outputMode = resolveStructuredOutputMode(options);
|
|
181721
182595
|
const auth = getAuthContextOrThrow();
|
|
@@ -181762,15 +182636,16 @@ ${entry.text}`).join("\n\n");
|
|
|
181762
182636
|
configOptionValues: dispatchConfig.configOptionValues,
|
|
181763
182637
|
resume: session.acpSessionId ?? void 0
|
|
181764
182638
|
}));
|
|
181765
|
-
const
|
|
181766
|
-
const
|
|
182639
|
+
const shouldWaitForCompletion = outputMode !== "human" || options.wait === true;
|
|
182640
|
+
const completionAbortController = shouldWaitForCompletion ? new AbortController() : void 0;
|
|
182641
|
+
const completionPromise = shouldWaitForCompletion ? waitForTurnCompletion({
|
|
181767
182642
|
sessionDoc,
|
|
181768
182643
|
userTurnId,
|
|
181769
|
-
outputMode,
|
|
182644
|
+
outputMode: outputMode === "human" ? "json" : outputMode,
|
|
181770
182645
|
timeoutMs: resolveStructuredOutputTimeoutMs(options.timeout),
|
|
181771
182646
|
signal: completionAbortController?.signal,
|
|
181772
182647
|
onEvent: outputMode === "jsonl" ? (event) => printJson(event) : void 0
|
|
181773
|
-
});
|
|
182648
|
+
}) : void 0;
|
|
181774
182649
|
try {
|
|
181775
182650
|
await updateSessionActivityTimestampsBestEffort(manager, sessionId);
|
|
181776
182651
|
await ensureSessionDocSynced(sessionDoc, `session.chat:${sessionId}:${userTurnId}`);
|
|
@@ -181811,6 +182686,18 @@ ${entry.text}`).join("\n\n");
|
|
|
181811
182686
|
}
|
|
181812
182687
|
return;
|
|
181813
182688
|
}
|
|
182689
|
+
if (options.wait === true) {
|
|
182690
|
+
try {
|
|
182691
|
+
if (!completionPromise) {
|
|
182692
|
+
throw new Error("Missing completion promise for session chat --wait output.");
|
|
182693
|
+
}
|
|
182694
|
+
const completedTurn = await completionPromise;
|
|
182695
|
+
console.log(renderAssistantTurnCompletion(completedTurn.content));
|
|
182696
|
+
} catch (error2) {
|
|
182697
|
+
throw buildStructuredWaitError("json", sessionId, userTurnId, error2);
|
|
182698
|
+
}
|
|
182699
|
+
return;
|
|
182700
|
+
}
|
|
181814
182701
|
console.log(userTurnId);
|
|
181815
182702
|
});
|
|
181816
182703
|
});
|
|
@@ -181852,11 +182739,14 @@ ${entry.text}`).join("\n\n");
|
|
|
181852
182739
|
});
|
|
181853
182740
|
});
|
|
181854
182741
|
});
|
|
181855
|
-
const sessionListCommand = new Command("list").description("List sessions in a workspace").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--archived", "Only include archived sessions").option("--all", "Include active and archived sessions").option("--limit <count>", "Maximum number of sessions to print", parsePositiveIntOption).option("--json", "Print JSON output").option("--debug", "Enable debug output").action(async (options) => {
|
|
182742
|
+
const sessionListCommand = new Command("list").description("List sessions in a workspace").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--archived", "Only include archived sessions").option("--all", "Include active and archived sessions").option("--limit <count>", "Maximum number of sessions to print", parsePositiveIntOption$1).option("--offline", "Read the local cache without syncing first").option("--json", "Print JSON output").option("--debug", "Enable debug output").action(async (options) => {
|
|
181856
182743
|
await runSessionCommand(options, async () => {
|
|
181857
182744
|
const auth = getAuthContextOrThrow();
|
|
181858
182745
|
const workspace = await resolveWorkspaceOrThrow(auth, options.workspace);
|
|
181859
182746
|
await withWorkspaceManager(auth, workspace, async (manager) => {
|
|
182747
|
+
if (options.offline !== true) {
|
|
182748
|
+
await syncWorkspaceMetaForRead(manager, `session.list:${workspace.id}`);
|
|
182749
|
+
}
|
|
181860
182750
|
const sessions = sortSessionMetas(filterSessionMetas(await listSessionMetasForWorkspace(manager), {
|
|
181861
182751
|
archivedOnly: options.archived,
|
|
181862
182752
|
includeAll: options.all
|
|
@@ -181874,7 +182764,7 @@ ${entry.text}`).join("\n\n");
|
|
|
181874
182764
|
});
|
|
181875
182765
|
});
|
|
181876
182766
|
});
|
|
181877
|
-
const sessionHistoryCommand = new Command("history").description("Read visible session transcript history").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--limit <count>", "Maximum number of transcript turns to print", parsePositiveIntOption).option("--all", "Include all transcript turns").option("--reverse", "Print newest transcript turns first").option("--json", "Print JSON output").option("--jsonl", "Print JSON Lines output").option("--debug", "Enable debug output").argument("[sessionId]", "Session ID; falls back to LODY_SESSION_ID").action(async (sessionIdArg, options) => {
|
|
182767
|
+
const sessionHistoryCommand = new Command("history").description("Read visible session transcript history").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--limit <count>", "Maximum number of transcript turns to print", parsePositiveIntOption$1).option("--all", "Include all transcript turns").option("--reverse", "Print newest transcript turns first").option("--offline", "Read the local cache without syncing first").option("--json", "Print JSON output").option("--jsonl", "Print JSON Lines output").option("--debug", "Enable debug output").argument("[sessionId]", "Session ID; falls back to LODY_SESSION_ID").action(async (sessionIdArg, options) => {
|
|
181878
182768
|
await runSessionCommand(options, async () => {
|
|
181879
182769
|
const outputMode = resolveStructuredOutputMode(options);
|
|
181880
182770
|
if (options.all && typeof options.limit === "number") {
|
|
@@ -181885,8 +182775,13 @@ ${entry.text}`).join("\n\n");
|
|
|
181885
182775
|
if (!sessionId) {
|
|
181886
182776
|
throw new Error("Missing session ID. Pass one explicitly or set LODY_SESSION_ID.");
|
|
181887
182777
|
}
|
|
181888
|
-
const workspace = await resolveWorkspaceForSessionOrThrow(auth, sessionId,
|
|
182778
|
+
const workspace = await resolveWorkspaceForSessionOrThrow(auth, sessionId, {
|
|
182779
|
+
workspace: options.workspace,
|
|
182780
|
+
offline: options.offline,
|
|
182781
|
+
reason: `session.history.resolve:${sessionId}`
|
|
182782
|
+
});
|
|
181889
182783
|
await withWorkspaceManager(auth, workspace, async (manager) => {
|
|
182784
|
+
await syncSessionReadData(manager, sessionId, options.offline, `session.history:${sessionId}`);
|
|
181890
182785
|
await resolveSessionMetaOrThrow(manager, sessionId);
|
|
181891
182786
|
const sessionDoc = await manager.getOrCreateSessionDoc(sessionId);
|
|
181892
182787
|
const transcript = toSessionTranscriptEntries(await sessionDoc.getHistory());
|
|
@@ -181920,15 +182815,20 @@ ${entry.text}`).join("\n\n");
|
|
|
181920
182815
|
});
|
|
181921
182816
|
});
|
|
181922
182817
|
});
|
|
181923
|
-
const sessionShowCommand = new Command("show").description("Show session metadata").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--json", "Print JSON output").option("--debug", "Enable debug output").argument("[sessionId]", "Session ID; falls back to LODY_SESSION_ID").action(async (sessionIdArg, options) => {
|
|
182818
|
+
const sessionShowCommand = new Command("show").description("Show session metadata").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--offline", "Read the local cache without syncing first").option("--json", "Print JSON output").option("--debug", "Enable debug output").argument("[sessionId]", "Session ID; falls back to LODY_SESSION_ID").action(async (sessionIdArg, options) => {
|
|
181924
182819
|
await runSessionCommand(options, async () => {
|
|
181925
182820
|
const auth = getAuthContextOrThrow();
|
|
181926
182821
|
const sessionId = normalizeCliValue(sessionIdArg) ?? normalizeCliValue(process.env.LODY_SESSION_ID);
|
|
181927
182822
|
if (!sessionId) {
|
|
181928
182823
|
throw new Error("Missing session ID. Pass one explicitly or set LODY_SESSION_ID.");
|
|
181929
182824
|
}
|
|
181930
|
-
const workspace = await resolveWorkspaceForSessionOrThrow(auth, sessionId,
|
|
182825
|
+
const workspace = await resolveWorkspaceForSessionOrThrow(auth, sessionId, {
|
|
182826
|
+
workspace: options.workspace,
|
|
182827
|
+
offline: options.offline,
|
|
182828
|
+
reason: `session.show.resolve:${sessionId}`
|
|
182829
|
+
});
|
|
181931
182830
|
await withWorkspaceManager(auth, workspace, async (manager) => {
|
|
182831
|
+
await syncSessionReadData(manager, sessionId, options.offline, `session.show:${sessionId}`);
|
|
181932
182832
|
const result = await buildSessionShowResult(workspace, manager, sessionId);
|
|
181933
182833
|
if (options.json) {
|
|
181934
182834
|
printJson({
|
|
@@ -181941,6 +182841,32 @@ ${entry.text}`).join("\n\n");
|
|
|
181941
182841
|
});
|
|
181942
182842
|
});
|
|
181943
182843
|
});
|
|
182844
|
+
const sessionStatusCommand = new Command("status").description("Show current session status").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--offline", "Read the local cache without syncing first").option("--json", "Print JSON output").option("--debug", "Enable debug output").argument("[sessionId]", "Session ID; falls back to LODY_SESSION_ID").action(async (sessionIdArg, options) => {
|
|
182845
|
+
await runSessionCommand(options, async () => {
|
|
182846
|
+
const auth = getAuthContextOrThrow();
|
|
182847
|
+
const sessionId = normalizeCliValue(sessionIdArg) ?? normalizeCliValue(process.env.LODY_SESSION_ID);
|
|
182848
|
+
if (!sessionId) {
|
|
182849
|
+
throw new Error("Missing session ID. Pass one explicitly or set LODY_SESSION_ID.");
|
|
182850
|
+
}
|
|
182851
|
+
const workspace = await resolveWorkspaceForSessionOrThrow(auth, sessionId, {
|
|
182852
|
+
workspace: options.workspace,
|
|
182853
|
+
offline: options.offline,
|
|
182854
|
+
reason: `session.status.resolve:${sessionId}`
|
|
182855
|
+
});
|
|
182856
|
+
await withWorkspaceManager(auth, workspace, async (manager) => {
|
|
182857
|
+
await syncSessionReadData(manager, sessionId, options.offline, `session.status:${sessionId}`);
|
|
182858
|
+
const result = await buildSessionStatusResult(workspace, manager, sessionId);
|
|
182859
|
+
if (options.json) {
|
|
182860
|
+
printJson({
|
|
182861
|
+
ok: true,
|
|
182862
|
+
...result
|
|
182863
|
+
});
|
|
182864
|
+
return;
|
|
182865
|
+
}
|
|
182866
|
+
printHumanSessionStatus(result);
|
|
182867
|
+
});
|
|
182868
|
+
});
|
|
182869
|
+
});
|
|
181944
182870
|
const sessionRenameCommand = new Command("rename").description("Rename a session").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--title <title>", "New session title").option("--json", "Print JSON output").option("--debug", "Enable debug output").argument("[sessionId]", "Session ID; falls back to LODY_SESSION_ID").argument("[title]", "New session title").action(async (sessionIdArg, titleArg, options) => {
|
|
181945
182871
|
await runSessionCommand(options, async () => {
|
|
181946
182872
|
const auth = getAuthContextOrThrow();
|
|
@@ -182149,7 +183075,270 @@ ${entry.text}`).join("\n\n");
|
|
|
182149
183075
|
});
|
|
182150
183076
|
});
|
|
182151
183077
|
});
|
|
182152
|
-
const sessionCommand = new Command("session").description("Manage sessions without the web UI").addCommand(sessionCreateCommand).addCommand(sessionChatCommand).addCommand(sessionCancelCommand).addCommand(sessionListCommand).addCommand(sessionHistoryCommand).addCommand(sessionShowCommand).addCommand(sessionRenameCommand).addCommand(sessionArchiveCommand).addCommand(sessionRestoreCommand).addCommand(sessionDeleteCommand);
|
|
183078
|
+
const sessionCommand = new Command("session").description("Manage sessions without the web UI").addCommand(sessionCreateCommand).addCommand(sessionChatCommand).addCommand(sessionCancelCommand).addCommand(sessionListCommand).addCommand(sessionHistoryCommand).addCommand(sessionShowCommand).addCommand(sessionStatusCommand).addCommand(sessionRenameCommand).addCommand(sessionArchiveCommand).addCommand(sessionRestoreCommand).addCommand(sessionDeleteCommand);
|
|
183079
|
+
async function mapWithConcurrency(items2, concurrency, worker) {
|
|
183080
|
+
if (items2.length === 0) {
|
|
183081
|
+
return [];
|
|
183082
|
+
}
|
|
183083
|
+
const limit2 = Math.max(1, Math.floor(concurrency));
|
|
183084
|
+
const results = new Array(items2.length);
|
|
183085
|
+
let nextIndex = 0;
|
|
183086
|
+
const runWorker = async () => {
|
|
183087
|
+
while (nextIndex < items2.length) {
|
|
183088
|
+
const currentIndex = nextIndex;
|
|
183089
|
+
nextIndex += 1;
|
|
183090
|
+
results[currentIndex] = await worker(items2[currentIndex], currentIndex);
|
|
183091
|
+
}
|
|
183092
|
+
};
|
|
183093
|
+
await Promise.all(Array.from({
|
|
183094
|
+
length: Math.min(limit2, items2.length)
|
|
183095
|
+
}, () => runWorker()));
|
|
183096
|
+
return results;
|
|
183097
|
+
}
|
|
183098
|
+
const DEFAULT_SYNC_CONCURRENCY = 4;
|
|
183099
|
+
function parsePositiveIntOption(value) {
|
|
183100
|
+
const parsed = Number.parseInt(value, 10);
|
|
183101
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
183102
|
+
throw new Error(`Invalid numeric value: ${value}`);
|
|
183103
|
+
}
|
|
183104
|
+
return parsed;
|
|
183105
|
+
}
|
|
183106
|
+
function createWorkspaceSummary(workspaceId) {
|
|
183107
|
+
return {
|
|
183108
|
+
workspaceId,
|
|
183109
|
+
totals: {
|
|
183110
|
+
meta: 0,
|
|
183111
|
+
doc: 0,
|
|
183112
|
+
flock: 0
|
|
183113
|
+
},
|
|
183114
|
+
completed: {
|
|
183115
|
+
meta: 0,
|
|
183116
|
+
doc: 0,
|
|
183117
|
+
flock: 0
|
|
183118
|
+
},
|
|
183119
|
+
failed: {
|
|
183120
|
+
meta: 0,
|
|
183121
|
+
doc: 0,
|
|
183122
|
+
flock: 0
|
|
183123
|
+
},
|
|
183124
|
+
failures: []
|
|
183125
|
+
};
|
|
183126
|
+
}
|
|
183127
|
+
function mergeSummaries(workspaces) {
|
|
183128
|
+
const failures2 = workspaces.flatMap((workspace) => workspace.failures);
|
|
183129
|
+
let total = 0;
|
|
183130
|
+
let completed = 0;
|
|
183131
|
+
let failed = 0;
|
|
183132
|
+
for (const workspace of workspaces) {
|
|
183133
|
+
for (const kind of [
|
|
183134
|
+
"meta",
|
|
183135
|
+
"doc",
|
|
183136
|
+
"flock"
|
|
183137
|
+
]) {
|
|
183138
|
+
total += workspace.totals[kind];
|
|
183139
|
+
completed += workspace.completed[kind];
|
|
183140
|
+
failed += workspace.failed[kind];
|
|
183141
|
+
}
|
|
183142
|
+
}
|
|
183143
|
+
return {
|
|
183144
|
+
ok: failures2.length === 0,
|
|
183145
|
+
workspaces,
|
|
183146
|
+
total,
|
|
183147
|
+
completed,
|
|
183148
|
+
failed,
|
|
183149
|
+
failures: failures2
|
|
183150
|
+
};
|
|
183151
|
+
}
|
|
183152
|
+
function buildProgressEvent(input2) {
|
|
183153
|
+
return {
|
|
183154
|
+
type: "progress",
|
|
183155
|
+
workspaceId: input2.workspaceId,
|
|
183156
|
+
kind: input2.kind,
|
|
183157
|
+
id: input2.id,
|
|
183158
|
+
total: input2.total,
|
|
183159
|
+
completed: input2.completed,
|
|
183160
|
+
failed: input2.failed,
|
|
183161
|
+
remaining: Math.max(0, input2.total - input2.completed - input2.failed),
|
|
183162
|
+
ok: input2.ok,
|
|
183163
|
+
...input2.error ? {
|
|
183164
|
+
error: input2.error
|
|
183165
|
+
} : {}
|
|
183166
|
+
};
|
|
183167
|
+
}
|
|
183168
|
+
function printHumanProgress(event) {
|
|
183169
|
+
const status = event.ok ? "synced" : "failed";
|
|
183170
|
+
const failedText = event.failed > 0 ? `, failed ${event.failed}` : "";
|
|
183171
|
+
console.log(`[${event.workspaceId}] ${event.kind} ${event.id}: ${status} (${event.completed}/${event.total}${failedText})`);
|
|
183172
|
+
if (event.error) {
|
|
183173
|
+
console.log(` ${event.error}`);
|
|
183174
|
+
}
|
|
183175
|
+
}
|
|
183176
|
+
function emitProgress(event, outputMode) {
|
|
183177
|
+
if (outputMode === "jsonl") {
|
|
183178
|
+
printJson(event);
|
|
183179
|
+
return;
|
|
183180
|
+
}
|
|
183181
|
+
if (outputMode === "human") {
|
|
183182
|
+
printHumanProgress(event);
|
|
183183
|
+
}
|
|
183184
|
+
}
|
|
183185
|
+
function recordSyncResult(args2) {
|
|
183186
|
+
if (args2.ok) {
|
|
183187
|
+
args2.summary.completed[args2.kind] += 1;
|
|
183188
|
+
} else {
|
|
183189
|
+
args2.summary.failed[args2.kind] += 1;
|
|
183190
|
+
args2.summary.failures.push({
|
|
183191
|
+
workspaceId: args2.summary.workspaceId,
|
|
183192
|
+
kind: args2.kind,
|
|
183193
|
+
id: args2.id,
|
|
183194
|
+
error: args2.error ?? "Sync failed."
|
|
183195
|
+
});
|
|
183196
|
+
}
|
|
183197
|
+
emitProgress(buildProgressEvent({
|
|
183198
|
+
workspaceId: args2.summary.workspaceId,
|
|
183199
|
+
kind: args2.kind,
|
|
183200
|
+
id: args2.id,
|
|
183201
|
+
total: args2.summary.totals[args2.kind],
|
|
183202
|
+
completed: args2.summary.completed[args2.kind],
|
|
183203
|
+
failed: args2.summary.failed[args2.kind],
|
|
183204
|
+
ok: args2.ok,
|
|
183205
|
+
error: args2.error
|
|
183206
|
+
}), args2.outputMode);
|
|
183207
|
+
}
|
|
183208
|
+
async function syncItems(input2) {
|
|
183209
|
+
input2.summary.totals[input2.kind] = input2.ids.length;
|
|
183210
|
+
await mapWithConcurrency(input2.ids, input2.concurrency, async (id2) => {
|
|
183211
|
+
try {
|
|
183212
|
+
await input2.syncOne(id2);
|
|
183213
|
+
recordSyncResult({
|
|
183214
|
+
summary: input2.summary,
|
|
183215
|
+
kind: input2.kind,
|
|
183216
|
+
id: id2,
|
|
183217
|
+
ok: true,
|
|
183218
|
+
outputMode: input2.outputMode
|
|
183219
|
+
});
|
|
183220
|
+
} catch (error2) {
|
|
183221
|
+
recordSyncResult({
|
|
183222
|
+
summary: input2.summary,
|
|
183223
|
+
kind: input2.kind,
|
|
183224
|
+
id: id2,
|
|
183225
|
+
ok: false,
|
|
183226
|
+
error: formatErrorMessage(error2),
|
|
183227
|
+
outputMode: input2.outputMode
|
|
183228
|
+
});
|
|
183229
|
+
}
|
|
183230
|
+
});
|
|
183231
|
+
}
|
|
183232
|
+
async function listMachineFlockDocIds(manager, workspaceId) {
|
|
183233
|
+
const machines = await listAliveDocMetas(manager, isMachineDocRoomId);
|
|
183234
|
+
return machines.map((entry) => getMachineFlockDocId(workspaceId, entry.meta.id)).sort((left2, right2) => left2.localeCompare(right2));
|
|
183235
|
+
}
|
|
183236
|
+
async function syncWorkspace(input2) {
|
|
183237
|
+
const workspaceId = input2.workspace.id;
|
|
183238
|
+
const summary2 = createWorkspaceSummary(input2.workspace.id);
|
|
183239
|
+
await withWorkspaceManager$1(input2.auth, input2.workspace, "sync", async (manager) => {
|
|
183240
|
+
summary2.totals.meta = 1;
|
|
183241
|
+
try {
|
|
183242
|
+
await manager.syncMetaOrThrow({
|
|
183243
|
+
reason: `sync:${workspaceId}:meta`
|
|
183244
|
+
});
|
|
183245
|
+
recordSyncResult({
|
|
183246
|
+
summary: summary2,
|
|
183247
|
+
kind: "meta",
|
|
183248
|
+
id: "meta",
|
|
183249
|
+
ok: true,
|
|
183250
|
+
outputMode: input2.outputMode
|
|
183251
|
+
});
|
|
183252
|
+
} catch (error2) {
|
|
183253
|
+
recordSyncResult({
|
|
183254
|
+
summary: summary2,
|
|
183255
|
+
kind: "meta",
|
|
183256
|
+
id: "meta",
|
|
183257
|
+
ok: false,
|
|
183258
|
+
error: formatErrorMessage(error2),
|
|
183259
|
+
outputMode: input2.outputMode
|
|
183260
|
+
});
|
|
183261
|
+
return;
|
|
183262
|
+
}
|
|
183263
|
+
const docIds = (await listAliveRoomIds(manager, () => true)).sort((left2, right2) => left2.localeCompare(right2));
|
|
183264
|
+
const flockDocIds = await listMachineFlockDocIds(manager, workspaceId);
|
|
183265
|
+
await syncItems({
|
|
183266
|
+
summary: summary2,
|
|
183267
|
+
kind: "doc",
|
|
183268
|
+
ids: docIds,
|
|
183269
|
+
concurrency: input2.concurrency,
|
|
183270
|
+
outputMode: input2.outputMode,
|
|
183271
|
+
syncOne: async (id2) => {
|
|
183272
|
+
await manager.syncDocOrThrow(id2, {
|
|
183273
|
+
reason: `sync:${workspaceId}:doc:${id2}`
|
|
183274
|
+
});
|
|
183275
|
+
}
|
|
183276
|
+
});
|
|
183277
|
+
await syncItems({
|
|
183278
|
+
summary: summary2,
|
|
183279
|
+
kind: "flock",
|
|
183280
|
+
ids: flockDocIds,
|
|
183281
|
+
concurrency: input2.concurrency,
|
|
183282
|
+
outputMode: input2.outputMode,
|
|
183283
|
+
syncOne: async (id2) => {
|
|
183284
|
+
await manager.syncFlockDocOrThrow(id2, {
|
|
183285
|
+
reason: `sync:${workspaceId}:flock:${id2}`
|
|
183286
|
+
});
|
|
183287
|
+
}
|
|
183288
|
+
});
|
|
183289
|
+
});
|
|
183290
|
+
return summary2;
|
|
183291
|
+
}
|
|
183292
|
+
function printHumanSummary(summary2) {
|
|
183293
|
+
console.log(`Finished sync: ${summary2.completed}/${summary2.total} item(s) synced, ${summary2.failed} failed.`);
|
|
183294
|
+
if (summary2.failures.length > 0) {
|
|
183295
|
+
console.log("Failures:");
|
|
183296
|
+
for (const failure of summary2.failures) {
|
|
183297
|
+
console.log(`- [${failure.workspaceId}] ${failure.kind} ${failure.id}: ${failure.error}`);
|
|
183298
|
+
}
|
|
183299
|
+
}
|
|
183300
|
+
}
|
|
183301
|
+
function createAlreadyPrintedError() {
|
|
183302
|
+
return Object.assign(new Error("Sync completed with failures."), {
|
|
183303
|
+
suppressCommandErrorOutput: true,
|
|
183304
|
+
exitCode: 1
|
|
183305
|
+
});
|
|
183306
|
+
}
|
|
183307
|
+
const syncCommand = new Command("sync").description("Sync workspace Loro data to the local cache").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--all-workspace", "Sync all accessible workspaces").option("--concurrency <count>", "Maximum number of documents to sync concurrently", parsePositiveIntOption, DEFAULT_SYNC_CONCURRENCY).option("--json", "Print final JSON summary").option("--jsonl", "Print JSON Lines progress events and final summary").option("--debug", "Enable debug output").action(async (options) => {
|
|
183308
|
+
await runOneShotCommand("sync", options, async () => {
|
|
183309
|
+
const outputMode = resolveStructuredOutputMode$1(options);
|
|
183310
|
+
const auth = getAuthContextOrThrow$1("sync");
|
|
183311
|
+
if (options.allWorkspace && options.workspace) {
|
|
183312
|
+
throw new Error("Pass either --workspace or --all-workspace, not both.");
|
|
183313
|
+
}
|
|
183314
|
+
const workspaces = options.allWorkspace ? await listWorkspacesForToken(auth.token) : [
|
|
183315
|
+
await resolveWorkspaceOrThrow$1(auth, options.workspace)
|
|
183316
|
+
];
|
|
183317
|
+
const workspaceSummaries = [];
|
|
183318
|
+
for (const workspace of workspaces) {
|
|
183319
|
+
workspaceSummaries.push(await syncWorkspace({
|
|
183320
|
+
auth,
|
|
183321
|
+
workspace,
|
|
183322
|
+
concurrency: options.concurrency ?? DEFAULT_SYNC_CONCURRENCY,
|
|
183323
|
+
outputMode
|
|
183324
|
+
}));
|
|
183325
|
+
}
|
|
183326
|
+
const summary2 = mergeSummaries(workspaceSummaries);
|
|
183327
|
+
if (outputMode === "jsonl") {
|
|
183328
|
+
printJson({
|
|
183329
|
+
type: "summary",
|
|
183330
|
+
...summary2
|
|
183331
|
+
});
|
|
183332
|
+
} else if (outputMode === "json") {
|
|
183333
|
+
printJson(summary2);
|
|
183334
|
+
} else {
|
|
183335
|
+
printHumanSummary(summary2);
|
|
183336
|
+
}
|
|
183337
|
+
if (!summary2.ok) {
|
|
183338
|
+
throw createAlreadyPrintedError();
|
|
183339
|
+
}
|
|
183340
|
+
});
|
|
183341
|
+
});
|
|
182153
183342
|
function sortWorkspaceSummaries(workspaces) {
|
|
182154
183343
|
return [
|
|
182155
183344
|
...workspaces
|
|
@@ -182291,19 +183480,53 @@ ${entry.text}`).join("\n\n");
|
|
|
182291
183480
|
} : {}
|
|
182292
183481
|
};
|
|
182293
183482
|
}
|
|
182294
|
-
function toMachineJsonEntry(machine,
|
|
182295
|
-
|
|
182296
|
-
|
|
183483
|
+
function toMachineJsonEntry(machine, options) {
|
|
183484
|
+
const withoutOptional = {
|
|
183485
|
+
...machine
|
|
183486
|
+
};
|
|
183487
|
+
if (!options.includeAcpCapabilities) {
|
|
183488
|
+
delete withoutOptional.acpCapabilities;
|
|
182297
183489
|
}
|
|
182298
|
-
|
|
182299
|
-
|
|
183490
|
+
if (!options.includeAgents) {
|
|
183491
|
+
delete withoutOptional.agentConfigs;
|
|
183492
|
+
}
|
|
183493
|
+
return withoutOptional;
|
|
183494
|
+
}
|
|
183495
|
+
function formatMachineAgents(machine) {
|
|
183496
|
+
const configs = machine.agentConfigs ?? [];
|
|
183497
|
+
if (configs.length === 0) {
|
|
183498
|
+
return "-";
|
|
183499
|
+
}
|
|
183500
|
+
return configs.map((config2) => `${config2.name} (${config2.agentType})`).join(",");
|
|
182300
183501
|
}
|
|
182301
|
-
function
|
|
183502
|
+
async function attachAgentConfigsToMachines(repo, workspaceId, machines) {
|
|
183503
|
+
const configs = await listMergedAgentConfigs(repo, workspaceId, machines.map((machine) => machine.id));
|
|
183504
|
+
const configsByMachine = /* @__PURE__ */ new Map();
|
|
183505
|
+
for (const config2 of configs) {
|
|
183506
|
+
const current2 = configsByMachine.get(config2.machineId) ?? [];
|
|
183507
|
+
current2.push(config2);
|
|
183508
|
+
configsByMachine.set(config2.machineId, current2);
|
|
183509
|
+
}
|
|
183510
|
+
for (const values of configsByMachine.values()) {
|
|
183511
|
+
values.sort((left2, right2) => {
|
|
183512
|
+
const nameCompare = left2.name.localeCompare(right2.name);
|
|
183513
|
+
if (nameCompare !== 0) {
|
|
183514
|
+
return nameCompare;
|
|
183515
|
+
}
|
|
183516
|
+
return left2.id.localeCompare(right2.id);
|
|
183517
|
+
});
|
|
183518
|
+
}
|
|
183519
|
+
return machines.map((machine) => ({
|
|
183520
|
+
...machine,
|
|
183521
|
+
agentConfigs: configsByMachine.get(machine.id) ?? []
|
|
183522
|
+
}));
|
|
183523
|
+
}
|
|
183524
|
+
function printHumanMachineList(machines, currentMachineId, includeAgents) {
|
|
182302
183525
|
if (machines.length === 0) {
|
|
182303
183526
|
console.log("No machines found.");
|
|
182304
183527
|
return;
|
|
182305
183528
|
}
|
|
182306
|
-
|
|
183529
|
+
const columns = [
|
|
182307
183530
|
{
|
|
182308
183531
|
header: "ID"
|
|
182309
183532
|
},
|
|
@@ -182316,30 +183539,49 @@ ${entry.text}`).join("\n\n");
|
|
|
182316
183539
|
{
|
|
182317
183540
|
header: "CLI"
|
|
182318
183541
|
}
|
|
182319
|
-
]
|
|
182320
|
-
|
|
182321
|
-
|
|
182322
|
-
|
|
182323
|
-
|
|
182324
|
-
|
|
183542
|
+
];
|
|
183543
|
+
if (includeAgents) {
|
|
183544
|
+
columns.push({
|
|
183545
|
+
header: "Agents"
|
|
183546
|
+
});
|
|
183547
|
+
}
|
|
183548
|
+
console.log(renderTerminalTable(columns, machines.map((machine) => {
|
|
183549
|
+
const row = [
|
|
183550
|
+
machine.id,
|
|
183551
|
+
machine.id === currentMachineId ? `${machine.name} (current)` : machine.name,
|
|
183552
|
+
machine.online ? "online" : "offline",
|
|
183553
|
+
formatMachineCli(machine)
|
|
183554
|
+
];
|
|
183555
|
+
if (includeAgents) {
|
|
183556
|
+
row.push(formatMachineAgents(machine));
|
|
183557
|
+
}
|
|
183558
|
+
return row;
|
|
183559
|
+
})));
|
|
182325
183560
|
}
|
|
182326
|
-
const machineCommand = new Command("machine").description("Inspect registered machines").addCommand(new Command("list").description("List machines in a workspace").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--online-only", "Only include machines with a recent heartbeat").option("--json", "Print JSON output").option("--include-acp-capabilities", "Include acpCapabilities in JSON output").option("--debug", "Enable debug output").action(async (options) => {
|
|
183561
|
+
const machineCommand = new Command("machine").description("Inspect registered machines").addCommand(new Command("list").description("List machines in a workspace").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--online-only", "Only include machines with a recent heartbeat").option("--json", "Print JSON output").option("--include-acp-capabilities", "Include acpCapabilities in JSON output").option("--include-agents", "Include agent config summaries per machine").option("--debug", "Enable debug output").action(async (options) => {
|
|
182327
183562
|
await runOneShotCommand("machine", options, async () => {
|
|
182328
183563
|
const auth = getAuthContextOrThrow$1("machine");
|
|
182329
183564
|
const workspace = await resolveWorkspaceOrThrow$1(auth, options.workspace);
|
|
182330
183565
|
await withWorkspaceManager$1(auth, workspace, "machine", async (manager) => {
|
|
182331
|
-
|
|
183566
|
+
let machines = sortMachineMetas((await listAliveDocMetas(manager, isMachineDocRoomId)).map((entry) => entry.meta), auth.machineId).map(toMachineListEntry).filter((machine) => !options.onlineOnly || machine.online);
|
|
183567
|
+
if (options.includeAgents === true) {
|
|
183568
|
+
machines = await attachAgentConfigsToMachines(manager.repo, workspace.id, machines);
|
|
183569
|
+
}
|
|
182332
183570
|
if (options.json) {
|
|
182333
183571
|
const includeAcpCapabilities = options.includeAcpCapabilities === true;
|
|
183572
|
+
const includeAgents = options.includeAgents === true;
|
|
182334
183573
|
const jsonMachines = await Promise.all(machines.map((machine) => mergeMachineFlockJsonState(manager.repo, workspace.id, machine, includeAcpCapabilities)));
|
|
182335
183574
|
printJson({
|
|
182336
183575
|
ok: true,
|
|
182337
183576
|
workspaceId: workspace.id,
|
|
182338
|
-
machines: jsonMachines.map((machine) => toMachineJsonEntry(machine,
|
|
183577
|
+
machines: jsonMachines.map((machine) => toMachineJsonEntry(machine, {
|
|
183578
|
+
includeAcpCapabilities,
|
|
183579
|
+
includeAgents
|
|
183580
|
+
}))
|
|
182339
183581
|
});
|
|
182340
183582
|
return;
|
|
182341
183583
|
}
|
|
182342
|
-
printHumanMachineList(machines, auth.machineId);
|
|
183584
|
+
printHumanMachineList(machines, auth.machineId, options.includeAgents === true);
|
|
182343
183585
|
});
|
|
182344
183586
|
});
|
|
182345
183587
|
}));
|
|
@@ -182521,25 +183763,6 @@ ${entry.text}`).join("\n\n");
|
|
|
182521
183763
|
].sort((left2, right2) => left2.imageId.localeCompare(right2.imageId))
|
|
182522
183764
|
};
|
|
182523
183765
|
}
|
|
182524
|
-
async function mapWithConcurrency(items2, concurrency, worker) {
|
|
182525
|
-
if (items2.length === 0) {
|
|
182526
|
-
return [];
|
|
182527
|
-
}
|
|
182528
|
-
const limit2 = Math.max(1, Math.floor(concurrency));
|
|
182529
|
-
const results = new Array(items2.length);
|
|
182530
|
-
let nextIndex = 0;
|
|
182531
|
-
const runWorker = async () => {
|
|
182532
|
-
while (nextIndex < items2.length) {
|
|
182533
|
-
const currentIndex = nextIndex;
|
|
182534
|
-
nextIndex += 1;
|
|
182535
|
-
results[currentIndex] = await worker(items2[currentIndex], currentIndex);
|
|
182536
|
-
}
|
|
182537
|
-
};
|
|
182538
|
-
await Promise.all(Array.from({
|
|
182539
|
-
length: Math.min(limit2, items2.length)
|
|
182540
|
-
}, () => runWorker()));
|
|
182541
|
-
return results;
|
|
182542
|
-
}
|
|
182543
183766
|
const MIME_EXTENSION_MAP = {
|
|
182544
183767
|
"image/png": ".png",
|
|
182545
183768
|
"image/jpeg": ".jpg",
|
|
@@ -182960,6 +184183,7 @@ ${entry.text}`).join("\n\n");
|
|
|
182960
184183
|
warnings
|
|
182961
184184
|
};
|
|
182962
184185
|
}
|
|
184186
|
+
const EXPORT_SYNC_CONCURRENCY = 4;
|
|
182963
184187
|
function buildDefaultOutputDir() {
|
|
182964
184188
|
const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replaceAll(":", "-");
|
|
182965
184189
|
return path__default$1.resolve(process.cwd(), `lody-export-${timestamp2}`);
|
|
@@ -182968,7 +184192,14 @@ ${entry.text}`).join("\n\n");
|
|
|
182968
184192
|
const candidate = (workspace.slug?.trim() || workspace.id).trim();
|
|
182969
184193
|
return candidate.replace(/[\\/]/g, "_");
|
|
182970
184194
|
}
|
|
182971
|
-
|
|
184195
|
+
async function syncWorkspaceSessionsForExport(manager, workspace) {
|
|
184196
|
+
await syncWorkspaceMetaForRead(manager, `export:${workspace.id}:meta`);
|
|
184197
|
+
const sessions = await listAliveDocMetas(manager, isSessionDocRoomId);
|
|
184198
|
+
await mapWithConcurrency(sessions, EXPORT_SYNC_CONCURRENCY, async (entry) => {
|
|
184199
|
+
await syncDocForRead(manager, getSessionRoomId(entry.meta.id), `export:${workspace.id}:${entry.meta.id}`);
|
|
184200
|
+
});
|
|
184201
|
+
}
|
|
184202
|
+
const exportCommand = new Command("export").description("Export user-facing workspace session data").option("--workspace <idOrSlug>", "Target workspace id or slug").option("--all-workspace", "Export all accessible workspaces").option("--no-images", "Skip downloading image binaries").option("--offline", "Read the local cache without syncing first").option("--debug", "Enable debug output").argument("[outputDir]", "Output directory for export files").action(async (outputDirArg, options) => {
|
|
182972
184203
|
await runOneShotCommand("export", options, async () => {
|
|
182973
184204
|
const auth = getAuthContextOrThrow$1("export");
|
|
182974
184205
|
const outputDir = path__default$1.resolve(outputDirArg ?? buildDefaultOutputDir());
|
|
@@ -182983,6 +184214,9 @@ ${entry.text}`).join("\n\n");
|
|
|
182983
184214
|
for (const workspace of workspaces) {
|
|
182984
184215
|
const workspaceOutputDir = path__default$1.join(outputDir, toWorkspaceDirName(workspace));
|
|
182985
184216
|
const result = await withWorkspaceManager$1(auth, workspace, "export", async (manager) => {
|
|
184217
|
+
if (options.offline !== true) {
|
|
184218
|
+
await syncWorkspaceSessionsForExport(manager, workspace);
|
|
184219
|
+
}
|
|
182986
184220
|
return await exportWorkspaceData({
|
|
182987
184221
|
manager,
|
|
182988
184222
|
workspace,
|
|
@@ -183106,7 +184340,7 @@ ${entry.text}`).join("\n\n");
|
|
|
183106
184340
|
data = createReviewBundleSnapshot(bundle);
|
|
183107
184341
|
}
|
|
183108
184342
|
const { injectReviewSnapshot } = await import("./chunks/index-VoI6Ds2-.js");
|
|
183109
|
-
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer
|
|
184343
|
+
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer--K5LcsS4.js");
|
|
183110
184344
|
const template = await resolveReviewViewerTemplate();
|
|
183111
184345
|
const html = injectReviewSnapshot(template, data);
|
|
183112
184346
|
const outputPath = options.output ? path__default$1.resolve(options.output) : defaultHtmlOutputPath(inputPath);
|
|
@@ -200435,6 +201669,7 @@ ${lines2.join("\n")}` : ""}${suffix}`);
|
|
|
200435
201669
|
program.addCommand(startCommand);
|
|
200436
201670
|
program.addCommand(projectCommand);
|
|
200437
201671
|
program.addCommand(sessionCommand);
|
|
201672
|
+
program.addCommand(syncCommand);
|
|
200438
201673
|
program.addCommand(workspaceCommand);
|
|
200439
201674
|
program.addCommand(agentConfigCommand);
|
|
200440
201675
|
program.addCommand(machineCommand);
|