@zq-silk/yui 0.7.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -23
- package/dist/cli/commandCatalog.js +234 -122
- package/dist/cli/completion.js +3 -3
- package/dist/cli/helpRenderer.js +3 -0
- package/dist/cli/interactionPolicy.js +44 -23
- package/dist/cli/interactiveSelection.js +1 -1
- package/dist/cli/invocationRouter.js +1 -1
- package/dist/cli/roleWizard.js +8 -8
- package/dist/cli.js +116 -72
- 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 +3 -6
- 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 +20 -9
- package/dist/controller/runtime.js +32 -18
- package/dist/coordination/workMailbox.js +25 -22
- package/dist/doctor/doctor.js +2 -2
- package/dist/resources/autoResourceGc.js +3 -1
- package/dist/review/reviewConfig.js +0 -2
- package/dist/run/providerRetry.js +29 -16
- package/dist/run/providerRetryConfig.js +5 -3
- package/dist/runtime/launchDiagnostics.js +1 -1
- 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 +58 -0
- package/dist/storage/sqliteStore.js +9 -2
- package/dist/storage/taskStore.js +21 -2
- 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/web/webSnapshot.js +5 -3
- package/i18n/README.zh-CN.md +37 -32
- 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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { supportedAgentAdapterIds } from "../agent/adapterCatalog.js";
|
|
2
|
-
import {
|
|
2
|
+
import { CONFIG_DEFINITIONS, CONFIG_DOMAINS, configDefinitionsForDomain } from "../config/configCatalog.js";
|
|
3
3
|
function buildNode(input, parentPath = []) {
|
|
4
4
|
const path = [...parentPath, input.name];
|
|
5
5
|
const children = (input.children ?? []).map((child) => buildNode(child, path));
|
|
@@ -7,12 +7,16 @@ function buildNode(input, parentPath = []) {
|
|
|
7
7
|
const usage = input.usage === undefined
|
|
8
8
|
? [`${path.join(" ")}${children.length > 0 && !executable ? " <command>" : ""}`]
|
|
9
9
|
: typeof input.usage === "string" ? [input.usage] : [...input.usage];
|
|
10
|
+
const examples = input.examples === undefined
|
|
11
|
+
? usage
|
|
12
|
+
: typeof input.examples === "string" ? [input.examples] : [...input.examples];
|
|
10
13
|
return Object.freeze({
|
|
11
14
|
name: input.name,
|
|
12
15
|
path: Object.freeze(path),
|
|
13
16
|
summary: input.summary,
|
|
14
17
|
kind: children.length === 0 ? "leaf" : executable ? "hybrid" : "group",
|
|
15
18
|
usage: Object.freeze(usage),
|
|
19
|
+
examples: Object.freeze(examples),
|
|
16
20
|
sections: Object.freeze((input.sections ?? []).map((section) => Object.freeze({
|
|
17
21
|
...section,
|
|
18
22
|
entries: Object.freeze([...section.entries])
|
|
@@ -37,49 +41,91 @@ function buildNode(input, parentPath = []) {
|
|
|
37
41
|
function freezeRecord(record) {
|
|
38
42
|
return Object.freeze(Object.fromEntries(Object.entries(record ?? {}).map(([key, values]) => [key, Object.freeze([...values])])));
|
|
39
43
|
}
|
|
40
|
-
const CONFIG_KEY_VALUES =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
44
|
+
const CONFIG_KEY_VALUES = CONFIG_DEFINITIONS.map((definition) => ({
|
|
45
|
+
name: definition.key,
|
|
46
|
+
summary: definition.summary,
|
|
47
|
+
takesEffect: definition.takesEffect
|
|
48
|
+
}));
|
|
49
|
+
const CONFIG_DOMAIN_SUMMARIES = {
|
|
50
|
+
system: "Configure Home-wide defaults and human-facing presentation.",
|
|
51
|
+
runtime: "Configure Controller recovery, concurrency, health, launch, delivery, and Provider retry policy.",
|
|
52
|
+
workflow: "Configure Leader convergence, context, and optional review policy.",
|
|
53
|
+
resources: "Configure resource garbage collection and quarantine policy.",
|
|
54
|
+
tools: "Configure tmux and optional diagnostic telemetry."
|
|
55
|
+
};
|
|
56
|
+
function durableConfigDomainNode(domain) {
|
|
57
|
+
const definitions = configDefinitionsForDomain(domain);
|
|
58
|
+
const keys = definitions.map(({ key }) => key);
|
|
59
|
+
const values = CONFIG_KEY_VALUES.filter(({ name }) => keys.includes(name));
|
|
60
|
+
const options = domain === "workflow"
|
|
61
|
+
? [
|
|
62
|
+
"--soft-tokens", "--hard-tokens", "--role", "--trigger", "--finding-ledger",
|
|
63
|
+
"--delta-recheck", "--delta-recheck-max-lines", "--delta-recheck-max-files"
|
|
64
|
+
]
|
|
65
|
+
: domain === "runtime"
|
|
66
|
+
? ["--quiet-after-seconds", "--diagnostic-after-seconds", "--stall-after-seconds"]
|
|
67
|
+
: [];
|
|
68
|
+
return {
|
|
69
|
+
name: domain,
|
|
70
|
+
summary: CONFIG_DOMAIN_SUMMARIES[domain],
|
|
71
|
+
examples: [
|
|
72
|
+
`yui config ${domain} show`,
|
|
73
|
+
`yui config ${domain} set ${keys[0]} <value>`,
|
|
74
|
+
`yui config ${domain} clear ${keys[0]}`
|
|
75
|
+
],
|
|
76
|
+
sections: [{ id: "manage", title: "Commands", entries: ["show", "set", "clear"] }],
|
|
77
|
+
children: [
|
|
78
|
+
{ name: "show", summary: `Show effective ${domain} configuration.` },
|
|
79
|
+
{
|
|
80
|
+
name: "set",
|
|
81
|
+
summary: `Set one ${domain} configuration key.`,
|
|
82
|
+
usage: `yui config ${domain} set <key> <value...>`,
|
|
83
|
+
sections: [{ id: "keys", title: "Configuration keys", entries: keys }],
|
|
84
|
+
values,
|
|
85
|
+
options,
|
|
86
|
+
optionValues: domain === "workflow"
|
|
87
|
+
? {
|
|
88
|
+
"--trigger": ["always", "leader", "final"],
|
|
89
|
+
"--finding-ledger": ["shadow", "enforce"],
|
|
90
|
+
"--delta-recheck": ["enabled", "disabled"]
|
|
91
|
+
}
|
|
92
|
+
: {}
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: "clear",
|
|
96
|
+
summary: `Reset one ${domain} configuration key to its default.`,
|
|
97
|
+
usage: `yui config ${domain} clear <key>`,
|
|
98
|
+
sections: [{ id: "keys", title: "Configuration keys", entries: keys }],
|
|
99
|
+
values
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
};
|
|
103
|
+
}
|
|
58
104
|
const agentChildren = [
|
|
59
105
|
{
|
|
60
106
|
name: "add",
|
|
61
107
|
summary: "Add a configured native Agent CLI.",
|
|
62
|
-
usage: "yui agent add <id> [--adapter <adapter>] --command <command> [--arg <arg> ...] [--env TARGET=PROCESS_NAME ...]",
|
|
108
|
+
usage: "yui config agent add <id> [--adapter <adapter>] --command <command> [--arg <arg> ...] [--env TARGET=PROCESS_NAME ...]",
|
|
63
109
|
options: ["--adapter", "--command", "--arg", "--env"],
|
|
64
110
|
optionValues: { "--adapter": supportedAgentAdapterIds() },
|
|
65
111
|
executableOptions: ["--command"]
|
|
66
112
|
},
|
|
67
113
|
{ name: "list", summary: "List configured Agents." },
|
|
68
|
-
{ name: "show", summary: "Show one configured Agent.", usage: "yui agent show <id>" },
|
|
114
|
+
{ name: "show", summary: "Show one configured Agent.", usage: "yui config agent show <id>" },
|
|
69
115
|
{
|
|
70
116
|
name: "capabilities",
|
|
71
117
|
summary: "Probe one Agent CLI for runtime configuration options.",
|
|
72
|
-
usage: "yui agent capabilities <id>"
|
|
118
|
+
usage: "yui config agent capabilities <id>"
|
|
73
119
|
},
|
|
74
120
|
{
|
|
75
121
|
name: "update",
|
|
76
122
|
summary: "Update a configured Agent.",
|
|
77
|
-
usage: "yui agent update <id> [--adapter <adapter>] [--command <command>] [--arg <arg> ... | --clear-args] [--env TARGET=PROCESS_NAME ... | --clear-env]",
|
|
123
|
+
usage: "yui config agent update <id> [--adapter <adapter>] [--command <command>] [--arg <arg> ... | --clear-args] [--env TARGET=PROCESS_NAME ... | --clear-env]",
|
|
78
124
|
options: ["--adapter", "--command", "--arg", "--clear-args", "--env", "--clear-env"],
|
|
79
125
|
optionValues: { "--adapter": supportedAgentAdapterIds() },
|
|
80
126
|
executableOptions: ["--command"]
|
|
81
127
|
},
|
|
82
|
-
{ name: "remove", summary: "Remove a configured Agent.", usage: "yui agent remove <id>" }
|
|
128
|
+
{ name: "remove", summary: "Remove a configured Agent.", usage: "yui config agent remove <id>" }
|
|
83
129
|
];
|
|
84
130
|
const roleProfileOptions = [
|
|
85
131
|
"--description", "--responsibility", "--constraint",
|
|
@@ -114,67 +160,83 @@ const roleChildren = [
|
|
|
114
160
|
{
|
|
115
161
|
name: "add",
|
|
116
162
|
summary: "Add a reusable global Role.",
|
|
117
|
-
usage: "yui role add <name> --agent <id> [Role and Agent settings]",
|
|
163
|
+
usage: "yui config role add <name> --agent <id> [Role and Agent settings]",
|
|
118
164
|
options: ["--agent", "--workspace", ...roleProfileOptions, ...roleAgentOptions],
|
|
119
165
|
optionValues: roleAgentOptionValues,
|
|
120
166
|
fileOptions: ["--workspace"]
|
|
121
167
|
},
|
|
122
168
|
{ name: "list", summary: "List global Roles." },
|
|
123
|
-
{ name: "show", summary: "Show one global Role.", usage: "yui role show <name>" },
|
|
124
|
-
{ name: "context", summary: "Load the exact authorized global Role context.", usage: "yui role context <name>" },
|
|
169
|
+
{ name: "show", summary: "Show one global Role.", usage: "yui config role show <name>" },
|
|
125
170
|
{
|
|
126
171
|
name: "update",
|
|
127
172
|
summary: "Update a global Role.",
|
|
128
|
-
usage: "yui role update <name> [profile options] [clear options]",
|
|
173
|
+
usage: "yui config role update <name> [profile options] [clear options]",
|
|
129
174
|
options: ["--agent", "--workspace", ...roleProfileOptions, ...roleAgentOptions,
|
|
130
175
|
...roleProfileClearOptions, ...roleAgentClearOptions],
|
|
131
176
|
optionValues: roleAgentOptionValues,
|
|
132
177
|
fileOptions: ["--workspace"]
|
|
133
178
|
},
|
|
134
|
-
{ name: "remove", summary: "Remove a global Role.", usage: "yui role remove <name>" },
|
|
135
|
-
{ name: "bind", summary: "Bind and activate an Agent for a global Role.", usage: "yui role bind <role> <agent-id>" },
|
|
136
|
-
{ name: "unbind", summary: "Unbind a dormant Agent from a global Role.", usage: "yui role unbind <role> <agent-id>" }
|
|
137
|
-
|
|
179
|
+
{ name: "remove", summary: "Remove a global Role.", usage: "yui config role remove <name>" },
|
|
180
|
+
{ name: "bind", summary: "Bind and activate an Agent for a global Role.", usage: "yui config role bind <role> <agent-id>" },
|
|
181
|
+
{ name: "unbind", summary: "Unbind a dormant Agent from a global Role.", usage: "yui config role unbind <role> <agent-id>" }
|
|
182
|
+
];
|
|
183
|
+
const globalSessionChildren = [
|
|
184
|
+
{ name: "enter", summary: "Enter a global Role's native session.", usage: "yui session enter <role>" },
|
|
138
185
|
{
|
|
139
|
-
name: "
|
|
140
|
-
summary: "
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
186
|
+
name: "context",
|
|
187
|
+
summary: "Load the exact authorized global Role context.",
|
|
188
|
+
usage: "yui session context <role>"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: "record",
|
|
192
|
+
summary: "Record the active Agent's native session ID.",
|
|
193
|
+
usage: "yui session record <role> --native-id <id>",
|
|
194
|
+
options: ["--native-id"]
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: "replace",
|
|
198
|
+
summary: "Explicitly replace the active Agent's native session ID.",
|
|
199
|
+
usage: "yui session replace <role> --native-id <id> --reason <text>",
|
|
200
|
+
options: ["--native-id", "--reason"]
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: "reconcile",
|
|
204
|
+
summary: "Reconcile durable Session owners with native sessions.",
|
|
205
|
+
usage: "yui session reconcile [--report] [--cleanup]",
|
|
206
|
+
options: ["--report", "--cleanup"]
|
|
156
207
|
}
|
|
157
208
|
];
|
|
158
209
|
const profileChildren = [
|
|
159
210
|
{
|
|
160
211
|
name: "add",
|
|
161
212
|
summary: "Add a reusable Agent Profile.",
|
|
162
|
-
usage: "yui profile add <id> [--access <read|write>] [Profile settings]",
|
|
213
|
+
usage: "yui config profile add <id> [--access <read|write>] [Profile settings]",
|
|
163
214
|
options: ["--access", ...agentProfileOptions],
|
|
164
215
|
optionValues: { "--access": ["read", "write"] }
|
|
165
216
|
},
|
|
166
217
|
{ name: "list", summary: "List Agent Profiles." },
|
|
167
|
-
{ name: "show", summary: "Show one Agent Profile.", usage: "yui profile show <id>" },
|
|
218
|
+
{ name: "show", summary: "Show one Agent Profile.", usage: "yui config profile show <id>" },
|
|
168
219
|
{
|
|
169
220
|
name: "update",
|
|
170
221
|
summary: "Update an Agent Profile.",
|
|
171
|
-
usage: "yui profile update <id> [--access <read|write>] [Profile settings]",
|
|
222
|
+
usage: "yui config profile update <id> [--access <read|write>] [Profile settings]",
|
|
172
223
|
options: ["--access", ...agentProfileOptions, ...agentProfileClearOptions],
|
|
173
224
|
optionValues: { "--access": ["read", "write"] }
|
|
174
225
|
},
|
|
175
|
-
{ name: "remove", summary: "Remove a custom Agent Profile.", usage: "yui profile remove <id>" },
|
|
226
|
+
{ name: "remove", summary: "Remove a custom Agent Profile.", usage: "yui config profile remove <id>" },
|
|
176
227
|
{ name: "reset", summary: "Reset all built-in Agent Profiles." }
|
|
177
228
|
];
|
|
229
|
+
const completionChildren = [
|
|
230
|
+
{ name: "bash", summary: "Interactively configure Bash completion." },
|
|
231
|
+
{ name: "zsh", summary: "Interactively configure Zsh completion." },
|
|
232
|
+
{ name: "fish", summary: "Interactively configure Fish completion." },
|
|
233
|
+
{
|
|
234
|
+
name: "candidates",
|
|
235
|
+
summary: "Resolve internal dynamic completion candidates.",
|
|
236
|
+
usage: "yui config completion candidates <prefix> -- <words...>",
|
|
237
|
+
hidden: true
|
|
238
|
+
}
|
|
239
|
+
];
|
|
178
240
|
const taskChildren = [
|
|
179
241
|
{
|
|
180
242
|
name: "create",
|
|
@@ -889,13 +951,14 @@ export const ROOT_COMMAND = buildNode({
|
|
|
889
951
|
name: "yui",
|
|
890
952
|
summary: "Coordinate durable, isolated Agent work.",
|
|
891
953
|
usage: "yui [--json] <command>",
|
|
954
|
+
examples: ["yui setup", "yui operator enter", "yui config show", "yui task list"],
|
|
892
955
|
sections: [
|
|
893
956
|
{ id: "general", title: "General", entries: [
|
|
894
|
-
"help", "version", "update", "upgrade", "setup", "doctor"
|
|
957
|
+
"help", "version", "update", "upgrade", "setup", "doctor"
|
|
895
958
|
] },
|
|
896
959
|
{ id: "workflow", title: "Workflow", entries: ["operator", "project", "task"] },
|
|
897
|
-
{ id: "configuration", title: "Configuration", entries: ["config"
|
|
898
|
-
{ id: "operations", title: "Operations", entries: ["web", "controller", "execution", "job", "jobs", "telemetry", "release"] },
|
|
960
|
+
{ id: "configuration", title: "Configuration", entries: ["config"] },
|
|
961
|
+
{ id: "operations", title: "Operations", entries: ["web", "controller", "session", "execution", "job", "jobs", "telemetry", "release"] },
|
|
899
962
|
{ id: "resources", title: "Resources", entries: ["resources"] },
|
|
900
963
|
{ id: "internal", title: "Internal", entries: ["internal"] }
|
|
901
964
|
],
|
|
@@ -909,7 +972,11 @@ export const ROOT_COMMAND = buildNode({
|
|
|
909
972
|
usage: "yui upgrade [--dry-run]",
|
|
910
973
|
options: ["--dry-run"]
|
|
911
974
|
},
|
|
912
|
-
{
|
|
975
|
+
{
|
|
976
|
+
name: "setup",
|
|
977
|
+
summary: "Initialize the minimum Operator and Leader configuration required to execute Tasks.",
|
|
978
|
+
examples: "yui setup"
|
|
979
|
+
},
|
|
913
980
|
{ name: "doctor", summary: "Check Yui dependencies and file state." },
|
|
914
981
|
{
|
|
915
982
|
name: "web",
|
|
@@ -917,28 +984,6 @@ export const ROOT_COMMAND = buildNode({
|
|
|
917
984
|
usage: "yui web [--host <loopback>] [--port <port>]",
|
|
918
985
|
options: ["--host", "--port"]
|
|
919
986
|
},
|
|
920
|
-
{
|
|
921
|
-
name: "completion",
|
|
922
|
-
summary: "Interactively configure shell completion.",
|
|
923
|
-
executable: true,
|
|
924
|
-
acceptsArguments: false,
|
|
925
|
-
usage: ["yui completion", "yui completion <bash|zsh|fish>"],
|
|
926
|
-
sections: [
|
|
927
|
-
{ id: "shells", title: "Shells", entries: ["bash", "zsh", "fish"] },
|
|
928
|
-
{ id: "internal", title: "Internal", entries: ["candidates"] }
|
|
929
|
-
],
|
|
930
|
-
children: [
|
|
931
|
-
{ name: "bash", summary: "Interactively configure Bash completion." },
|
|
932
|
-
{ name: "zsh", summary: "Interactively configure Zsh completion." },
|
|
933
|
-
{ name: "fish", summary: "Interactively configure Fish completion." },
|
|
934
|
-
{
|
|
935
|
-
name: "candidates",
|
|
936
|
-
summary: "Resolve internal dynamic completion candidates.",
|
|
937
|
-
usage: "yui completion candidates <prefix> -- <words...>",
|
|
938
|
-
hidden: true
|
|
939
|
-
}
|
|
940
|
-
]
|
|
941
|
-
},
|
|
942
987
|
{
|
|
943
988
|
name: "controller",
|
|
944
989
|
summary: "Inspect and recover local Controller runtime resources.",
|
|
@@ -1028,29 +1073,78 @@ export const ROOT_COMMAND = buildNode({
|
|
|
1028
1073
|
},
|
|
1029
1074
|
{
|
|
1030
1075
|
name: "config",
|
|
1031
|
-
summary: "Inspect
|
|
1032
|
-
|
|
1076
|
+
summary: "Inspect, understand, and update all persistent Yui configuration.",
|
|
1077
|
+
examples: [
|
|
1078
|
+
"yui config show",
|
|
1079
|
+
"yui config describe runtime",
|
|
1080
|
+
"yui config workflow show",
|
|
1081
|
+
"yui config agent list",
|
|
1082
|
+
"yui config role show operator",
|
|
1083
|
+
"yui config profile list",
|
|
1084
|
+
"yui config completion"
|
|
1085
|
+
],
|
|
1086
|
+
sections: [
|
|
1087
|
+
{ id: "inspect", title: "Inspect", entries: ["show", "describe"] },
|
|
1088
|
+
{ id: "domains", title: "Configuration domains", entries: [
|
|
1089
|
+
...CONFIG_DOMAINS, "agent", "role", "profile", "completion"
|
|
1090
|
+
] }
|
|
1091
|
+
],
|
|
1033
1092
|
children: [
|
|
1034
|
-
{ name: "show", summary: "Show effective Yui configuration." },
|
|
1035
1093
|
{
|
|
1036
|
-
name: "
|
|
1037
|
-
summary: "
|
|
1038
|
-
|
|
1039
|
-
sections: [{ id: "keys", title: "Configuration keys", entries: [...CONFIG_KEYS] }],
|
|
1040
|
-
values: CONFIG_KEY_VALUES,
|
|
1041
|
-
options: ["--role", "--trigger", "--finding-ledger", "--delta-recheck", "--delta-recheck-max-lines", "--delta-recheck-max-files"],
|
|
1042
|
-
optionValues: {
|
|
1043
|
-
"--trigger": ["always", "leader", "final"],
|
|
1044
|
-
"--finding-ledger": ["shadow", "enforce"],
|
|
1045
|
-
"--delta-recheck": ["enabled", "disabled"]
|
|
1046
|
-
}
|
|
1094
|
+
name: "show",
|
|
1095
|
+
summary: "Show the complete effective Yui configuration.",
|
|
1096
|
+
examples: ["yui config show", "yui --json config show"]
|
|
1047
1097
|
},
|
|
1048
1098
|
{
|
|
1049
|
-
name: "
|
|
1050
|
-
summary: "
|
|
1051
|
-
usage:
|
|
1052
|
-
|
|
1053
|
-
|
|
1099
|
+
name: "describe",
|
|
1100
|
+
summary: "Explain configuration effects, defaults, choices, and activation behavior.",
|
|
1101
|
+
usage: `yui config describe [${[...CONFIG_DOMAINS, "agent", "role", "profile", "completion"].join("|")}]`,
|
|
1102
|
+
examples: ["yui config describe", "yui --json config describe role"],
|
|
1103
|
+
argumentValues: { 0: [...CONFIG_DOMAINS, "agent", "role", "profile", "completion"] }
|
|
1104
|
+
},
|
|
1105
|
+
...CONFIG_DOMAINS.map(durableConfigDomainNode),
|
|
1106
|
+
{
|
|
1107
|
+
name: "agent",
|
|
1108
|
+
summary: "Manage configured native Agent CLIs; launch-setting changes require affected Sessions to be stopped.",
|
|
1109
|
+
examples: ["yui config agent list", "yui config agent capabilities codex"],
|
|
1110
|
+
sections: [
|
|
1111
|
+
{ id: "inspect", title: "Inspect", entries: ["list", "show", "capabilities"] },
|
|
1112
|
+
{ id: "manage", title: "Manage", entries: ["add", "update", "remove"] }
|
|
1113
|
+
],
|
|
1114
|
+
children: agentChildren
|
|
1115
|
+
},
|
|
1116
|
+
{
|
|
1117
|
+
name: "profile",
|
|
1118
|
+
summary: "Manage reusable Agent Profiles; updates affect future copies and do not rewrite existing Task Roles.",
|
|
1119
|
+
examples: ["yui config profile list", "yui config profile show implementer"],
|
|
1120
|
+
sections: [
|
|
1121
|
+
{ id: "inspect", title: "Inspect", entries: ["list", "show"] },
|
|
1122
|
+
{ id: "manage", title: "Manage", entries: ["add", "update", "remove", "reset"] }
|
|
1123
|
+
],
|
|
1124
|
+
children: profileChildren
|
|
1125
|
+
},
|
|
1126
|
+
{
|
|
1127
|
+
name: "role",
|
|
1128
|
+
summary: "Manage reusable global Roles and desired Agent launch configuration for the next compatible Session.",
|
|
1129
|
+
examples: ["yui config role list", "yui config role show operator"],
|
|
1130
|
+
sections: [
|
|
1131
|
+
{ id: "inspect", title: "Inspect", entries: ["list", "show"] },
|
|
1132
|
+
{ id: "manage", title: "Manage", entries: ["add", "update", "remove", "bind", "unbind"] }
|
|
1133
|
+
],
|
|
1134
|
+
children: roleChildren
|
|
1135
|
+
},
|
|
1136
|
+
{
|
|
1137
|
+
name: "completion",
|
|
1138
|
+
summary: "Interactively configure shell completion after confirming generated files and startup-file changes.",
|
|
1139
|
+
executable: true,
|
|
1140
|
+
acceptsArguments: false,
|
|
1141
|
+
usage: ["yui config completion", "yui config completion <bash|zsh|fish>"],
|
|
1142
|
+
examples: ["yui config completion", "yui config completion zsh"],
|
|
1143
|
+
sections: [
|
|
1144
|
+
{ id: "shells", title: "Shells", entries: ["bash", "zsh", "fish"] },
|
|
1145
|
+
{ id: "internal", title: "Internal", entries: ["candidates"] }
|
|
1146
|
+
],
|
|
1147
|
+
children: completionChildren
|
|
1054
1148
|
}
|
|
1055
1149
|
]
|
|
1056
1150
|
},
|
|
@@ -1207,32 +1301,18 @@ export const ROOT_COMMAND = buildNode({
|
|
|
1207
1301
|
]
|
|
1208
1302
|
},
|
|
1209
1303
|
{
|
|
1210
|
-
name: "
|
|
1211
|
-
summary: "
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
children: agentChildren
|
|
1217
|
-
},
|
|
1218
|
-
{
|
|
1219
|
-
name: "profile",
|
|
1220
|
-
summary: "Manage reusable Agent Profiles.",
|
|
1221
|
-
sections: [
|
|
1222
|
-
{ id: "inspect", title: "Inspect", entries: ["list", "show"] },
|
|
1223
|
-
{ id: "manage", title: "Manage", entries: ["add", "update", "remove", "reset"] }
|
|
1304
|
+
name: "session",
|
|
1305
|
+
summary: "Load and enter global Role sessions, and reconcile their durable identities.",
|
|
1306
|
+
examples: [
|
|
1307
|
+
"yui session context operator --json",
|
|
1308
|
+
"yui session enter operator",
|
|
1309
|
+
"yui session reconcile --report"
|
|
1224
1310
|
],
|
|
1225
|
-
children: profileChildren
|
|
1226
|
-
},
|
|
1227
|
-
{
|
|
1228
|
-
name: "role",
|
|
1229
|
-
summary: "Manage reusable global Roles and their native sessions.",
|
|
1230
1311
|
sections: [
|
|
1231
|
-
{ id: "
|
|
1232
|
-
{ id: "
|
|
1233
|
-
{ id: "sessions", title: "Sessions", entries: ["enter", "session"] }
|
|
1312
|
+
{ id: "global", title: "Global Role sessions", entries: ["context", "enter", "record", "replace"] },
|
|
1313
|
+
{ id: "recovery", title: "Recovery", entries: ["reconcile"] }
|
|
1234
1314
|
],
|
|
1235
|
-
children:
|
|
1315
|
+
children: globalSessionChildren
|
|
1236
1316
|
},
|
|
1237
1317
|
{
|
|
1238
1318
|
name: "task",
|
|
@@ -1333,6 +1413,20 @@ export function findCommandNode(path) {
|
|
|
1333
1413
|
return node;
|
|
1334
1414
|
}
|
|
1335
1415
|
export const findCommand = findCommandNode;
|
|
1416
|
+
/** Structured help projection consumed by `config describe --json` and Operator. */
|
|
1417
|
+
export function describeCommandTree(node) {
|
|
1418
|
+
return {
|
|
1419
|
+
path: node.path.slice(1).join(" "),
|
|
1420
|
+
summary: node.summary,
|
|
1421
|
+
usage: node.usage,
|
|
1422
|
+
examples: node.examples,
|
|
1423
|
+
options: node.options,
|
|
1424
|
+
optionValues: node.optionValues,
|
|
1425
|
+
argumentValues: node.argumentValues,
|
|
1426
|
+
values: node.values,
|
|
1427
|
+
children: visibleChildren(node).map(describeCommandTree)
|
|
1428
|
+
};
|
|
1429
|
+
}
|
|
1336
1430
|
export function validateCommandCatalog(root) {
|
|
1337
1431
|
const reservedAliases = new Set(["-h", "--help", "-help", "-v", "--version"]);
|
|
1338
1432
|
const commandPathProviders = [];
|
|
@@ -1341,6 +1435,16 @@ export function validateCommandCatalog(root) {
|
|
|
1341
1435
|
throw new Error(`Command summary is required: ${node.path.join(" ")}`);
|
|
1342
1436
|
if (node.usage.length === 0)
|
|
1343
1437
|
throw new Error(`Command usage is required: ${node.path.join(" ")}`);
|
|
1438
|
+
if (node.examples.length === 0 || node.examples.some((example) => example.trim().length === 0)) {
|
|
1439
|
+
throw new Error(`Command examples are required: ${node.path.join(" ")}`);
|
|
1440
|
+
}
|
|
1441
|
+
const canonicalPath = node.path.join(" ");
|
|
1442
|
+
for (const example of node.examples) {
|
|
1443
|
+
const normalized = example.replace(/^yui --json(?=\s|$)/, "yui");
|
|
1444
|
+
if (normalized !== canonicalPath && !normalized.startsWith(`${canonicalPath} `)) {
|
|
1445
|
+
throw new Error(`Command example does not match its path: ${canonicalPath}: ${example}`);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1344
1448
|
if (node.commandPathArguments) {
|
|
1345
1449
|
commandPathProviders.push(node);
|
|
1346
1450
|
const ownsOtherCompletionMetadata = node.kind !== "leaf"
|
|
@@ -1432,10 +1536,18 @@ export function validateCommandCatalog(root) {
|
|
|
1432
1536
|
if (!options.has(option))
|
|
1433
1537
|
throw new Error(`Executable completion references unknown option: ${[...node.path, option].join(" ")}`);
|
|
1434
1538
|
}
|
|
1539
|
+
if (new Set(node.workspaceMapOptions).size !== node.workspaceMapOptions.length) {
|
|
1540
|
+
throw new Error(`Duplicate workspace-map completion option: ${node.path.join(" ")}`);
|
|
1541
|
+
}
|
|
1542
|
+
for (const option of node.workspaceMapOptions) {
|
|
1543
|
+
if (!options.has(option))
|
|
1544
|
+
throw new Error(`Workspace-map completion references unknown option: ${[...node.path, option].join(" ")}`);
|
|
1545
|
+
}
|
|
1435
1546
|
for (const option of options) {
|
|
1436
1547
|
const owners = Number(Object.hasOwn(node.optionValues, option))
|
|
1437
1548
|
+ Number(node.fileOptions.includes(option))
|
|
1438
|
-
+ Number(node.executableOptions.includes(option))
|
|
1549
|
+
+ Number(node.executableOptions.includes(option))
|
|
1550
|
+
+ Number(node.workspaceMapOptions.includes(option));
|
|
1439
1551
|
if (owners > 1)
|
|
1440
1552
|
throw new Error(`Multiple completion owners for option: ${[...node.path, option].join(" ")}`);
|
|
1441
1553
|
}
|
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) {
|