@zq-silk/yui 0.7.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +27 -28
- package/README.md +79 -71
- package/dist/cli/commandCatalog.js +283 -136
- package/dist/cli/completion.js +3 -3
- package/dist/cli/helpRenderer.js +3 -0
- package/dist/cli/interactionPolicy.js +48 -33
- package/dist/cli/interactiveSelection.js +1 -1
- package/dist/cli/invocationRouter.js +3 -2
- package/dist/cli/roleWizard.js +8 -8
- package/dist/cli.js +189 -93
- package/dist/commands/agentCommands.js +5 -5
- package/dist/commands/configCommands.js +351 -104
- package/dist/commands/configOverview.js +60 -0
- package/dist/commands/deliveryGuardPreflight.js +2 -2
- package/dist/commands/globalRoleCommands.js +9 -9
- package/dist/commands/profileCommands.js +8 -8
- package/dist/commands/resourcesCommands.js +6 -5
- package/dist/commands/taskCommands.js +111 -59
- package/dist/commands/taskRoleRuntimeStatus.js +3 -1
- package/dist/commands/telemetryCommands.js +11 -6
- package/dist/config/configCatalog.js +42 -0
- package/dist/config/yuiConfig.js +80 -35
- package/dist/context/sessionBootstrapManifest.js +1 -1
- package/dist/controller/clientRuntime.js +0 -2
- package/dist/controller/controller.js +21 -9
- package/dist/controller/fileSchedulerStoreAdapter.js +409 -79
- package/dist/controller/resourceInventory.js +9 -5
- package/dist/controller/runtime.js +112 -25
- package/dist/controller/runtimeLaunchCoordinator.js +18 -78
- package/dist/controller/structuredProviderObservation.js +273 -0
- package/dist/doctor/doctor.js +2 -2
- package/dist/executor/agentAdapter.js +40 -0
- package/dist/executor/agentExecutor.js +31 -7
- package/dist/executor/executorRegistry.js +11 -49
- package/dist/executor/fileRoleLaunchPlanner.js +115 -37
- package/dist/lifecycle/canonicalLifecycleEvent.js +5 -2
- package/dist/resources/autoResourceGc.js +3 -1
- package/dist/review/reviewConfig.js +0 -2
- package/dist/run/agentRun.js +2 -2
- package/dist/run/providerRetry.js +29 -16
- package/dist/run/providerRetryConfig.js +5 -3
- package/dist/runtime/agentHost.js +767 -158
- package/dist/runtime/builtinAgentDrivers.js +1 -5
- package/dist/runtime/codexAppServerRuntime.js +67 -60
- package/dist/runtime/exactControlPlane.js +7 -2
- package/dist/runtime/index.js +6 -2
- package/dist/runtime/launchBroker.js +30 -8
- package/dist/runtime/launchDiagnostics.js +1 -1
- package/dist/runtime/providerAuthorityFence.js +24 -0
- package/dist/runtime/providerControl.js +63 -0
- package/dist/runtime/providerRecoveryDecision.js +55 -0
- package/dist/runtime/providerRuntimeIdentity.js +269 -19
- package/dist/runtime/runtimeBinding.js +20 -11
- package/dist/runtime/structuredProviderHost.js +476 -0
- package/dist/runtime/tmuxAdapters.js +143 -42
- package/dist/scheduler/activeRoleRunDelivery.js +206 -120
- package/dist/scheduler/leaderWakeupProcessor.js +141 -16
- package/dist/scheduler/roleRunStall.js +12 -9
- package/dist/setup/setupCommand.js +153 -492
- package/dist/storage/compatibleTaskStore.js +9 -5
- package/dist/storage/migration/productionRegistry.js +169 -0
- package/dist/storage/taskStore.js +22 -3
- package/dist/telemetry/sqliteTelemetryStore.js +9 -1
- package/dist/telemetry/telemetryConfig.js +1 -18
- package/dist/telemetry/telemetryStore.js +2 -2
- package/dist/telemetry/telemetryWiring.js +6 -5
- package/dist/tmux/tmuxManager.js +1 -1
- package/dist/web/webSnapshot.js +5 -3
- package/i18n/README.zh-CN.md +48 -40
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +12 -5
- package/skills/yui-operator/SKILL.md +44 -6
- package/skills/yui-runtime/SKILL.md +1 -1
package/dist/cli/completion.js
CHANGED
|
@@ -55,7 +55,7 @@ ${bashDynamicOptionCases(entries)}
|
|
|
55
55
|
if [[ "$dynamic" == true ]]; then
|
|
56
56
|
while IFS= read -r dynamic_candidate; do
|
|
57
57
|
[[ -n "$dynamic_candidate" ]] && dynamic_candidates+=("$dynamic_candidate")
|
|
58
|
-
done < <(command ${identity} completion candidates "$current" -- "\${COMP_WORDS[@]:1:COMP_CWORD-1}" 2>/dev/null)
|
|
58
|
+
done < <(command ${identity} config completion candidates "$current" -- "\${COMP_WORDS[@]:1:COMP_CWORD-1}" 2>/dev/null)
|
|
59
59
|
candidates=("\${dynamic_candidates[@]}")
|
|
60
60
|
elif [[ "$current" == -* ]]; then
|
|
61
61
|
case "$path" in
|
|
@@ -95,7 +95,7 @@ ${zshDynamicOptionCases(entries)}
|
|
|
95
95
|
esac
|
|
96
96
|
fi
|
|
97
97
|
if [[ "$dynamic" == true ]]; then
|
|
98
|
-
dynamic_output="$(command ${identity} completion candidates "$current" -- "\${(@)words[2,CURRENT-1]}" 2>/dev/null)"
|
|
98
|
+
dynamic_output="$(command ${identity} config completion candidates "$current" -- "\${(@)words[2,CURRENT-1]}" 2>/dev/null)"
|
|
99
99
|
candidates=("\${(@f)dynamic_output}")
|
|
100
100
|
elif [[ "$current" == -* ]]; then
|
|
101
101
|
case "$command_path" in
|
|
@@ -151,7 +151,7 @@ function renderFish(entries, identity) {
|
|
|
151
151
|
"end",
|
|
152
152
|
`function ${prefix}_dynamic`,
|
|
153
153
|
" set -l words (commandline -opc)",
|
|
154
|
-
` ${identity} completion candidates (commandline -ct) -- $words[2..-1] 2>/dev/null`,
|
|
154
|
+
` ${identity} config completion candidates (commandline -ct) -- $words[2..-1] 2>/dev/null`,
|
|
155
155
|
"end"
|
|
156
156
|
];
|
|
157
157
|
for (const entry of entries) {
|
package/dist/cli/helpRenderer.js
CHANGED
|
@@ -15,6 +15,9 @@ export function renderCommandHelp(node, version) {
|
|
|
15
15
|
const width = Math.max(...node.options.map((option) => option.length));
|
|
16
16
|
lines.push("", "Options:", ...node.options.map((option) => ` ${option.padEnd(width)} ${describeOption(option)}`));
|
|
17
17
|
}
|
|
18
|
+
if (node.examples.length > 0) {
|
|
19
|
+
lines.push("", "Examples:", ...node.examples.map((example) => ` ${example}`));
|
|
20
|
+
}
|
|
18
21
|
return `${lines.join("\n")}\n`;
|
|
19
22
|
}
|
|
20
23
|
function describeOption(option) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { findCommandNode } from "./commandCatalog.js";
|
|
1
2
|
const taskTarget = (command, argumentIndex = 2, statuses) => ({
|
|
2
3
|
commandPath: ["task", command],
|
|
3
4
|
selectors: [{
|
|
@@ -47,7 +48,7 @@ export const INTERACTION_POLICIES = Object.freeze([
|
|
|
47
48
|
"--development": "value"
|
|
48
49
|
}
|
|
49
50
|
},
|
|
50
|
-
...["add", "
|
|
51
|
+
...["add", "retire", "list", "show"].map((command) => ({
|
|
51
52
|
commandPath: ["project", "knowledge", command],
|
|
52
53
|
selectors: [{
|
|
53
54
|
argumentIndex: 3,
|
|
@@ -57,26 +58,24 @@ export const INTERACTION_POLICIES = Object.freeze([
|
|
|
57
58
|
}],
|
|
58
59
|
...(command === "add"
|
|
59
60
|
? { trailingOptions: { "--body": "value" } }
|
|
60
|
-
: command === "
|
|
61
|
-
? { trailingOptions: { "--
|
|
62
|
-
:
|
|
63
|
-
? { trailingOptions: { "--all": "flag" } }
|
|
64
|
-
: {})
|
|
61
|
+
: command === "list"
|
|
62
|
+
? { trailingOptions: { "--all": "flag" } }
|
|
63
|
+
: {})
|
|
65
64
|
})),
|
|
66
65
|
...["show", "capabilities", "update", "remove"].map((command) => ({
|
|
67
|
-
commandPath: ["agent", command],
|
|
66
|
+
commandPath: ["config", "agent", command],
|
|
68
67
|
selectors: [{
|
|
69
|
-
argumentIndex:
|
|
68
|
+
argumentIndex: 3,
|
|
70
69
|
entity: "agent",
|
|
71
70
|
provider: "configured-agents",
|
|
72
71
|
actionTarget: true
|
|
73
72
|
}],
|
|
74
73
|
...(command === "remove"
|
|
75
|
-
? { confirmation: { action: "Remove Agent", targetArgumentIndex:
|
|
74
|
+
? { confirmation: { action: "Remove Agent", targetArgumentIndex: 3 } }
|
|
76
75
|
: {})
|
|
77
76
|
})),
|
|
78
77
|
{
|
|
79
|
-
commandPath: ["role", "add"],
|
|
78
|
+
commandPath: ["config", "role", "add"],
|
|
80
79
|
selectors: [{
|
|
81
80
|
option: "--agent",
|
|
82
81
|
requiredOption: true,
|
|
@@ -93,29 +92,31 @@ export const INTERACTION_POLICIES = Object.freeze([
|
|
|
93
92
|
"--search": "value"
|
|
94
93
|
}
|
|
95
94
|
},
|
|
96
|
-
...["show", "update", "remove", "enter"].map((command) => ({
|
|
97
|
-
commandPath:
|
|
95
|
+
...["show", "update", "remove", "enter", "context"].map((command) => ({
|
|
96
|
+
commandPath: command === "enter" || command === "context"
|
|
97
|
+
? ["session", command]
|
|
98
|
+
: ["config", "role", command],
|
|
98
99
|
selectors: [{
|
|
99
|
-
argumentIndex: 2,
|
|
100
|
+
argumentIndex: command === "enter" || command === "context" ? 2 : 3,
|
|
100
101
|
entity: "global-role",
|
|
101
102
|
provider: "global-roles",
|
|
102
103
|
actionTarget: true
|
|
103
104
|
}],
|
|
104
105
|
...(command === "remove"
|
|
105
|
-
? { confirmation: { action: "Remove Role", targetArgumentIndex:
|
|
106
|
+
? { confirmation: { action: "Remove Role", targetArgumentIndex: 3 } }
|
|
106
107
|
: {})
|
|
107
108
|
})),
|
|
108
109
|
...["bind", "unbind"].map((command) => ({
|
|
109
|
-
commandPath: ["role", command],
|
|
110
|
+
commandPath: ["config", "role", command],
|
|
110
111
|
selectors: [
|
|
111
|
-
{ argumentIndex:
|
|
112
|
-
{ argumentIndex:
|
|
112
|
+
{ argumentIndex: 3, entity: "global-role", provider: "global-roles", actionTarget: true },
|
|
113
|
+
{ argumentIndex: 4, entity: "agent", provider: "configured-agents", actionTarget: false }
|
|
113
114
|
]
|
|
114
115
|
})),
|
|
115
116
|
...["record", "replace"].map((command) => ({
|
|
116
|
-
commandPath: ["
|
|
117
|
+
commandPath: ["session", command],
|
|
117
118
|
selectors: [{
|
|
118
|
-
argumentIndex:
|
|
119
|
+
argumentIndex: 2,
|
|
119
120
|
entity: "global-role",
|
|
120
121
|
provider: "global-roles",
|
|
121
122
|
actionTarget: true
|
|
@@ -125,7 +126,7 @@ export const INTERACTION_POLICIES = Object.freeze([
|
|
|
125
126
|
: { "--native-id": "value" }
|
|
126
127
|
})),
|
|
127
128
|
{
|
|
128
|
-
commandPath: ["profile", "add"],
|
|
129
|
+
commandPath: ["config", "profile", "add"],
|
|
129
130
|
selectors: [],
|
|
130
131
|
trailingOptions: {
|
|
131
132
|
"--description": "value", "--instructions": "value",
|
|
@@ -133,9 +134,9 @@ export const INTERACTION_POLICIES = Object.freeze([
|
|
|
133
134
|
}
|
|
134
135
|
},
|
|
135
136
|
...["show", "update", "remove"].map((command) => ({
|
|
136
|
-
commandPath: ["profile", command],
|
|
137
|
+
commandPath: ["config", "profile", command],
|
|
137
138
|
selectors: [{
|
|
138
|
-
argumentIndex:
|
|
139
|
+
argumentIndex: 3,
|
|
139
140
|
entity: "agent-profile",
|
|
140
141
|
provider: "agent-profiles",
|
|
141
142
|
actionTarget: true
|
|
@@ -151,7 +152,7 @@ export const INTERACTION_POLICIES = Object.freeze([
|
|
|
151
152
|
}
|
|
152
153
|
: {}),
|
|
153
154
|
...(command === "remove"
|
|
154
|
-
? { confirmation: { action: "Remove Agent Profile", targetArgumentIndex:
|
|
155
|
+
? { confirmation: { action: "Remove Agent Profile", targetArgumentIndex: 3 } }
|
|
155
156
|
: {})
|
|
156
157
|
})),
|
|
157
158
|
taskTarget("show"),
|
|
@@ -360,8 +361,8 @@ export const INTERACTION_POLICIES = Object.freeze([
|
|
|
360
361
|
trailingOptions: { "--reason": "value" },
|
|
361
362
|
confirmation: { action: "Reset Task Role Session", targetArgumentIndex: 4 }
|
|
362
363
|
},
|
|
363
|
-
{
|
|
364
|
-
commandPath: ["task", "role",
|
|
364
|
+
...["view", "takeover", "release"].map((command) => ({
|
|
365
|
+
commandPath: ["task", "role", command],
|
|
365
366
|
selectors: [
|
|
366
367
|
{ argumentIndex: 3, entity: "task", provider: "tasks", actionTarget: true },
|
|
367
368
|
{
|
|
@@ -371,9 +372,8 @@ export const INTERACTION_POLICIES = Object.freeze([
|
|
|
371
372
|
dependsOn: 3,
|
|
372
373
|
actionTarget: true
|
|
373
374
|
}
|
|
374
|
-
]
|
|
375
|
-
|
|
376
|
-
},
|
|
375
|
+
]
|
|
376
|
+
})),
|
|
377
377
|
{
|
|
378
378
|
commandPath: ["task", "work", "create"],
|
|
379
379
|
selectors: [
|
|
@@ -533,11 +533,6 @@ export const INTERACTION_POLICIES = Object.freeze([
|
|
|
533
533
|
? { trailingOptions: { "--reason": "value" } }
|
|
534
534
|
: {})
|
|
535
535
|
})),
|
|
536
|
-
{
|
|
537
|
-
commandPath: ["task", "enter"],
|
|
538
|
-
selectors: [{ argumentIndex: 2, entity: "task", provider: "tasks", actionTarget: true }],
|
|
539
|
-
trailingOptions: { "--read-only": "flag", "--read-write": "flag" }
|
|
540
|
-
},
|
|
541
536
|
{
|
|
542
537
|
commandPath: ["jobs", "retry"],
|
|
543
538
|
selectors: [{ argumentIndex: 2, entity: "job", provider: "jobs", actionTarget: true }]
|
|
@@ -630,10 +625,30 @@ export function validateInteractionPolicies(policies = INTERACTION_POLICIES) {
|
|
|
630
625
|
if (paths.has(path))
|
|
631
626
|
throw new Error(`Duplicate interaction policy: ${path}`);
|
|
632
627
|
paths.add(path);
|
|
628
|
+
const node = findCommandNode(policy.commandPath);
|
|
629
|
+
if (node === undefined || node.hidden) {
|
|
630
|
+
throw new Error(`Interaction policy references an unknown command: ${path}`);
|
|
631
|
+
}
|
|
633
632
|
for (const selector of policy.selectors) {
|
|
634
633
|
if ((selector.argumentIndex === undefined) === (selector.option === undefined)) {
|
|
635
634
|
throw new Error(`Interaction selector must declare exactly one slot: ${path}`);
|
|
636
635
|
}
|
|
636
|
+
if (selector.argumentIndex !== undefined && (!Number.isInteger(selector.argumentIndex)
|
|
637
|
+
|| selector.argumentIndex < node.path.length - 1)) {
|
|
638
|
+
throw new Error(`Interaction selector has an invalid argument index: ${path}`);
|
|
639
|
+
}
|
|
640
|
+
if (selector.option !== undefined && !node.options.includes(selector.option)) {
|
|
641
|
+
throw new Error(`Interaction selector references an unknown option: ${path} ${selector.option}`);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
for (const option of Object.keys(policy.trailingOptions ?? {})) {
|
|
645
|
+
if (!node.options.includes(option)) {
|
|
646
|
+
throw new Error(`Interaction policy references an unknown trailing option: ${path} ${option}`);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
if (policy.confirmation !== undefined && !policy.selectors.some((selector) => selector.argumentIndex === policy.confirmation?.targetArgumentIndex
|
|
650
|
+
&& selector.actionTarget)) {
|
|
651
|
+
throw new Error(`Interaction confirmation has no action target selector: ${path}`);
|
|
637
652
|
}
|
|
638
653
|
}
|
|
639
654
|
}
|
|
@@ -53,7 +53,7 @@ export async function resolveInteractiveArguments(args, node, ports, io) {
|
|
|
53
53
|
}
|
|
54
54
|
export function allowsInteractiveSelection(args, globalJson) {
|
|
55
55
|
return !globalJson && !args.includes("--json")
|
|
56
|
-
&& !(args[0] === "
|
|
56
|
+
&& !(args[0] === "config" && args[1] === "completion" && args[2] === "candidates");
|
|
57
57
|
}
|
|
58
58
|
function missingSlot(args, selector, node) {
|
|
59
59
|
if (selector.argumentIndex !== undefined) {
|
|
@@ -31,8 +31,9 @@ function resolveExecutionPath(args) {
|
|
|
31
31
|
break;
|
|
32
32
|
const child = findChild(node, args[index] ?? "");
|
|
33
33
|
const internalExecutable = child !== undefined && ((node === ROOT_COMMAND && child.name === "internal")
|
|
34
|
-
|| (node.path.join(" ") === "yui completion" && child.name === "candidates")
|
|
35
|
-
|| (node.path.join(" ") === "yui task run"
|
|
34
|
+
|| (node.path.join(" ") === "yui config completion" && child.name === "candidates")
|
|
35
|
+
|| (node.path.join(" ") === "yui task run"
|
|
36
|
+
&& (child.name === "checkpoint" || child.name === "context"))
|
|
36
37
|
|| (node.path.join(" ") === "yui controller"
|
|
37
38
|
&& (child.name === "identity" || child.name === "live-identity")));
|
|
38
39
|
if (child === undefined || (child.hidden && !internalExecutable)) {
|
package/dist/cli/roleWizard.js
CHANGED
|
@@ -20,7 +20,7 @@ export async function resolveRoleWizardArguments(commandArgs, ports, io) {
|
|
|
20
20
|
return { kind: "unchanged", args };
|
|
21
21
|
}
|
|
22
22
|
export async function resolveGlobalRoleAgentConfigurationArguments(roleName, agentId, ports, io) {
|
|
23
|
-
const args = ["role", "update", roleName];
|
|
23
|
+
const args = ["config", "role", "update", roleName];
|
|
24
24
|
if (!io.interactive || io.json)
|
|
25
25
|
return { kind: "unchanged", args };
|
|
26
26
|
const role = asRole(await ports.call("role.show", { name: roleName }));
|
|
@@ -31,7 +31,7 @@ export async function resolveGlobalRoleAgentConfigurationArguments(roleName, age
|
|
|
31
31
|
return updateAgentBindingSettings(args, role, binding, ports, io);
|
|
32
32
|
}
|
|
33
33
|
function isGlobalRoleAdd(args) {
|
|
34
|
-
return args[0] === "
|
|
34
|
+
return args[0] === "config" && args[1] === "role" && args[2] === "add";
|
|
35
35
|
}
|
|
36
36
|
function isTaskRoleAdd(args) {
|
|
37
37
|
return args[0] === "task" && args[1] === "role" && args[2] === "add";
|
|
@@ -39,18 +39,18 @@ function isTaskRoleAdd(args) {
|
|
|
39
39
|
// Explicit update options always win. This keeps scripts and deliberate
|
|
40
40
|
// non-interactive invocations out of the wizard even when run from a TTY.
|
|
41
41
|
function isGlobalRoleUpdate(args) {
|
|
42
|
-
return args.length ===
|
|
43
|
-
&& isValue(args[
|
|
42
|
+
return args.length === 4 && args[0] === "config" && args[1] === "role"
|
|
43
|
+
&& args[2] === "update" && isValue(args[3]);
|
|
44
44
|
}
|
|
45
45
|
function isTaskRoleUpdate(args) {
|
|
46
46
|
return args.length === 5 && args[0] === "task" && args[1] === "role"
|
|
47
47
|
&& args[2] === "update" && isValue(args[3]) && isValue(args[4]);
|
|
48
48
|
}
|
|
49
49
|
async function addGlobalRole(args, ports, io) {
|
|
50
|
-
const named = await ensureRoleName(args,
|
|
50
|
+
const named = await ensureRoleName(args, 3, io);
|
|
51
51
|
if (named === undefined)
|
|
52
52
|
return { kind: "cancelled", args };
|
|
53
|
-
const explicitSettings = hasExplicitAddSettings(named,
|
|
53
|
+
const explicitSettings = hasExplicitAddSettings(named, 4);
|
|
54
54
|
const agents = await loadAgentSelection(ports);
|
|
55
55
|
const explicitAgent = optionValue(named, "--agent");
|
|
56
56
|
const selected = explicitAgent ?? await selectConfiguredAgent(ports, io, "Create Global Role from Agent", agents);
|
|
@@ -236,7 +236,7 @@ async function configureNewAgentField(args, agent, ports, io) {
|
|
|
236
236
|
: { kind: "resolved", args: [...args, selected.set, value] };
|
|
237
237
|
}
|
|
238
238
|
async function updateGlobalRole(args, ports, io) {
|
|
239
|
-
const role = asRole(await ports.call("role.show", { name: args[
|
|
239
|
+
const role = asRole(await ports.call("role.show", { name: args[3] }));
|
|
240
240
|
if (role === undefined)
|
|
241
241
|
return { kind: "unchanged", args };
|
|
242
242
|
return updateRole(args, role, ports, io, false);
|
|
@@ -286,7 +286,7 @@ async function updateRoleSettings(args, role, ports, io, taskRole) {
|
|
|
286
286
|
return { kind: "cancelled", args };
|
|
287
287
|
return taskRole
|
|
288
288
|
? { kind: "resolved", args: ["task", "role", "bind", args[3] ?? "", args[4] ?? "", target] }
|
|
289
|
-
: { kind: "resolved", args: ["role", "bind", args[
|
|
289
|
+
: { kind: "resolved", args: ["config", "role", "bind", args[3] ?? "", target] };
|
|
290
290
|
}
|
|
291
291
|
if (field === "workspace") {
|
|
292
292
|
const value = (await io.question(`Workspace [${roleDisplay(role.workspace)}]: `))?.trim();
|