@ricsam/r5dctl 0.0.39 → 0.0.41
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 +4 -4
- package/dist/cjs/cli.cjs +71 -52
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/cli.mjs +70 -52
- package/dist/mjs/package.json +1 -1
- package/dist/types/cli.d.ts +4 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -49,9 +49,9 @@ r5dctl delete project <namespace/name|id>
|
|
|
49
49
|
|
|
50
50
|
r5dctl -p <project> get branches
|
|
51
51
|
r5dctl -p <project> describe branch <branch>
|
|
52
|
-
r5dctl -p <project>
|
|
53
|
-
r5dctl -p <project>
|
|
54
|
-
r5dctl -p <project>
|
|
52
|
+
r5dctl -p <project> get envs
|
|
53
|
+
r5dctl -p <project> set envs --from-env-file ~/.env --only-missing
|
|
54
|
+
r5dctl -p <project> set envs -e API_KEY=value --description "API credential"
|
|
55
55
|
r5dctl -p <project> get sessions --branch <branch>
|
|
56
56
|
r5dctl -p <project> create session -b <branch> --name "Spec session"
|
|
57
57
|
r5dctl describe session <session-id>
|
|
@@ -69,7 +69,7 @@ r5dctl conversation inspect-work <session-id> <work-id> --summary
|
|
|
69
69
|
r5dctl conversation inspect-work <session-id> <work-id> --full
|
|
70
70
|
r5dctl -s <session-id> prompt --mode plan --model max "..."
|
|
71
71
|
r5dctl -s <session-id> answer-questions -a1 "Recipe Collection" -a2 "Both Manual & AI"
|
|
72
|
-
r5dctl -s <session-id>
|
|
72
|
+
r5dctl -s <session-id> answer-env-request -e KEY=value --context "Generate the remaining salts"
|
|
73
73
|
|
|
74
74
|
r5dctl -p <project> -b <branch> shell
|
|
75
75
|
r5dctl -p <project> -b <branch> shell -c "bun test"
|
package/dist/cjs/cli.cjs
CHANGED
|
@@ -36,6 +36,7 @@ __export(cli_exports, {
|
|
|
36
36
|
parseConversationRenderArgs: () => parseConversationRenderArgs,
|
|
37
37
|
parseConversationWorkDetailArgs: () => parseConversationWorkDetailArgs,
|
|
38
38
|
parseEnvFlags: () => parseEnvFlags,
|
|
39
|
+
parseEnvRequestResponseArgs: () => parseEnvRequestResponseArgs,
|
|
39
40
|
parseGlobalArgs: () => parseGlobalArgs,
|
|
40
41
|
parsePromptArgs: () => parsePromptArgs,
|
|
41
42
|
parsePsHistoryArgs: () => parsePsHistoryArgs,
|
|
@@ -153,18 +154,18 @@ const SHARED_HELP_ENTRIES = [
|
|
|
153
154
|
{ section: "branches", usage: "-p <project> describe branch <branch>", description: "Show branch URLs and sessions." },
|
|
154
155
|
{
|
|
155
156
|
section: "envs",
|
|
156
|
-
usage: "-p <project>
|
|
157
|
+
usage: "-p <project> get envs",
|
|
157
158
|
description: "List declared envs and whether each has a value, without revealing values."
|
|
158
159
|
},
|
|
159
160
|
{
|
|
160
161
|
section: "envs",
|
|
161
|
-
usage: "-p <project>
|
|
162
|
-
description: "Securely import
|
|
162
|
+
usage: "-p <project> set envs --from-env-file <path> [--only-missing]",
|
|
163
|
+
description: "Securely import project envs from a dotenv file without putting values in command arguments."
|
|
163
164
|
},
|
|
164
165
|
{
|
|
165
166
|
section: "envs",
|
|
166
|
-
usage: "-p <project>
|
|
167
|
-
description: "Set one or more
|
|
167
|
+
usage: "-p <project> set envs -e KEY=value [--description <text>] [--only-missing]",
|
|
168
|
+
description: "Set one or more project envs directly."
|
|
168
169
|
},
|
|
169
170
|
{
|
|
170
171
|
section: "sessions",
|
|
@@ -211,8 +212,8 @@ const SHARED_HELP_ENTRIES = [
|
|
|
211
212
|
},
|
|
212
213
|
{
|
|
213
214
|
section: "sessions",
|
|
214
|
-
usage: "-s <session-id>
|
|
215
|
-
description: "
|
|
215
|
+
usage: "-s <session-id> answer-env-request [-e KEY=value] [--context <text>]",
|
|
216
|
+
description: "Answer a pending environment variable request with values, context, or both."
|
|
216
217
|
},
|
|
217
218
|
{
|
|
218
219
|
section: "processes",
|
|
@@ -660,16 +661,6 @@ function parseSetEnvArgs(args) {
|
|
|
660
661
|
parsed.description = requireValue(inlineDescription, "Missing value for --description");
|
|
661
662
|
continue;
|
|
662
663
|
}
|
|
663
|
-
if (arg === "--optional") {
|
|
664
|
-
if (parsed.optional === false) throw new Error("Use only one of --optional or --required");
|
|
665
|
-
parsed.optional = true;
|
|
666
|
-
continue;
|
|
667
|
-
}
|
|
668
|
-
if (arg === "--required") {
|
|
669
|
-
if (parsed.optional === true) throw new Error("Use only one of --optional or --required");
|
|
670
|
-
parsed.optional = false;
|
|
671
|
-
continue;
|
|
672
|
-
}
|
|
673
664
|
if (arg === "--only-missing") {
|
|
674
665
|
parsed.onlyMissing = true;
|
|
675
666
|
continue;
|
|
@@ -730,6 +721,45 @@ function parseEnvFlags(args) {
|
|
|
730
721
|
}
|
|
731
722
|
return envs;
|
|
732
723
|
}
|
|
724
|
+
function parseEnvRequestResponseArgs(args) {
|
|
725
|
+
const envs = [];
|
|
726
|
+
let additionalContext;
|
|
727
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
728
|
+
const arg = args[index];
|
|
729
|
+
if (!arg) continue;
|
|
730
|
+
if (arg === "-e" || arg === "--env") {
|
|
731
|
+
const value = requireValue(args[index + 1], `Missing value for ${arg}`);
|
|
732
|
+
validateEnvAssignment(value);
|
|
733
|
+
if (value.slice(value.indexOf("=") + 1).trim()) envs.push(value);
|
|
734
|
+
index += 1;
|
|
735
|
+
continue;
|
|
736
|
+
}
|
|
737
|
+
const inlineEnv = parseLongOptionWithEquals(arg, "--env");
|
|
738
|
+
if (inlineEnv !== void 0) {
|
|
739
|
+
validateEnvAssignment(inlineEnv);
|
|
740
|
+
if (inlineEnv.slice(inlineEnv.indexOf("=") + 1).trim()) envs.push(inlineEnv);
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
743
|
+
if (arg === "--context") {
|
|
744
|
+
additionalContext = requireValue(args[index + 1], "Missing value for --context");
|
|
745
|
+
index += 1;
|
|
746
|
+
continue;
|
|
747
|
+
}
|
|
748
|
+
const inlineContext = parseLongOptionWithEquals(arg, "--context");
|
|
749
|
+
if (inlineContext !== void 0) {
|
|
750
|
+
additionalContext = inlineContext;
|
|
751
|
+
continue;
|
|
752
|
+
}
|
|
753
|
+
throw new Error(arg.startsWith("-") ? `Unknown answer env request flag: ${arg}` : `Unexpected value '${arg}'`);
|
|
754
|
+
}
|
|
755
|
+
if (envs.length === 0 && !additionalContext?.trim()) {
|
|
756
|
+
throw new Error("Provide at least one -e/--env value or --context.");
|
|
757
|
+
}
|
|
758
|
+
return {
|
|
759
|
+
...envs.length > 0 ? { envs } : {},
|
|
760
|
+
...additionalContext?.trim() ? { additionalContext: additionalContext.trim() } : {}
|
|
761
|
+
};
|
|
762
|
+
}
|
|
733
763
|
function parsePromptArgs(args) {
|
|
734
764
|
let modeRaw;
|
|
735
765
|
let modelRaw;
|
|
@@ -1145,7 +1175,6 @@ function summarizeEnvData(data) {
|
|
|
1145
1175
|
Object.entries(data).sort(([left], [right]) => left.localeCompare(right)).map(([name, env]) => [
|
|
1146
1176
|
name,
|
|
1147
1177
|
{
|
|
1148
|
-
optional: env.optional ?? false,
|
|
1149
1178
|
description: env.description,
|
|
1150
1179
|
hasValue: env.value !== null
|
|
1151
1180
|
}
|
|
@@ -1155,15 +1184,13 @@ function summarizeEnvData(data) {
|
|
|
1155
1184
|
function renderEnvSummary(data) {
|
|
1156
1185
|
const lines = [];
|
|
1157
1186
|
for (const [name, env] of Object.entries(data)) {
|
|
1158
|
-
lines.push(`${name} ${env.hasValue ? "set" : "missing"} ${env.
|
|
1187
|
+
lines.push(`${name} ${env.hasValue ? "set" : "missing"} ${env.description}`);
|
|
1159
1188
|
}
|
|
1160
1189
|
return lines.length > 0 ? `${lines.join("\n")}
|
|
1161
1190
|
` : "No environment variables declared.\n";
|
|
1162
1191
|
}
|
|
1163
1192
|
function renderEnvSetResult(result) {
|
|
1164
|
-
const lines = [
|
|
1165
|
-
`Updated ${result.updated.length} environment variable${result.updated.length === 1 ? "" : "s"} for ${result.project}/${result.branch}.`
|
|
1166
|
-
];
|
|
1193
|
+
const lines = [`Updated ${result.updated.length} environment variable${result.updated.length === 1 ? "" : "s"} for ${result.project}.`];
|
|
1167
1194
|
if (result.skippedExisting.length > 0) lines.push(`Skipped ${result.skippedExisting.length} existing value(s).`);
|
|
1168
1195
|
if (result.skippedEmpty.length > 0) lines.push(`Skipped ${result.skippedEmpty.length} empty value(s).`);
|
|
1169
1196
|
if (result.updated.length > 0) {
|
|
@@ -1172,10 +1199,10 @@ function renderEnvSetResult(result) {
|
|
|
1172
1199
|
return `${lines.join("\n")}
|
|
1173
1200
|
`;
|
|
1174
1201
|
}
|
|
1175
|
-
async function
|
|
1202
|
+
async function setProjectEnvs(client, projectRef, args) {
|
|
1176
1203
|
const options = parseSetEnvArgs(args);
|
|
1177
1204
|
const project = await client.projects.describe(projectRef);
|
|
1178
|
-
const current = await client.projects.env.get(project.id
|
|
1205
|
+
const current = await client.projects.env.get(project.id);
|
|
1179
1206
|
const assignments = options.fromEnvFile ? Object.entries(readDotenvFile(options.fromEnvFile)).map(([name, value]) => {
|
|
1180
1207
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
|
|
1181
1208
|
throw new Error(`Invalid environment variable name in dotenv file: ${name}`);
|
|
@@ -1188,7 +1215,6 @@ async function setBranchEnvs(client, projectRef, branchName, args) {
|
|
|
1188
1215
|
const result = {
|
|
1189
1216
|
success: true,
|
|
1190
1217
|
project: project.path,
|
|
1191
|
-
branch: branchName,
|
|
1192
1218
|
updated: [],
|
|
1193
1219
|
skippedExisting: [],
|
|
1194
1220
|
skippedEmpty: []
|
|
@@ -1211,11 +1237,9 @@ async function setBranchEnvs(client, projectRef, branchName, args) {
|
|
|
1211
1237
|
missingDescriptions.push(identity);
|
|
1212
1238
|
continue;
|
|
1213
1239
|
}
|
|
1214
|
-
const optional = options.optional ?? existing?.optional;
|
|
1215
1240
|
update[assignment.name] = {
|
|
1216
1241
|
description,
|
|
1217
|
-
value: assignment.value
|
|
1218
|
-
...optional === void 0 ? {} : { optional }
|
|
1242
|
+
value: assignment.value
|
|
1219
1243
|
};
|
|
1220
1244
|
result.updated.push(identity);
|
|
1221
1245
|
}
|
|
@@ -1223,7 +1247,7 @@ async function setBranchEnvs(client, projectRef, branchName, args) {
|
|
|
1223
1247
|
throw new Error(`--description is required when declaring new envs with -e: ${missingDescriptions.map(({ name }) => name).join(", ")}`);
|
|
1224
1248
|
}
|
|
1225
1249
|
if (result.updated.length > 0) {
|
|
1226
|
-
await client.projects.env.update(project.id,
|
|
1250
|
+
await client.projects.env.update(project.id, update);
|
|
1227
1251
|
}
|
|
1228
1252
|
return result;
|
|
1229
1253
|
}
|
|
@@ -1497,20 +1521,15 @@ Sessions: ${result.sessions.length}
|
|
|
1497
1521
|
return;
|
|
1498
1522
|
}
|
|
1499
1523
|
if (first === "get" && second === "envs") {
|
|
1524
|
+
if (args.length !== 3) throw new Error(`Unexpected get envs argument: ${args[3] ?? ""}`.trim());
|
|
1500
1525
|
const projectRef = requireValue(args[2], "Missing project reference");
|
|
1501
|
-
const branchName = requireValue(args[3], "Missing branch name");
|
|
1502
1526
|
const project = await client.projects.describe(projectRef);
|
|
1503
|
-
const envs = summarizeEnvData(await client.projects.env.get(project.id
|
|
1504
|
-
write({ project: project.path,
|
|
1527
|
+
const envs = summarizeEnvData(await client.projects.env.get(project.id));
|
|
1528
|
+
write({ project: project.path, envs }, renderEnvSummary(envs));
|
|
1505
1529
|
return;
|
|
1506
1530
|
}
|
|
1507
1531
|
if (first === "set" && second === "envs") {
|
|
1508
|
-
const result = await
|
|
1509
|
-
client,
|
|
1510
|
-
requireValue(args[2], "Missing project reference"),
|
|
1511
|
-
requireValue(args[3], "Missing branch name"),
|
|
1512
|
-
args.slice(4)
|
|
1513
|
-
);
|
|
1532
|
+
const result = await setProjectEnvs(client, requireValue(args[2], "Missing project reference"), args.slice(3));
|
|
1514
1533
|
write(result, renderEnvSetResult(result));
|
|
1515
1534
|
return;
|
|
1516
1535
|
}
|
|
@@ -1646,11 +1665,10 @@ ${result.message}
|
|
|
1646
1665
|
write(read, renderConversationResponse(read));
|
|
1647
1666
|
return;
|
|
1648
1667
|
}
|
|
1649
|
-
if (first === "sessions" && second === "
|
|
1650
|
-
const offset = first === "
|
|
1651
|
-
const
|
|
1652
|
-
|
|
1653
|
-
const read = await client.sessions.applyRequiredEnvs(requireValue(args[offset], "Missing session id"), { envs });
|
|
1668
|
+
if (first === "sessions" && second === "answer-env-request" || first === "answer-env-request") {
|
|
1669
|
+
const offset = first === "answer-env-request" ? 1 : 2;
|
|
1670
|
+
const input = parseEnvRequestResponseArgs(args.slice(offset + 1));
|
|
1671
|
+
const read = await client.sessions.answerEnvRequest(requireValue(args[offset], "Missing session id"), input);
|
|
1654
1672
|
write(read, renderConversationResponse(read));
|
|
1655
1673
|
return;
|
|
1656
1674
|
}
|
|
@@ -1832,12 +1850,12 @@ function resolveCommandExecution(options, rest) {
|
|
|
1832
1850
|
if (!options.project) {
|
|
1833
1851
|
throw new Error("--project/-p is required for `get envs`");
|
|
1834
1852
|
}
|
|
1835
|
-
if (
|
|
1836
|
-
throw new Error("--branch/-b is
|
|
1853
|
+
if (options.branch) {
|
|
1854
|
+
throw new Error("--branch/-b is not supported for project environment variables");
|
|
1837
1855
|
}
|
|
1838
1856
|
return {
|
|
1839
1857
|
kind: "plugin",
|
|
1840
|
-
pluginArgs: ["get", "envs", options.project
|
|
1858
|
+
pluginArgs: ["get", "envs", options.project]
|
|
1841
1859
|
};
|
|
1842
1860
|
}
|
|
1843
1861
|
throw new Error("Unknown get command");
|
|
@@ -1850,12 +1868,12 @@ function resolveCommandExecution(options, rest) {
|
|
|
1850
1868
|
if (!options.project) {
|
|
1851
1869
|
throw new Error("--project/-p is required for `set envs`");
|
|
1852
1870
|
}
|
|
1853
|
-
if (
|
|
1854
|
-
throw new Error("--branch/-b is
|
|
1871
|
+
if (options.branch) {
|
|
1872
|
+
throw new Error("--branch/-b is not supported for project environment variables");
|
|
1855
1873
|
}
|
|
1856
1874
|
return {
|
|
1857
1875
|
kind: "plugin",
|
|
1858
|
-
pluginArgs: ["set", "envs", options.project,
|
|
1876
|
+
pluginArgs: ["set", "envs", options.project, ...commandArgs.slice(1)]
|
|
1859
1877
|
};
|
|
1860
1878
|
}
|
|
1861
1879
|
if (command === "describe") {
|
|
@@ -2126,14 +2144,14 @@ function resolveCommandExecution(options, rest) {
|
|
|
2126
2144
|
pluginArgs: ["answer-questions", sessionId, ...parseAnswerFlags(commandArgs)]
|
|
2127
2145
|
};
|
|
2128
2146
|
}
|
|
2129
|
-
if (command === "
|
|
2147
|
+
if (command === "answer-env-request") {
|
|
2130
2148
|
const sessionId = options.session;
|
|
2131
2149
|
if (!sessionId) {
|
|
2132
|
-
throw new Error("--session/-s is required for `
|
|
2150
|
+
throw new Error("--session/-s is required for `answer-env-request`");
|
|
2133
2151
|
}
|
|
2134
2152
|
return {
|
|
2135
2153
|
kind: "plugin",
|
|
2136
|
-
pluginArgs: ["
|
|
2154
|
+
pluginArgs: ["answer-env-request", sessionId, ...commandArgs]
|
|
2137
2155
|
};
|
|
2138
2156
|
}
|
|
2139
2157
|
throw new Error(`Unknown command: ${command}`);
|
|
@@ -2219,6 +2237,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
2219
2237
|
parseConversationRenderArgs,
|
|
2220
2238
|
parseConversationWorkDetailArgs,
|
|
2221
2239
|
parseEnvFlags,
|
|
2240
|
+
parseEnvRequestResponseArgs,
|
|
2222
2241
|
parseGlobalArgs,
|
|
2223
2242
|
parsePromptArgs,
|
|
2224
2243
|
parsePsHistoryArgs,
|
package/dist/cjs/package.json
CHANGED
package/dist/mjs/cli.mjs
CHANGED
|
@@ -98,18 +98,18 @@ const SHARED_HELP_ENTRIES = [
|
|
|
98
98
|
{ section: "branches", usage: "-p <project> describe branch <branch>", description: "Show branch URLs and sessions." },
|
|
99
99
|
{
|
|
100
100
|
section: "envs",
|
|
101
|
-
usage: "-p <project>
|
|
101
|
+
usage: "-p <project> get envs",
|
|
102
102
|
description: "List declared envs and whether each has a value, without revealing values."
|
|
103
103
|
},
|
|
104
104
|
{
|
|
105
105
|
section: "envs",
|
|
106
|
-
usage: "-p <project>
|
|
107
|
-
description: "Securely import
|
|
106
|
+
usage: "-p <project> set envs --from-env-file <path> [--only-missing]",
|
|
107
|
+
description: "Securely import project envs from a dotenv file without putting values in command arguments."
|
|
108
108
|
},
|
|
109
109
|
{
|
|
110
110
|
section: "envs",
|
|
111
|
-
usage: "-p <project>
|
|
112
|
-
description: "Set one or more
|
|
111
|
+
usage: "-p <project> set envs -e KEY=value [--description <text>] [--only-missing]",
|
|
112
|
+
description: "Set one or more project envs directly."
|
|
113
113
|
},
|
|
114
114
|
{
|
|
115
115
|
section: "sessions",
|
|
@@ -156,8 +156,8 @@ const SHARED_HELP_ENTRIES = [
|
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
section: "sessions",
|
|
159
|
-
usage: "-s <session-id>
|
|
160
|
-
description: "
|
|
159
|
+
usage: "-s <session-id> answer-env-request [-e KEY=value] [--context <text>]",
|
|
160
|
+
description: "Answer a pending environment variable request with values, context, or both."
|
|
161
161
|
},
|
|
162
162
|
{
|
|
163
163
|
section: "processes",
|
|
@@ -605,16 +605,6 @@ function parseSetEnvArgs(args) {
|
|
|
605
605
|
parsed.description = requireValue(inlineDescription, "Missing value for --description");
|
|
606
606
|
continue;
|
|
607
607
|
}
|
|
608
|
-
if (arg === "--optional") {
|
|
609
|
-
if (parsed.optional === false) throw new Error("Use only one of --optional or --required");
|
|
610
|
-
parsed.optional = true;
|
|
611
|
-
continue;
|
|
612
|
-
}
|
|
613
|
-
if (arg === "--required") {
|
|
614
|
-
if (parsed.optional === true) throw new Error("Use only one of --optional or --required");
|
|
615
|
-
parsed.optional = false;
|
|
616
|
-
continue;
|
|
617
|
-
}
|
|
618
608
|
if (arg === "--only-missing") {
|
|
619
609
|
parsed.onlyMissing = true;
|
|
620
610
|
continue;
|
|
@@ -675,6 +665,45 @@ function parseEnvFlags(args) {
|
|
|
675
665
|
}
|
|
676
666
|
return envs;
|
|
677
667
|
}
|
|
668
|
+
function parseEnvRequestResponseArgs(args) {
|
|
669
|
+
const envs = [];
|
|
670
|
+
let additionalContext;
|
|
671
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
672
|
+
const arg = args[index];
|
|
673
|
+
if (!arg) continue;
|
|
674
|
+
if (arg === "-e" || arg === "--env") {
|
|
675
|
+
const value = requireValue(args[index + 1], `Missing value for ${arg}`);
|
|
676
|
+
validateEnvAssignment(value);
|
|
677
|
+
if (value.slice(value.indexOf("=") + 1).trim()) envs.push(value);
|
|
678
|
+
index += 1;
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
const inlineEnv = parseLongOptionWithEquals(arg, "--env");
|
|
682
|
+
if (inlineEnv !== void 0) {
|
|
683
|
+
validateEnvAssignment(inlineEnv);
|
|
684
|
+
if (inlineEnv.slice(inlineEnv.indexOf("=") + 1).trim()) envs.push(inlineEnv);
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
if (arg === "--context") {
|
|
688
|
+
additionalContext = requireValue(args[index + 1], "Missing value for --context");
|
|
689
|
+
index += 1;
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
692
|
+
const inlineContext = parseLongOptionWithEquals(arg, "--context");
|
|
693
|
+
if (inlineContext !== void 0) {
|
|
694
|
+
additionalContext = inlineContext;
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
throw new Error(arg.startsWith("-") ? `Unknown answer env request flag: ${arg}` : `Unexpected value '${arg}'`);
|
|
698
|
+
}
|
|
699
|
+
if (envs.length === 0 && !additionalContext?.trim()) {
|
|
700
|
+
throw new Error("Provide at least one -e/--env value or --context.");
|
|
701
|
+
}
|
|
702
|
+
return {
|
|
703
|
+
...envs.length > 0 ? { envs } : {},
|
|
704
|
+
...additionalContext?.trim() ? { additionalContext: additionalContext.trim() } : {}
|
|
705
|
+
};
|
|
706
|
+
}
|
|
678
707
|
function parsePromptArgs(args) {
|
|
679
708
|
let modeRaw;
|
|
680
709
|
let modelRaw;
|
|
@@ -1090,7 +1119,6 @@ function summarizeEnvData(data) {
|
|
|
1090
1119
|
Object.entries(data).sort(([left], [right]) => left.localeCompare(right)).map(([name, env]) => [
|
|
1091
1120
|
name,
|
|
1092
1121
|
{
|
|
1093
|
-
optional: env.optional ?? false,
|
|
1094
1122
|
description: env.description,
|
|
1095
1123
|
hasValue: env.value !== null
|
|
1096
1124
|
}
|
|
@@ -1100,15 +1128,13 @@ function summarizeEnvData(data) {
|
|
|
1100
1128
|
function renderEnvSummary(data) {
|
|
1101
1129
|
const lines = [];
|
|
1102
1130
|
for (const [name, env] of Object.entries(data)) {
|
|
1103
|
-
lines.push(`${name} ${env.hasValue ? "set" : "missing"} ${env.
|
|
1131
|
+
lines.push(`${name} ${env.hasValue ? "set" : "missing"} ${env.description}`);
|
|
1104
1132
|
}
|
|
1105
1133
|
return lines.length > 0 ? `${lines.join("\n")}
|
|
1106
1134
|
` : "No environment variables declared.\n";
|
|
1107
1135
|
}
|
|
1108
1136
|
function renderEnvSetResult(result) {
|
|
1109
|
-
const lines = [
|
|
1110
|
-
`Updated ${result.updated.length} environment variable${result.updated.length === 1 ? "" : "s"} for ${result.project}/${result.branch}.`
|
|
1111
|
-
];
|
|
1137
|
+
const lines = [`Updated ${result.updated.length} environment variable${result.updated.length === 1 ? "" : "s"} for ${result.project}.`];
|
|
1112
1138
|
if (result.skippedExisting.length > 0) lines.push(`Skipped ${result.skippedExisting.length} existing value(s).`);
|
|
1113
1139
|
if (result.skippedEmpty.length > 0) lines.push(`Skipped ${result.skippedEmpty.length} empty value(s).`);
|
|
1114
1140
|
if (result.updated.length > 0) {
|
|
@@ -1117,10 +1143,10 @@ function renderEnvSetResult(result) {
|
|
|
1117
1143
|
return `${lines.join("\n")}
|
|
1118
1144
|
`;
|
|
1119
1145
|
}
|
|
1120
|
-
async function
|
|
1146
|
+
async function setProjectEnvs(client, projectRef, args) {
|
|
1121
1147
|
const options = parseSetEnvArgs(args);
|
|
1122
1148
|
const project = await client.projects.describe(projectRef);
|
|
1123
|
-
const current = await client.projects.env.get(project.id
|
|
1149
|
+
const current = await client.projects.env.get(project.id);
|
|
1124
1150
|
const assignments = options.fromEnvFile ? Object.entries(readDotenvFile(options.fromEnvFile)).map(([name, value]) => {
|
|
1125
1151
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
|
|
1126
1152
|
throw new Error(`Invalid environment variable name in dotenv file: ${name}`);
|
|
@@ -1133,7 +1159,6 @@ async function setBranchEnvs(client, projectRef, branchName, args) {
|
|
|
1133
1159
|
const result = {
|
|
1134
1160
|
success: true,
|
|
1135
1161
|
project: project.path,
|
|
1136
|
-
branch: branchName,
|
|
1137
1162
|
updated: [],
|
|
1138
1163
|
skippedExisting: [],
|
|
1139
1164
|
skippedEmpty: []
|
|
@@ -1156,11 +1181,9 @@ async function setBranchEnvs(client, projectRef, branchName, args) {
|
|
|
1156
1181
|
missingDescriptions.push(identity);
|
|
1157
1182
|
continue;
|
|
1158
1183
|
}
|
|
1159
|
-
const optional = options.optional ?? existing?.optional;
|
|
1160
1184
|
update[assignment.name] = {
|
|
1161
1185
|
description,
|
|
1162
|
-
value: assignment.value
|
|
1163
|
-
...optional === void 0 ? {} : { optional }
|
|
1186
|
+
value: assignment.value
|
|
1164
1187
|
};
|
|
1165
1188
|
result.updated.push(identity);
|
|
1166
1189
|
}
|
|
@@ -1168,7 +1191,7 @@ async function setBranchEnvs(client, projectRef, branchName, args) {
|
|
|
1168
1191
|
throw new Error(`--description is required when declaring new envs with -e: ${missingDescriptions.map(({ name }) => name).join(", ")}`);
|
|
1169
1192
|
}
|
|
1170
1193
|
if (result.updated.length > 0) {
|
|
1171
|
-
await client.projects.env.update(project.id,
|
|
1194
|
+
await client.projects.env.update(project.id, update);
|
|
1172
1195
|
}
|
|
1173
1196
|
return result;
|
|
1174
1197
|
}
|
|
@@ -1442,20 +1465,15 @@ Sessions: ${result.sessions.length}
|
|
|
1442
1465
|
return;
|
|
1443
1466
|
}
|
|
1444
1467
|
if (first === "get" && second === "envs") {
|
|
1468
|
+
if (args.length !== 3) throw new Error(`Unexpected get envs argument: ${args[3] ?? ""}`.trim());
|
|
1445
1469
|
const projectRef = requireValue(args[2], "Missing project reference");
|
|
1446
|
-
const branchName = requireValue(args[3], "Missing branch name");
|
|
1447
1470
|
const project = await client.projects.describe(projectRef);
|
|
1448
|
-
const envs = summarizeEnvData(await client.projects.env.get(project.id
|
|
1449
|
-
write({ project: project.path,
|
|
1471
|
+
const envs = summarizeEnvData(await client.projects.env.get(project.id));
|
|
1472
|
+
write({ project: project.path, envs }, renderEnvSummary(envs));
|
|
1450
1473
|
return;
|
|
1451
1474
|
}
|
|
1452
1475
|
if (first === "set" && second === "envs") {
|
|
1453
|
-
const result = await
|
|
1454
|
-
client,
|
|
1455
|
-
requireValue(args[2], "Missing project reference"),
|
|
1456
|
-
requireValue(args[3], "Missing branch name"),
|
|
1457
|
-
args.slice(4)
|
|
1458
|
-
);
|
|
1476
|
+
const result = await setProjectEnvs(client, requireValue(args[2], "Missing project reference"), args.slice(3));
|
|
1459
1477
|
write(result, renderEnvSetResult(result));
|
|
1460
1478
|
return;
|
|
1461
1479
|
}
|
|
@@ -1591,11 +1609,10 @@ ${result.message}
|
|
|
1591
1609
|
write(read, renderConversationResponse(read));
|
|
1592
1610
|
return;
|
|
1593
1611
|
}
|
|
1594
|
-
if (first === "sessions" && second === "
|
|
1595
|
-
const offset = first === "
|
|
1596
|
-
const
|
|
1597
|
-
|
|
1598
|
-
const read = await client.sessions.applyRequiredEnvs(requireValue(args[offset], "Missing session id"), { envs });
|
|
1612
|
+
if (first === "sessions" && second === "answer-env-request" || first === "answer-env-request") {
|
|
1613
|
+
const offset = first === "answer-env-request" ? 1 : 2;
|
|
1614
|
+
const input = parseEnvRequestResponseArgs(args.slice(offset + 1));
|
|
1615
|
+
const read = await client.sessions.answerEnvRequest(requireValue(args[offset], "Missing session id"), input);
|
|
1599
1616
|
write(read, renderConversationResponse(read));
|
|
1600
1617
|
return;
|
|
1601
1618
|
}
|
|
@@ -1777,12 +1794,12 @@ function resolveCommandExecution(options, rest) {
|
|
|
1777
1794
|
if (!options.project) {
|
|
1778
1795
|
throw new Error("--project/-p is required for `get envs`");
|
|
1779
1796
|
}
|
|
1780
|
-
if (
|
|
1781
|
-
throw new Error("--branch/-b is
|
|
1797
|
+
if (options.branch) {
|
|
1798
|
+
throw new Error("--branch/-b is not supported for project environment variables");
|
|
1782
1799
|
}
|
|
1783
1800
|
return {
|
|
1784
1801
|
kind: "plugin",
|
|
1785
|
-
pluginArgs: ["get", "envs", options.project
|
|
1802
|
+
pluginArgs: ["get", "envs", options.project]
|
|
1786
1803
|
};
|
|
1787
1804
|
}
|
|
1788
1805
|
throw new Error("Unknown get command");
|
|
@@ -1795,12 +1812,12 @@ function resolveCommandExecution(options, rest) {
|
|
|
1795
1812
|
if (!options.project) {
|
|
1796
1813
|
throw new Error("--project/-p is required for `set envs`");
|
|
1797
1814
|
}
|
|
1798
|
-
if (
|
|
1799
|
-
throw new Error("--branch/-b is
|
|
1815
|
+
if (options.branch) {
|
|
1816
|
+
throw new Error("--branch/-b is not supported for project environment variables");
|
|
1800
1817
|
}
|
|
1801
1818
|
return {
|
|
1802
1819
|
kind: "plugin",
|
|
1803
|
-
pluginArgs: ["set", "envs", options.project,
|
|
1820
|
+
pluginArgs: ["set", "envs", options.project, ...commandArgs.slice(1)]
|
|
1804
1821
|
};
|
|
1805
1822
|
}
|
|
1806
1823
|
if (command === "describe") {
|
|
@@ -2071,14 +2088,14 @@ function resolveCommandExecution(options, rest) {
|
|
|
2071
2088
|
pluginArgs: ["answer-questions", sessionId, ...parseAnswerFlags(commandArgs)]
|
|
2072
2089
|
};
|
|
2073
2090
|
}
|
|
2074
|
-
if (command === "
|
|
2091
|
+
if (command === "answer-env-request") {
|
|
2075
2092
|
const sessionId = options.session;
|
|
2076
2093
|
if (!sessionId) {
|
|
2077
|
-
throw new Error("--session/-s is required for `
|
|
2094
|
+
throw new Error("--session/-s is required for `answer-env-request`");
|
|
2078
2095
|
}
|
|
2079
2096
|
return {
|
|
2080
2097
|
kind: "plugin",
|
|
2081
|
-
pluginArgs: ["
|
|
2098
|
+
pluginArgs: ["answer-env-request", sessionId, ...commandArgs]
|
|
2082
2099
|
};
|
|
2083
2100
|
}
|
|
2084
2101
|
throw new Error(`Unknown command: ${command}`);
|
|
@@ -2163,6 +2180,7 @@ export {
|
|
|
2163
2180
|
parseConversationRenderArgs,
|
|
2164
2181
|
parseConversationWorkDetailArgs,
|
|
2165
2182
|
parseEnvFlags,
|
|
2183
|
+
parseEnvRequestResponseArgs,
|
|
2166
2184
|
parseGlobalArgs,
|
|
2167
2185
|
parsePromptArgs,
|
|
2168
2186
|
parsePsHistoryArgs,
|
package/dist/mjs/package.json
CHANGED
package/dist/types/cli.d.ts
CHANGED
|
@@ -45,13 +45,16 @@ export type SetEnvOptions = {
|
|
|
45
45
|
assignments: string[];
|
|
46
46
|
fromEnvFile?: string;
|
|
47
47
|
description?: string;
|
|
48
|
-
optional?: boolean;
|
|
49
48
|
onlyMissing: boolean;
|
|
50
49
|
includeEmpty: boolean;
|
|
51
50
|
};
|
|
52
51
|
export declare function parseSetEnvArgs(args: string[]): SetEnvOptions;
|
|
53
52
|
export declare function readDotenvFile(filePath: string): Record<string, string>;
|
|
54
53
|
export declare function parseEnvFlags(args: string[]): string[];
|
|
54
|
+
export declare function parseEnvRequestResponseArgs(args: string[]): {
|
|
55
|
+
envs?: string[];
|
|
56
|
+
additionalContext?: string;
|
|
57
|
+
};
|
|
55
58
|
export declare function parsePromptArgs(args: string[]): {
|
|
56
59
|
mode: ChatMode;
|
|
57
60
|
model: ModelTier;
|
|
@@ -69,7 +72,6 @@ export declare function renderProcessList(processes: R5dctlProcessRun[], nowMs?:
|
|
|
69
72
|
export declare function renderProcessHistory(processes: R5dctlProcessRun[], nowMs?: number): string;
|
|
70
73
|
export declare function renderProcessInspection(process: R5dctlProcessInspection): string;
|
|
71
74
|
export type EnvSummaryData = Record<string, {
|
|
72
|
-
optional: boolean;
|
|
73
75
|
description: string;
|
|
74
76
|
hasValue: boolean;
|
|
75
77
|
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ricsam/r5dctl",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/cjs/cli.cjs",
|
|
6
6
|
"module": "./dist/mjs/cli.mjs",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"r5dctl": "dist/cjs/main.cjs"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ricsam/r5d-api": "^0.0.
|
|
29
|
+
"@ricsam/r5d-api": "^0.0.41",
|
|
30
30
|
"dotenv": "^17",
|
|
31
31
|
"ws": "^8.18.3"
|
|
32
32
|
},
|