@mytegroupinc/myte-core 0.0.45 → 0.0.46
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 +20 -16
- package/THIRD_PARTY_NOTICES.md +21 -21
- package/TRADEMARKS.md +10 -10
- package/cli.js +332 -489
- package/lib/mytecody-release-public-key.pem +11 -11
- package/lib/mytecody-splash.js +251 -251
- package/mytecody-cli.js +2025 -2025
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -235,12 +235,6 @@ function printHelp() {
|
|
|
235
235
|
" - Set MYTE_API_KEY in a workspace .env (or env var)",
|
|
236
236
|
" - Set MYTEAI_API_KEY in a workspace .env (or env var) for `myte ai`",
|
|
237
237
|
"",
|
|
238
|
-
"Live write approval:",
|
|
239
|
-
" - Live project-key mutations require --confirm-write --approval-artifact <path>",
|
|
240
|
-
" - The artifact must be a local .md, .yml/.yaml, or .json file shown to and approved by the user before the command is rerun",
|
|
241
|
-
" - Batch artifacts must enumerate every feedback id, mission id, suggestion id, request id, or PRD item",
|
|
242
|
-
" - Read/sync/query/validate, --print-context, and --dry-run commands do not require write approval",
|
|
243
|
-
"",
|
|
244
238
|
"bootstrap contract:",
|
|
245
239
|
" - Run from any workspace where you want local MyteCommandCenter data written",
|
|
246
240
|
" - Writes MyteCommandCenter/data/project.yml plus phases, epics, stories, and missions locally",
|
|
@@ -402,8 +396,6 @@ function printHelp() {
|
|
|
402
396
|
" --wait Poll batch status until terminal completion for run-qaqc",
|
|
403
397
|
" --sync After run-qaqc completes, refresh local QAQC file",
|
|
404
398
|
" --force Allow run-qaqc to bypass stale-state protection when supported",
|
|
405
|
-
" --confirm-write Confirm the user explicitly approved a live Myte project-key mutation",
|
|
406
|
-
" --approval-artifact Local .md/.yml/.json approval artifact shown to and approved by the user",
|
|
407
399
|
" --no-sync Skip automatic post-mutation sync for suggestions, missions, and feedback mutations",
|
|
408
400
|
" --print-context Print JSON payload and exit (no query call)",
|
|
409
401
|
" --no-fetch Don't git fetch origin main/master before diff",
|
|
@@ -701,164 +693,6 @@ async function fetchJsonWithTimeout(fetchFn, url, options, timeoutMs) {
|
|
|
701
693
|
}
|
|
702
694
|
}
|
|
703
695
|
|
|
704
|
-
const WRITE_APPROVAL_TRANSPORT_KEYS = new Set(["write_approval", "client_session_id"]);
|
|
705
|
-
|
|
706
|
-
function canonicalizeWritePayload(value) {
|
|
707
|
-
if (Array.isArray(value)) {
|
|
708
|
-
return value.map((item) => canonicalizeWritePayload(item));
|
|
709
|
-
}
|
|
710
|
-
if (value && typeof value === "object") {
|
|
711
|
-
return Object.fromEntries(
|
|
712
|
-
Object.keys(value)
|
|
713
|
-
.filter((key) => !WRITE_APPROVAL_TRANSPORT_KEYS.has(String(key)))
|
|
714
|
-
.sort()
|
|
715
|
-
.map((key) => [key, canonicalizeWritePayload(value[key])])
|
|
716
|
-
);
|
|
717
|
-
}
|
|
718
|
-
return value;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
function projectApiWritePayloadHash(payload) {
|
|
722
|
-
return createHash("sha256")
|
|
723
|
-
.update(pythonJsonDumpsCompatible(canonicalizeWritePayload(payload || {})))
|
|
724
|
-
.digest("hex");
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
function isConfirmWrite(args) {
|
|
728
|
-
return Boolean(args["confirm-write"] || args.confirmWrite || args.confirm_write);
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
function resolveWriteApprovalArtifactPath(args) {
|
|
732
|
-
const explicit = firstNonEmptyString(args["approval-artifact"], args.approvalArtifact, args.approval_artifact);
|
|
733
|
-
if (!explicit) return "";
|
|
734
|
-
const resolved = path.resolve(process.cwd(), explicit);
|
|
735
|
-
if (!fs.existsSync(resolved) || !fs.statSync(resolved).isFile()) {
|
|
736
|
-
console.error(`Approval artifact not found: ${resolved}`);
|
|
737
|
-
process.exit(1);
|
|
738
|
-
}
|
|
739
|
-
return resolved;
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
function inferApprovalArtifactKind(filePath, fallbackKind) {
|
|
743
|
-
const ext = path.extname(String(filePath || "")).toLowerCase();
|
|
744
|
-
if (ext === ".md" || ext === ".markdown") return "markdown";
|
|
745
|
-
if (ext === ".yml" || ext === ".yaml") return "yaml";
|
|
746
|
-
if (ext === ".json") return "json";
|
|
747
|
-
return fallbackKind || "artifact";
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
function normalizeApprovalTargets(targets) {
|
|
751
|
-
return toStringArray(targets).map((item) => item.trim()).filter(Boolean);
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
function writePayloadItems(payload) {
|
|
755
|
-
if (Array.isArray(payload?.items)) return payload.items;
|
|
756
|
-
if (Array.isArray(payload)) return payload;
|
|
757
|
-
return payload && typeof payload === "object" ? [payload] : [];
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
function suggestionApprovalTargets(payload) {
|
|
761
|
-
return writePayloadItems(payload).map((item, index) => {
|
|
762
|
-
if (!item || typeof item !== "object") return `index:${index}`;
|
|
763
|
-
return firstNonEmptyString(
|
|
764
|
-
item.suggestion_id,
|
|
765
|
-
item.id,
|
|
766
|
-
item._id,
|
|
767
|
-
item.mission_id,
|
|
768
|
-
item.target_mission_id,
|
|
769
|
-
item.title ? `${item.change_type || "suggestion"}:${item.title}` : ""
|
|
770
|
-
) || `index:${index}`;
|
|
771
|
-
});
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
function prdApprovalTargets(payload) {
|
|
775
|
-
return writePayloadItems(payload).map((item, index) => {
|
|
776
|
-
if (!item || typeof item !== "object") return `index:${index}`;
|
|
777
|
-
return firstNonEmptyString(item.client_ref, item.title) || `index:${index}`;
|
|
778
|
-
});
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
function requireWriteApproval(args, payload, { operation, artifactKind, targets = [], batchCount = null } = {}) {
|
|
782
|
-
const payloadSha256 = projectApiWritePayloadHash(payload || {});
|
|
783
|
-
const targetValues = normalizeApprovalTargets(targets);
|
|
784
|
-
const expectedBatchCount = batchCount !== null && batchCount !== undefined
|
|
785
|
-
? Number(batchCount)
|
|
786
|
-
: targetValues.length > 1
|
|
787
|
-
? targetValues.length
|
|
788
|
-
: null;
|
|
789
|
-
|
|
790
|
-
if (!isConfirmWrite(args)) {
|
|
791
|
-
console.error("Refusing live Myte write without explicit human approval.");
|
|
792
|
-
console.error(`Operation: ${operation || "unknown"}`);
|
|
793
|
-
console.error(`Payload SHA256: ${payloadSha256}`);
|
|
794
|
-
if (targetValues.length) console.error(`Targets: ${targetValues.join(", ")}`);
|
|
795
|
-
if (expectedBatchCount !== null) console.error(`Batch count: ${expectedBatchCount}`);
|
|
796
|
-
console.error("Create a local .md/.yml/.json approval artifact that lists the exact operation, payload summary, and every target.");
|
|
797
|
-
console.error("Show that artifact to the user and ask for explicit approval.");
|
|
798
|
-
console.error("Then rerun with --confirm-write --approval-artifact <path>.");
|
|
799
|
-
process.exit(1);
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
const artifactPath = resolveWriteApprovalArtifactPath(args);
|
|
803
|
-
if (!artifactPath) {
|
|
804
|
-
console.error("Missing --approval-artifact <path> for approved Myte write.");
|
|
805
|
-
console.error(`Payload SHA256: ${payloadSha256}`);
|
|
806
|
-
console.error("The artifact must be a local .md/.yml/.json file shown to and explicitly approved by the user.");
|
|
807
|
-
process.exit(1);
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
return {
|
|
811
|
-
approved: true,
|
|
812
|
-
source: "explicit_user_approval",
|
|
813
|
-
artifact_path: artifactPath,
|
|
814
|
-
artifact_kind: inferApprovalArtifactKind(artifactPath, artifactKind),
|
|
815
|
-
payload_sha256: payloadSha256,
|
|
816
|
-
targets: targetValues,
|
|
817
|
-
batch_count: expectedBatchCount,
|
|
818
|
-
};
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
function writeApprovalHeaders(writeApproval) {
|
|
822
|
-
if (!writeApproval) return {};
|
|
823
|
-
const headers = {
|
|
824
|
-
"X-Myte-Write-Approval": "explicit_user_approval",
|
|
825
|
-
"X-Myte-Approval-Artifact": String(writeApproval.artifact_path || ""),
|
|
826
|
-
"X-Myte-Approval-Artifact-Kind": String(writeApproval.artifact_kind || ""),
|
|
827
|
-
"X-Myte-Approval-Payload-SHA256": String(writeApproval.payload_sha256 || ""),
|
|
828
|
-
};
|
|
829
|
-
if (writeApproval.batch_count !== null && writeApproval.batch_count !== undefined) {
|
|
830
|
-
headers["X-Myte-Approval-Batch-Count"] = String(writeApproval.batch_count);
|
|
831
|
-
}
|
|
832
|
-
if (Array.isArray(writeApproval.targets) && writeApproval.targets.length) {
|
|
833
|
-
headers["X-Myte-Approval-Targets"] = writeApproval.targets.join(",");
|
|
834
|
-
}
|
|
835
|
-
return headers;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
function formatProjectApiErrorMessage(body, fallback) {
|
|
839
|
-
const message = body?.message || fallback;
|
|
840
|
-
const data = body?.data || {};
|
|
841
|
-
const code = String(data?.code || "");
|
|
842
|
-
if (!code.startsWith("myte_write_approval")) {
|
|
843
|
-
return message;
|
|
844
|
-
}
|
|
845
|
-
const lines = [
|
|
846
|
-
message,
|
|
847
|
-
`Approval error: ${code}`,
|
|
848
|
-
];
|
|
849
|
-
if (data.operation) lines.push(`Operation: ${data.operation}`);
|
|
850
|
-
if (data.payload_sha256) lines.push(`Payload SHA256: ${data.payload_sha256}`);
|
|
851
|
-
if (Array.isArray(data.targets) && data.targets.length) lines.push(`Targets: ${data.targets.join(", ")}`);
|
|
852
|
-
if (data.batch_count !== undefined && data.batch_count !== null) lines.push(`Batch count: ${data.batch_count}`);
|
|
853
|
-
if (Array.isArray(data.required_agent_steps) && data.required_agent_steps.length) {
|
|
854
|
-
lines.push("Required agent steps:");
|
|
855
|
-
for (const step of data.required_agent_steps) {
|
|
856
|
-
lines.push(`- ${step}`);
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
return lines.join("\n");
|
|
860
|
-
}
|
|
861
|
-
|
|
862
696
|
function summarizeDiffDiagnosticsForContext(diagnostics) {
|
|
863
697
|
if (!diagnostics) return null;
|
|
864
698
|
const repos = Array.isArray(diagnostics.repo_summaries)
|
|
@@ -1922,7 +1756,7 @@ async function fetchFeedbackHistory({ apiBase, key, timeoutMs, feedbackId }) {
|
|
|
1922
1756
|
return body.data || {};
|
|
1923
1757
|
}
|
|
1924
1758
|
|
|
1925
|
-
async function postFeedbackRefinement({ apiBase, key, timeoutMs, feedbackId, mode, payload, idempotencyKey, clientSessionId
|
|
1759
|
+
async function postFeedbackRefinement({ apiBase, key, timeoutMs, feedbackId, mode, payload, idempotencyKey, clientSessionId }) {
|
|
1926
1760
|
const fetchFn = await getFetch();
|
|
1927
1761
|
const action = String(mode || "").trim();
|
|
1928
1762
|
const url = `${apiBase}/project-assistant/feedback/${encodeURIComponent(String(feedbackId || ""))}/refinement/${action}`;
|
|
@@ -1930,7 +1764,6 @@ async function postFeedbackRefinement({ apiBase, key, timeoutMs, feedbackId, mod
|
|
|
1930
1764
|
"Content-Type": "application/json",
|
|
1931
1765
|
Authorization: `Bearer ${key}`,
|
|
1932
1766
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
1933
|
-
...writeApprovalHeaders(writeApproval),
|
|
1934
1767
|
};
|
|
1935
1768
|
if (idempotencyKey) {
|
|
1936
1769
|
headers["X-Idempotency-Key"] = String(idempotencyKey).trim();
|
|
@@ -1947,7 +1780,7 @@ async function postFeedbackRefinement({ apiBase, key, timeoutMs, feedbackId, mod
|
|
|
1947
1780
|
);
|
|
1948
1781
|
|
|
1949
1782
|
if (!resp.ok || body.status !== "success") {
|
|
1950
|
-
const msg =
|
|
1783
|
+
const msg = body?.message || `Feedback refinement ${action} failed (${resp.status})`;
|
|
1951
1784
|
const err = new Error(msg);
|
|
1952
1785
|
err.status = resp.status;
|
|
1953
1786
|
err.data = body?.data;
|
|
@@ -2026,7 +1859,7 @@ async function fetchFeedbackEvents({ apiBase, key, timeoutMs, feedbackId, limit
|
|
|
2026
1859
|
return body.data || {};
|
|
2027
1860
|
}
|
|
2028
1861
|
|
|
2029
|
-
async function postFeedbackReviewSubmission({ apiBase, key, timeoutMs, feedbackId, payload, idempotencyKey, clientSessionId
|
|
1862
|
+
async function postFeedbackReviewSubmission({ apiBase, key, timeoutMs, feedbackId, payload, idempotencyKey, clientSessionId }) {
|
|
2030
1863
|
const fetchFn = await getFetch();
|
|
2031
1864
|
const url = `${apiBase}/project-assistant/feedback/${encodeURIComponent(String(feedbackId || ""))}/refinement/requests`;
|
|
2032
1865
|
const { resp, body } = await fetchJsonWithTimeout(
|
|
@@ -2039,7 +1872,6 @@ async function postFeedbackReviewSubmission({ apiBase, key, timeoutMs, feedbackI
|
|
|
2039
1872
|
Authorization: `Bearer ${key}`,
|
|
2040
1873
|
"X-Idempotency-Key": String(idempotencyKey || "").trim(),
|
|
2041
1874
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
2042
|
-
...writeApprovalHeaders(writeApproval),
|
|
2043
1875
|
},
|
|
2044
1876
|
body: JSON.stringify(payload || {}),
|
|
2045
1877
|
},
|
|
@@ -2047,7 +1879,7 @@ async function postFeedbackReviewSubmission({ apiBase, key, timeoutMs, feedbackI
|
|
|
2047
1879
|
);
|
|
2048
1880
|
|
|
2049
1881
|
if (!resp.ok || body.status !== "success") {
|
|
2050
|
-
const msg =
|
|
1882
|
+
const msg = body?.message || `Feedback review submission failed (${resp.status})`;
|
|
2051
1883
|
const err = new Error(msg);
|
|
2052
1884
|
err.status = resp.status;
|
|
2053
1885
|
err.data = body?.data;
|
|
@@ -2056,7 +1888,7 @@ async function postFeedbackReviewSubmission({ apiBase, key, timeoutMs, feedbackI
|
|
|
2056
1888
|
return body.data || {};
|
|
2057
1889
|
}
|
|
2058
1890
|
|
|
2059
|
-
async function postFeedbackReviewRequestMutation({ apiBase, key, timeoutMs, requestId, endpointAction, payload, idempotencyKey, clientSessionId
|
|
1891
|
+
async function postFeedbackReviewRequestMutation({ apiBase, key, timeoutMs, requestId, endpointAction, payload, idempotencyKey, clientSessionId }) {
|
|
2060
1892
|
const fetchFn = await getFetch();
|
|
2061
1893
|
const url = `${apiBase}/project-assistant/feedback-review-requests/${encodeURIComponent(String(requestId || ""))}/${endpointAction}`;
|
|
2062
1894
|
const { resp, body } = await fetchJsonWithTimeout(
|
|
@@ -2069,7 +1901,6 @@ async function postFeedbackReviewRequestMutation({ apiBase, key, timeoutMs, requ
|
|
|
2069
1901
|
Authorization: `Bearer ${key}`,
|
|
2070
1902
|
"X-Idempotency-Key": String(idempotencyKey || "").trim(),
|
|
2071
1903
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
2072
|
-
...writeApprovalHeaders(writeApproval),
|
|
2073
1904
|
},
|
|
2074
1905
|
body: JSON.stringify(payload || {}),
|
|
2075
1906
|
},
|
|
@@ -2077,7 +1908,7 @@ async function postFeedbackReviewRequestMutation({ apiBase, key, timeoutMs, requ
|
|
|
2077
1908
|
);
|
|
2078
1909
|
|
|
2079
1910
|
if (!resp.ok || body.status !== "success") {
|
|
2080
|
-
const msg =
|
|
1911
|
+
const msg = body?.message || `Feedback review ${endpointAction} failed (${resp.status})`;
|
|
2081
1912
|
const err = new Error(msg);
|
|
2082
1913
|
err.status = resp.status;
|
|
2083
1914
|
err.data = body?.data;
|
|
@@ -2086,7 +1917,7 @@ async function postFeedbackReviewRequestMutation({ apiBase, key, timeoutMs, requ
|
|
|
2086
1917
|
return body.data || {};
|
|
2087
1918
|
}
|
|
2088
1919
|
|
|
2089
|
-
async function postFeedbackBatchReviewMutation({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId
|
|
1920
|
+
async function postFeedbackBatchReviewMutation({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId }) {
|
|
2090
1921
|
const fetchFn = await getFetch();
|
|
2091
1922
|
const url = `${apiBase}/project-assistant/feedback-review-requests/batch-review`;
|
|
2092
1923
|
const { resp, body } = await fetchJsonWithTimeout(
|
|
@@ -2099,7 +1930,6 @@ async function postFeedbackBatchReviewMutation({ apiBase, key, timeoutMs, payloa
|
|
|
2099
1930
|
Authorization: `Bearer ${key}`,
|
|
2100
1931
|
"X-Idempotency-Key": String(idempotencyKey || "").trim(),
|
|
2101
1932
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
2102
|
-
...writeApprovalHeaders(writeApproval),
|
|
2103
1933
|
},
|
|
2104
1934
|
body: JSON.stringify(payload || {}),
|
|
2105
1935
|
},
|
|
@@ -2107,7 +1937,7 @@ async function postFeedbackBatchReviewMutation({ apiBase, key, timeoutMs, payloa
|
|
|
2107
1937
|
);
|
|
2108
1938
|
|
|
2109
1939
|
if (!resp.ok || body.status !== "success") {
|
|
2110
|
-
const msg =
|
|
1940
|
+
const msg = body?.message || `Feedback batch review failed (${resp.status})`;
|
|
2111
1941
|
const err = new Error(msg);
|
|
2112
1942
|
err.status = resp.status;
|
|
2113
1943
|
err.data = body?.data;
|
|
@@ -2116,7 +1946,7 @@ async function postFeedbackBatchReviewMutation({ apiBase, key, timeoutMs, payloa
|
|
|
2116
1946
|
return body.data || {};
|
|
2117
1947
|
}
|
|
2118
1948
|
|
|
2119
|
-
async function postFeedbackBoardMutation({ apiBase, key, timeoutMs, feedbackId, endpoint, payload, idempotencyKey, clientSessionId
|
|
1949
|
+
async function postFeedbackBoardMutation({ apiBase, key, timeoutMs, feedbackId, endpoint, payload, idempotencyKey, clientSessionId }) {
|
|
2120
1950
|
const fetchFn = await getFetch();
|
|
2121
1951
|
const url = `${apiBase}/project-assistant/feedback/${encodeURIComponent(String(feedbackId || ""))}/${endpoint}`;
|
|
2122
1952
|
const { resp, body } = await fetchJsonWithTimeout(
|
|
@@ -2129,7 +1959,6 @@ async function postFeedbackBoardMutation({ apiBase, key, timeoutMs, feedbackId,
|
|
|
2129
1959
|
Authorization: `Bearer ${key}`,
|
|
2130
1960
|
"X-Idempotency-Key": String(idempotencyKey || "").trim(),
|
|
2131
1961
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
2132
|
-
...writeApprovalHeaders(writeApproval),
|
|
2133
1962
|
},
|
|
2134
1963
|
body: JSON.stringify(payload || {}),
|
|
2135
1964
|
},
|
|
@@ -2137,7 +1966,7 @@ async function postFeedbackBoardMutation({ apiBase, key, timeoutMs, feedbackId,
|
|
|
2137
1966
|
);
|
|
2138
1967
|
|
|
2139
1968
|
if (!resp.ok || body.status !== "success") {
|
|
2140
|
-
const msg =
|
|
1969
|
+
const msg = body?.message || `Feedback board mutation failed (${resp.status})`;
|
|
2141
1970
|
const err = new Error(msg);
|
|
2142
1971
|
err.status = resp.status;
|
|
2143
1972
|
err.data = body?.data;
|
|
@@ -2146,7 +1975,7 @@ async function postFeedbackBoardMutation({ apiBase, key, timeoutMs, feedbackId,
|
|
|
2146
1975
|
return body.data || {};
|
|
2147
1976
|
}
|
|
2148
1977
|
|
|
2149
|
-
async function postFeedbackBatchBoardMutation({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId
|
|
1978
|
+
async function postFeedbackBatchBoardMutation({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId }) {
|
|
2150
1979
|
const fetchFn = await getFetch();
|
|
2151
1980
|
const url = `${apiBase}/project-assistant/feedback/batch-board-move`;
|
|
2152
1981
|
const { resp, body } = await fetchJsonWithTimeout(
|
|
@@ -2159,7 +1988,6 @@ async function postFeedbackBatchBoardMutation({ apiBase, key, timeoutMs, payload
|
|
|
2159
1988
|
Authorization: `Bearer ${key}`,
|
|
2160
1989
|
"X-Idempotency-Key": String(idempotencyKey || "").trim(),
|
|
2161
1990
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
2162
|
-
...writeApprovalHeaders(writeApproval),
|
|
2163
1991
|
},
|
|
2164
1992
|
body: JSON.stringify(payload || {}),
|
|
2165
1993
|
},
|
|
@@ -2167,7 +1995,7 @@ async function postFeedbackBatchBoardMutation({ apiBase, key, timeoutMs, payload
|
|
|
2167
1995
|
);
|
|
2168
1996
|
|
|
2169
1997
|
if (!resp.ok || body.status !== "success") {
|
|
2170
|
-
const msg =
|
|
1998
|
+
const msg = body?.message || `Feedback batch board mutation failed (${resp.status})`;
|
|
2171
1999
|
const err = new Error(msg);
|
|
2172
2000
|
err.status = resp.status;
|
|
2173
2001
|
err.data = body?.data;
|
|
@@ -2176,7 +2004,7 @@ async function postFeedbackBatchBoardMutation({ apiBase, key, timeoutMs, payload
|
|
|
2176
2004
|
return body.data || {};
|
|
2177
2005
|
}
|
|
2178
2006
|
|
|
2179
|
-
async function postFeedbackComment({ apiBase, key, timeoutMs, feedbackId, payload, idempotencyKey, clientSessionId
|
|
2007
|
+
async function postFeedbackComment({ apiBase, key, timeoutMs, feedbackId, payload, idempotencyKey, clientSessionId }) {
|
|
2180
2008
|
const fetchFn = await getFetch();
|
|
2181
2009
|
const url = `${apiBase}/project-assistant/feedback/${encodeURIComponent(String(feedbackId || ""))}/comments`;
|
|
2182
2010
|
const { resp, body } = await fetchJsonWithTimeout(
|
|
@@ -2189,7 +2017,6 @@ async function postFeedbackComment({ apiBase, key, timeoutMs, feedbackId, payloa
|
|
|
2189
2017
|
Authorization: `Bearer ${key}`,
|
|
2190
2018
|
"X-Idempotency-Key": String(idempotencyKey || "").trim(),
|
|
2191
2019
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
2192
|
-
...writeApprovalHeaders(writeApproval),
|
|
2193
2020
|
},
|
|
2194
2021
|
body: JSON.stringify(payload || {}),
|
|
2195
2022
|
},
|
|
@@ -2197,7 +2024,7 @@ async function postFeedbackComment({ apiBase, key, timeoutMs, feedbackId, payloa
|
|
|
2197
2024
|
);
|
|
2198
2025
|
|
|
2199
2026
|
if (!resp.ok || body.status !== "success") {
|
|
2200
|
-
const msg =
|
|
2027
|
+
const msg = body?.message || `Feedback comment failed (${resp.status})`;
|
|
2201
2028
|
const err = new Error(msg);
|
|
2202
2029
|
err.status = resp.status;
|
|
2203
2030
|
err.data = body?.data;
|
|
@@ -2303,7 +2130,7 @@ function resolveProjectMutationIdempotencyKey({ args, operation, payload }) {
|
|
|
2303
2130
|
return createHash("sha256").update(fingerprint).digest("hex");
|
|
2304
2131
|
}
|
|
2305
2132
|
|
|
2306
|
-
async function postSuggestionsMutation({ apiBase, key, timeoutMs, endpoint, payload, idempotencyKey, clientSessionId
|
|
2133
|
+
async function postSuggestionsMutation({ apiBase, key, timeoutMs, endpoint, payload, idempotencyKey, clientSessionId }) {
|
|
2307
2134
|
const fetchFn = await getFetch();
|
|
2308
2135
|
const url = `${apiBase}${endpoint}`;
|
|
2309
2136
|
const { resp, body } = await fetchJsonWithTimeout(
|
|
@@ -2316,7 +2143,6 @@ async function postSuggestionsMutation({ apiBase, key, timeoutMs, endpoint, payl
|
|
|
2316
2143
|
Authorization: `Bearer ${key}`,
|
|
2317
2144
|
"X-Idempotency-Key": String(idempotencyKey || "").trim(),
|
|
2318
2145
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
2319
|
-
...writeApprovalHeaders(writeApproval),
|
|
2320
2146
|
},
|
|
2321
2147
|
body: JSON.stringify(payload),
|
|
2322
2148
|
},
|
|
@@ -2324,16 +2150,15 @@ async function postSuggestionsMutation({ apiBase, key, timeoutMs, endpoint, payl
|
|
|
2324
2150
|
);
|
|
2325
2151
|
|
|
2326
2152
|
if (!resp.ok || body.status !== "success") {
|
|
2327
|
-
const msg =
|
|
2153
|
+
const msg = body?.message || `Mission suggestions request failed (${resp.status})`;
|
|
2328
2154
|
const err = new Error(msg);
|
|
2329
2155
|
err.status = resp.status;
|
|
2330
|
-
err.data = body?.data;
|
|
2331
2156
|
throw err;
|
|
2332
2157
|
}
|
|
2333
2158
|
return body.data || {};
|
|
2334
2159
|
}
|
|
2335
2160
|
|
|
2336
|
-
async function createRunQaqcBatch({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId
|
|
2161
|
+
async function createRunQaqcBatch({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId }) {
|
|
2337
2162
|
const fetchFn = await getFetch();
|
|
2338
2163
|
const url = `${apiBase}/project-assistant/run-qaqc`;
|
|
2339
2164
|
const { resp, body } = await fetchJsonWithTimeout(
|
|
@@ -2346,7 +2171,6 @@ async function createRunQaqcBatch({ apiBase, key, timeoutMs, payload, idempotenc
|
|
|
2346
2171
|
Authorization: `Bearer ${key}`,
|
|
2347
2172
|
"X-Idempotency-Key": String(idempotencyKey || "").trim(),
|
|
2348
2173
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
2349
|
-
...writeApprovalHeaders(writeApproval),
|
|
2350
2174
|
},
|
|
2351
2175
|
body: JSON.stringify(payload),
|
|
2352
2176
|
},
|
|
@@ -2354,16 +2178,15 @@ async function createRunQaqcBatch({ apiBase, key, timeoutMs, payload, idempotenc
|
|
|
2354
2178
|
);
|
|
2355
2179
|
|
|
2356
2180
|
if (!resp.ok || body.status !== "success") {
|
|
2357
|
-
const msg =
|
|
2181
|
+
const msg = body?.message || `Run QAQC request failed (${resp.status})`;
|
|
2358
2182
|
const err = new Error(msg);
|
|
2359
2183
|
err.status = resp.status;
|
|
2360
|
-
err.data = body?.data;
|
|
2361
2184
|
throw err;
|
|
2362
2185
|
}
|
|
2363
2186
|
return body.data || {};
|
|
2364
2187
|
}
|
|
2365
2188
|
|
|
2366
|
-
async function createMissionStatusUpdate({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId
|
|
2189
|
+
async function createMissionStatusUpdate({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId }) {
|
|
2367
2190
|
const fetchFn = await getFetch();
|
|
2368
2191
|
const url = `${apiBase}/project-assistant/mission-status-update`;
|
|
2369
2192
|
const { resp, body } = await fetchJsonWithTimeout(
|
|
@@ -2376,7 +2199,6 @@ async function createMissionStatusUpdate({ apiBase, key, timeoutMs, payload, ide
|
|
|
2376
2199
|
Authorization: `Bearer ${key}`,
|
|
2377
2200
|
"X-Idempotency-Key": String(idempotencyKey || "").trim(),
|
|
2378
2201
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
2379
|
-
...writeApprovalHeaders(writeApproval),
|
|
2380
2202
|
},
|
|
2381
2203
|
body: JSON.stringify(payload),
|
|
2382
2204
|
},
|
|
@@ -2384,16 +2206,15 @@ async function createMissionStatusUpdate({ apiBase, key, timeoutMs, payload, ide
|
|
|
2384
2206
|
);
|
|
2385
2207
|
|
|
2386
2208
|
if (!resp.ok || body.status !== "success") {
|
|
2387
|
-
const msg =
|
|
2209
|
+
const msg = body?.message || `Mission status update request failed (${resp.status})`;
|
|
2388
2210
|
const err = new Error(msg);
|
|
2389
2211
|
err.status = resp.status;
|
|
2390
|
-
err.data = body?.data;
|
|
2391
2212
|
throw err;
|
|
2392
2213
|
}
|
|
2393
2214
|
return body.data || {};
|
|
2394
2215
|
}
|
|
2395
2216
|
|
|
2396
|
-
async function createMissionArchiveUpdate({ apiBase, key, timeoutMs, endpoint, payload, idempotencyKey, clientSessionId
|
|
2217
|
+
async function createMissionArchiveUpdate({ apiBase, key, timeoutMs, endpoint, payload, idempotencyKey, clientSessionId }) {
|
|
2397
2218
|
const fetchFn = await getFetch();
|
|
2398
2219
|
const url = `${apiBase}${endpoint}`;
|
|
2399
2220
|
const { resp, body } = await fetchJsonWithTimeout(
|
|
@@ -2406,7 +2227,6 @@ async function createMissionArchiveUpdate({ apiBase, key, timeoutMs, endpoint, p
|
|
|
2406
2227
|
Authorization: `Bearer ${key}`,
|
|
2407
2228
|
"X-Idempotency-Key": String(idempotencyKey || "").trim(),
|
|
2408
2229
|
...(String(clientSessionId || "").trim() ? { "X-Client-Session-Id": String(clientSessionId).trim() } : {}),
|
|
2409
|
-
...writeApprovalHeaders(writeApproval),
|
|
2410
2230
|
},
|
|
2411
2231
|
body: JSON.stringify(payload),
|
|
2412
2232
|
},
|
|
@@ -2414,10 +2234,9 @@ async function createMissionArchiveUpdate({ apiBase, key, timeoutMs, endpoint, p
|
|
|
2414
2234
|
);
|
|
2415
2235
|
|
|
2416
2236
|
if (!resp.ok || body.status !== "success") {
|
|
2417
|
-
const msg =
|
|
2237
|
+
const msg = body?.message || `Mission archive request failed (${resp.status})`;
|
|
2418
2238
|
const err = new Error(msg);
|
|
2419
2239
|
err.status = resp.status;
|
|
2420
|
-
err.data = body?.data;
|
|
2421
2240
|
throw err;
|
|
2422
2241
|
}
|
|
2423
2242
|
return body.data || {};
|
|
@@ -2530,15 +2349,20 @@ async function runRunQaqc(args) {
|
|
|
2530
2349
|
process.exit(1);
|
|
2531
2350
|
}
|
|
2532
2351
|
|
|
2533
|
-
|
|
2534
|
-
mission_ids: missionIds,
|
|
2535
|
-
force: Boolean(args.force),
|
|
2536
|
-
};
|
|
2537
|
-
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
2538
|
-
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2352
|
+
let payload = {
|
|
2353
|
+
mission_ids: missionIds,
|
|
2354
|
+
force: Boolean(args.force),
|
|
2355
|
+
};
|
|
2356
|
+
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
2357
|
+
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
2358
|
+
payload = withWriteApproval(args, payload, {
|
|
2359
|
+
artifactKind: "yaml",
|
|
2360
|
+
targets: missionIds,
|
|
2361
|
+
batchCount: missionIds.length > 1 ? missionIds.length : null,
|
|
2362
|
+
});
|
|
2363
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
2364
|
+
args,
|
|
2365
|
+
operation: "run-qaqc",
|
|
2542
2366
|
payload,
|
|
2543
2367
|
});
|
|
2544
2368
|
|
|
@@ -2551,12 +2375,6 @@ async function runRunQaqc(args) {
|
|
|
2551
2375
|
const apiBase = resolveApiBase(args);
|
|
2552
2376
|
const shouldWait = Boolean(args.wait || args.sync);
|
|
2553
2377
|
const shouldSync = Boolean(args.sync);
|
|
2554
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
2555
|
-
operation: "run-qaqc",
|
|
2556
|
-
artifactKind: "yaml",
|
|
2557
|
-
targets: missionIds,
|
|
2558
|
-
batchCount: missionIds.length,
|
|
2559
|
-
});
|
|
2560
2378
|
|
|
2561
2379
|
let data;
|
|
2562
2380
|
try {
|
|
@@ -2567,7 +2385,6 @@ async function runRunQaqc(args) {
|
|
|
2567
2385
|
payload,
|
|
2568
2386
|
idempotencyKey,
|
|
2569
2387
|
clientSessionId,
|
|
2570
|
-
writeApproval,
|
|
2571
2388
|
});
|
|
2572
2389
|
} catch (err) {
|
|
2573
2390
|
if (err?.name === "AbortError") {
|
|
@@ -2692,15 +2509,20 @@ async function runMissionStatus(args) {
|
|
|
2692
2509
|
process.exit(1);
|
|
2693
2510
|
}
|
|
2694
2511
|
|
|
2695
|
-
|
|
2696
|
-
mission_ids: missionIds,
|
|
2697
|
-
new_status: newStatus,
|
|
2698
|
-
};
|
|
2699
|
-
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
2700
|
-
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2512
|
+
let payload = {
|
|
2513
|
+
mission_ids: missionIds,
|
|
2514
|
+
new_status: newStatus,
|
|
2515
|
+
};
|
|
2516
|
+
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
2517
|
+
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
2518
|
+
payload = withWriteApproval(args, payload, {
|
|
2519
|
+
artifactKind: "yaml",
|
|
2520
|
+
targets: missionIds,
|
|
2521
|
+
batchCount: missionIds.length > 1 ? missionIds.length : null,
|
|
2522
|
+
});
|
|
2523
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
2524
|
+
args,
|
|
2525
|
+
operation: "mission-status-update",
|
|
2704
2526
|
payload,
|
|
2705
2527
|
});
|
|
2706
2528
|
|
|
@@ -2711,12 +2533,6 @@ async function runMissionStatus(args) {
|
|
|
2711
2533
|
|
|
2712
2534
|
const timeoutMs = resolveTimeoutMs(args);
|
|
2713
2535
|
const apiBase = resolveApiBase(args);
|
|
2714
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
2715
|
-
operation: "mission-status-update",
|
|
2716
|
-
artifactKind: "yaml",
|
|
2717
|
-
targets: missionIds,
|
|
2718
|
-
batchCount: missionIds.length,
|
|
2719
|
-
});
|
|
2720
2536
|
|
|
2721
2537
|
let data;
|
|
2722
2538
|
try {
|
|
@@ -2727,7 +2543,6 @@ async function runMissionStatus(args) {
|
|
|
2727
2543
|
payload,
|
|
2728
2544
|
idempotencyKey,
|
|
2729
2545
|
clientSessionId,
|
|
2730
|
-
writeApproval,
|
|
2731
2546
|
});
|
|
2732
2547
|
} catch (err) {
|
|
2733
2548
|
if (err?.name === "AbortError") {
|
|
@@ -2802,13 +2617,18 @@ async function runMissionArchiveCommand(args) {
|
|
|
2802
2617
|
process.exit(1);
|
|
2803
2618
|
}
|
|
2804
2619
|
|
|
2805
|
-
|
|
2806
|
-
mission_ids: missionIds,
|
|
2807
|
-
};
|
|
2808
|
-
const reason = firstNonEmptyString(args.reason);
|
|
2809
|
-
if (reason) payload.reason = reason;
|
|
2810
|
-
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
2811
|
-
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
2620
|
+
let payload = {
|
|
2621
|
+
mission_ids: missionIds,
|
|
2622
|
+
};
|
|
2623
|
+
const reason = firstNonEmptyString(args.reason);
|
|
2624
|
+
if (reason) payload.reason = reason;
|
|
2625
|
+
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
2626
|
+
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
2627
|
+
payload = withWriteApproval(args, payload, {
|
|
2628
|
+
artifactKind: "yaml",
|
|
2629
|
+
targets: missionIds,
|
|
2630
|
+
batchCount: missionIds.length > 1 ? missionIds.length : null,
|
|
2631
|
+
});
|
|
2812
2632
|
|
|
2813
2633
|
const operation = "mission-archive";
|
|
2814
2634
|
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
@@ -2825,12 +2645,6 @@ async function runMissionArchiveCommand(args) {
|
|
|
2825
2645
|
const timeoutMs = resolveTimeoutMs(args);
|
|
2826
2646
|
const apiBase = resolveApiBase(args);
|
|
2827
2647
|
const endpoint = "/project-assistant/mission-archive";
|
|
2828
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
2829
|
-
operation: "mission-archive",
|
|
2830
|
-
artifactKind: "yaml",
|
|
2831
|
-
targets: missionIds,
|
|
2832
|
-
batchCount: missionIds.length,
|
|
2833
|
-
});
|
|
2834
2648
|
|
|
2835
2649
|
let data;
|
|
2836
2650
|
try {
|
|
@@ -2842,7 +2656,6 @@ async function runMissionArchiveCommand(args) {
|
|
|
2842
2656
|
payload,
|
|
2843
2657
|
idempotencyKey,
|
|
2844
2658
|
clientSessionId,
|
|
2845
|
-
writeApproval,
|
|
2846
2659
|
});
|
|
2847
2660
|
} catch (err) {
|
|
2848
2661
|
if (err?.name === "AbortError") {
|
|
@@ -2924,9 +2737,9 @@ async function runUpdateTeam(args) {
|
|
|
2924
2737
|
process.exit(1);
|
|
2925
2738
|
}
|
|
2926
2739
|
|
|
2927
|
-
|
|
2928
|
-
content: await resolveTeamUpdateContent(args),
|
|
2929
|
-
};
|
|
2740
|
+
let payload = {
|
|
2741
|
+
content: await resolveTeamUpdateContent(args),
|
|
2742
|
+
};
|
|
2930
2743
|
|
|
2931
2744
|
if (args["print-context"] || args.printContext || args["dry-run"] || args.dryRun) {
|
|
2932
2745
|
console.log(JSON.stringify(payload, null, 2));
|
|
@@ -2934,18 +2747,18 @@ async function runUpdateTeam(args) {
|
|
|
2934
2747
|
}
|
|
2935
2748
|
|
|
2936
2749
|
const timeoutMs = resolveTimeoutMs(args);
|
|
2937
|
-
const apiBase = resolveApiBase(args);
|
|
2938
|
-
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
2939
|
-
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
2940
|
-
|
|
2750
|
+
const apiBase = resolveApiBase(args);
|
|
2751
|
+
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
2752
|
+
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
2753
|
+
payload = withWriteApproval(args, payload, {
|
|
2754
|
+
artifactKind: "markdown",
|
|
2755
|
+
targets: ["project"],
|
|
2756
|
+
});
|
|
2757
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
2941
2758
|
args,
|
|
2942
2759
|
operation: "update_team",
|
|
2943
2760
|
payload,
|
|
2944
2761
|
});
|
|
2945
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
2946
|
-
operation: "update_team",
|
|
2947
|
-
artifactKind: "markdown",
|
|
2948
|
-
});
|
|
2949
2762
|
|
|
2950
2763
|
let data;
|
|
2951
2764
|
try {
|
|
@@ -2957,7 +2770,6 @@ async function runUpdateTeam(args) {
|
|
|
2957
2770
|
endpoint: "/project-assistant/project-comment",
|
|
2958
2771
|
idempotencyKey,
|
|
2959
2772
|
clientSessionId,
|
|
2960
|
-
writeApproval,
|
|
2961
2773
|
});
|
|
2962
2774
|
} catch (err) {
|
|
2963
2775
|
if (err?.name === "AbortError") {
|
|
@@ -2997,10 +2809,10 @@ async function runUpdateOwner(args) {
|
|
|
2997
2809
|
process.exit(1);
|
|
2998
2810
|
}
|
|
2999
2811
|
|
|
3000
|
-
|
|
3001
|
-
subject,
|
|
3002
|
-
body_markdown: await resolveOwnerUpdateBody(args),
|
|
3003
|
-
};
|
|
2812
|
+
let payload = {
|
|
2813
|
+
subject,
|
|
2814
|
+
body_markdown: await resolveOwnerUpdateBody(args),
|
|
2815
|
+
};
|
|
3004
2816
|
|
|
3005
2817
|
if (args["print-context"] || args.printContext || args["dry-run"] || args.dryRun) {
|
|
3006
2818
|
console.log(JSON.stringify(payload, null, 2));
|
|
@@ -3008,18 +2820,18 @@ async function runUpdateOwner(args) {
|
|
|
3008
2820
|
}
|
|
3009
2821
|
|
|
3010
2822
|
const timeoutMs = resolveTimeoutMs(args);
|
|
3011
|
-
const apiBase = resolveApiBase(args);
|
|
3012
|
-
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
3013
|
-
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
3014
|
-
|
|
2823
|
+
const apiBase = resolveApiBase(args);
|
|
2824
|
+
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
2825
|
+
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
2826
|
+
payload = withWriteApproval(args, payload, {
|
|
2827
|
+
artifactKind: "markdown",
|
|
2828
|
+
targets: ["project"],
|
|
2829
|
+
});
|
|
2830
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
3015
2831
|
args,
|
|
3016
2832
|
operation: "update_owner",
|
|
3017
2833
|
payload,
|
|
3018
2834
|
});
|
|
3019
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
3020
|
-
operation: "update_owner",
|
|
3021
|
-
artifactKind: "markdown",
|
|
3022
|
-
});
|
|
3023
2835
|
|
|
3024
2836
|
let data;
|
|
3025
2837
|
try {
|
|
@@ -3031,7 +2843,6 @@ async function runUpdateOwner(args) {
|
|
|
3031
2843
|
endpoint: "/project-assistant/update-owner",
|
|
3032
2844
|
idempotencyKey,
|
|
3033
2845
|
clientSessionId,
|
|
3034
|
-
writeApproval,
|
|
3035
2846
|
});
|
|
3036
2847
|
} catch (err) {
|
|
3037
2848
|
if (err?.name === "AbortError") {
|
|
@@ -3079,11 +2890,11 @@ async function runUpdateClient(args) {
|
|
|
3079
2890
|
process.exit(1);
|
|
3080
2891
|
}
|
|
3081
2892
|
|
|
3082
|
-
|
|
3083
|
-
subject,
|
|
3084
|
-
body_markdown: await resolveClientUpdateBody(args),
|
|
3085
|
-
target_contact_ids: resolveTargetContactIds(args),
|
|
3086
|
-
};
|
|
2893
|
+
let payload = {
|
|
2894
|
+
subject,
|
|
2895
|
+
body_markdown: await resolveClientUpdateBody(args),
|
|
2896
|
+
target_contact_ids: resolveTargetContactIds(args),
|
|
2897
|
+
};
|
|
3087
2898
|
|
|
3088
2899
|
if (args["print-context"] || args.printContext || args["dry-run"] || args.dryRun) {
|
|
3089
2900
|
console.log(JSON.stringify(payload, null, 2));
|
|
@@ -3091,18 +2902,18 @@ async function runUpdateClient(args) {
|
|
|
3091
2902
|
}
|
|
3092
2903
|
|
|
3093
2904
|
const timeoutMs = resolveTimeoutMs(args);
|
|
3094
|
-
const apiBase = resolveApiBase(args);
|
|
3095
|
-
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
3096
|
-
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
3097
|
-
|
|
2905
|
+
const apiBase = resolveApiBase(args);
|
|
2906
|
+
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
2907
|
+
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
2908
|
+
payload = withWriteApproval(args, payload, {
|
|
2909
|
+
artifactKind: "markdown",
|
|
2910
|
+
targets: ["project"],
|
|
2911
|
+
});
|
|
2912
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
3098
2913
|
args,
|
|
3099
2914
|
operation: "update_client",
|
|
3100
2915
|
payload,
|
|
3101
2916
|
});
|
|
3102
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
3103
|
-
operation: "update_client",
|
|
3104
|
-
artifactKind: "markdown",
|
|
3105
|
-
});
|
|
3106
2917
|
|
|
3107
2918
|
let data;
|
|
3108
2919
|
try {
|
|
@@ -3114,7 +2925,6 @@ async function runUpdateClient(args) {
|
|
|
3114
2925
|
endpoint: "/project-assistant/client-update-drafts",
|
|
3115
2926
|
idempotencyKey,
|
|
3116
2927
|
clientSessionId,
|
|
3117
|
-
writeApproval,
|
|
3118
2928
|
});
|
|
3119
2929
|
} catch (err) {
|
|
3120
2930
|
if (err?.name === "AbortError") {
|
|
@@ -3210,7 +3020,7 @@ function stringifyYaml(value) {
|
|
|
3210
3020
|
function stableJsonStringify(value) {
|
|
3211
3021
|
if (Array.isArray(value)) {
|
|
3212
3022
|
return `[${value.map((item) => stableJsonStringify(item)).join(",")}]`;
|
|
3213
|
-
}
|
|
3023
|
+
}
|
|
3214
3024
|
if (value && typeof value === "object") {
|
|
3215
3025
|
const entries = Object.keys(value)
|
|
3216
3026
|
.sort()
|
|
@@ -3220,38 +3030,125 @@ function stableJsonStringify(value) {
|
|
|
3220
3030
|
return JSON.stringify(value);
|
|
3221
3031
|
}
|
|
3222
3032
|
|
|
3223
|
-
function
|
|
3033
|
+
function pythonJsonStringify(value) {
|
|
3034
|
+
if (Array.isArray(value)) {
|
|
3035
|
+
return `[${value.map((item) => pythonJsonStringify(item)).join(", ")}]`;
|
|
3036
|
+
}
|
|
3037
|
+
if (value && typeof value === "object") {
|
|
3038
|
+
const entries = Object.keys(value)
|
|
3039
|
+
.filter((key) => value[key] !== undefined)
|
|
3040
|
+
.sort()
|
|
3041
|
+
.map((key) => `${jsonStringEnsureAscii(key)}: ${pythonJsonStringify(value[key])}`);
|
|
3042
|
+
return `{${entries.join(", ")}}`;
|
|
3043
|
+
}
|
|
3044
|
+
if (typeof value === "string") return jsonStringEnsureAscii(value);
|
|
3045
|
+
if (value === undefined) return "null";
|
|
3046
|
+
return JSON.stringify(value);
|
|
3047
|
+
}
|
|
3048
|
+
|
|
3049
|
+
function jsonStringEnsureAscii(value) {
|
|
3224
3050
|
return JSON.stringify(String(value)).replace(/[^\x00-\x7F]/g, (char) => {
|
|
3225
3051
|
const code = char.charCodeAt(0);
|
|
3226
3052
|
return `\\u${code.toString(16).padStart(4, "0")}`;
|
|
3227
3053
|
});
|
|
3228
3054
|
}
|
|
3229
3055
|
|
|
3230
|
-
function
|
|
3056
|
+
function canonicalizeWritePayload(value) {
|
|
3231
3057
|
if (Array.isArray(value)) {
|
|
3232
|
-
return
|
|
3058
|
+
return value.map((item) => canonicalizeWritePayload(item));
|
|
3233
3059
|
}
|
|
3234
3060
|
if (value && typeof value === "object") {
|
|
3235
|
-
const
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3061
|
+
const next = {};
|
|
3062
|
+
for (const key of Object.keys(value)) {
|
|
3063
|
+
if (key === "write_approval" || key === "client_session_id") continue;
|
|
3064
|
+
if (value[key] === undefined) continue;
|
|
3065
|
+
next[key] = canonicalizeWritePayload(value[key]);
|
|
3066
|
+
}
|
|
3067
|
+
return next;
|
|
3068
|
+
}
|
|
3069
|
+
return value;
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
function projectWritePayloadHash(payload) {
|
|
3073
|
+
const canonical = canonicalizeWritePayload(payload || {});
|
|
3074
|
+
return createHash("sha256").update(pythonJsonStringify(canonical)).digest("hex");
|
|
3075
|
+
}
|
|
3076
|
+
|
|
3077
|
+
function approvalArtifactKind(artifactPath, fallback = "yaml") {
|
|
3078
|
+
const ext = path.extname(String(artifactPath || "")).toLowerCase();
|
|
3079
|
+
if (ext === ".md" || ext === ".markdown") return "markdown";
|
|
3080
|
+
if (ext === ".json") return "json";
|
|
3081
|
+
if (ext === ".yml" || ext === ".yaml") return "yaml";
|
|
3082
|
+
return fallback || "yaml";
|
|
3083
|
+
}
|
|
3084
|
+
|
|
3085
|
+
function resolveWriteApprovalArtifact(args) {
|
|
3086
|
+
const artifactPath = firstNonEmptyString(
|
|
3087
|
+
args["approval-artifact"],
|
|
3088
|
+
args.approvalArtifact,
|
|
3089
|
+
args.approval_artifact
|
|
3090
|
+
);
|
|
3091
|
+
if (!artifactPath) {
|
|
3092
|
+
console.error("Missing --approval-artifact for confirmed live Myte write.");
|
|
3093
|
+
process.exit(1);
|
|
3094
|
+
}
|
|
3095
|
+
const absPath = path.resolve(String(artifactPath));
|
|
3096
|
+
if (!fs.existsSync(absPath) || !fs.statSync(absPath).isFile()) {
|
|
3097
|
+
console.error(`Approval artifact not found: ${absPath}`);
|
|
3098
|
+
process.exit(1);
|
|
3239
3099
|
}
|
|
3240
|
-
|
|
3241
|
-
if (
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
if (value === Infinity) return "Infinity";
|
|
3245
|
-
if (value === -Infinity) return "-Infinity";
|
|
3246
|
-
return JSON.stringify(value);
|
|
3100
|
+
const ext = path.extname(absPath).toLowerCase();
|
|
3101
|
+
if (![".md", ".markdown", ".yml", ".yaml", ".json"].includes(ext)) {
|
|
3102
|
+
console.error("Approval artifact must be a local .md, .yml, .yaml, or .json file.");
|
|
3103
|
+
process.exit(1);
|
|
3247
3104
|
}
|
|
3248
|
-
return
|
|
3105
|
+
return { displayPath: String(artifactPath), absPath };
|
|
3106
|
+
}
|
|
3107
|
+
|
|
3108
|
+
function approvalTargets(values) {
|
|
3109
|
+
return uniqueNormalizedStrings(Array.isArray(values) ? values : [values]);
|
|
3110
|
+
}
|
|
3111
|
+
|
|
3112
|
+
function withWriteApproval(args, payload, { artifactKind = "yaml", targets = [], batchCount = null } = {}) {
|
|
3113
|
+
const confirmed = Boolean(args["confirm-write"] || args.confirmWrite || args.confirm_write);
|
|
3114
|
+
if (!confirmed) return payload;
|
|
3115
|
+
const { displayPath } = resolveWriteApprovalArtifact(args);
|
|
3116
|
+
const nextPayload = { ...(payload || {}) };
|
|
3117
|
+
const normalizedTargets = approvalTargets(targets);
|
|
3118
|
+
const approval = {
|
|
3119
|
+
approved: true,
|
|
3120
|
+
source: "explicit_user_approval",
|
|
3121
|
+
artifact_path: displayPath,
|
|
3122
|
+
artifact_kind: approvalArtifactKind(displayPath, artifactKind),
|
|
3123
|
+
payload_sha256: projectWritePayloadHash(nextPayload),
|
|
3124
|
+
};
|
|
3125
|
+
if (normalizedTargets.length) approval.targets = normalizedTargets;
|
|
3126
|
+
if (batchCount !== undefined && batchCount !== null) approval.batch_count = Number(batchCount);
|
|
3127
|
+
nextPayload.write_approval = approval;
|
|
3128
|
+
return nextPayload;
|
|
3129
|
+
}
|
|
3130
|
+
|
|
3131
|
+
function suggestionWriteTargets(items) {
|
|
3132
|
+
return (Array.isArray(items) ? items : [])
|
|
3133
|
+
.map((item, index) => {
|
|
3134
|
+
if (!item || typeof item !== "object") return `index:${index}`;
|
|
3135
|
+
const changeType = String(item.change_type || item.action || "suggestion").trim().toLowerCase() || "suggestion";
|
|
3136
|
+
const changeSet = item.change_set && typeof item.change_set === "object" ? item.change_set : item;
|
|
3137
|
+
return firstNonEmptyString(
|
|
3138
|
+
item.suggestion_id,
|
|
3139
|
+
item.mission_id,
|
|
3140
|
+
item.client_ref,
|
|
3141
|
+
changeSet.title ? `${changeType}:${String(changeSet.title).slice(0, 80)}` : "",
|
|
3142
|
+
`index:${index}`
|
|
3143
|
+
);
|
|
3144
|
+
})
|
|
3145
|
+
.filter(Boolean);
|
|
3249
3146
|
}
|
|
3250
3147
|
|
|
3251
3148
|
function parseYaml(text) {
|
|
3252
|
-
const raw = String(text || "").trim();
|
|
3253
|
-
if (!raw) return null;
|
|
3254
|
-
if (raw.startsWith("{") || raw.startsWith("[")) {
|
|
3149
|
+
const raw = String(text || "").trim();
|
|
3150
|
+
if (!raw) return null;
|
|
3151
|
+
if (raw.startsWith("{") || raw.startsWith("[")) {
|
|
3255
3152
|
return JSON.parse(raw);
|
|
3256
3153
|
}
|
|
3257
3154
|
return parseSimpleYaml(raw);
|
|
@@ -4514,7 +4411,7 @@ async function fetchSuggestionsSyncSnapshot({ apiBase, key, timeoutMs, actorScop
|
|
|
4514
4411
|
return body.data || {};
|
|
4515
4412
|
}
|
|
4516
4413
|
|
|
4517
|
-
async function createProjectSuggestions({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId
|
|
4414
|
+
async function createProjectSuggestions({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId }) {
|
|
4518
4415
|
return postSuggestionsMutation({
|
|
4519
4416
|
apiBase,
|
|
4520
4417
|
key,
|
|
@@ -4523,11 +4420,10 @@ async function createProjectSuggestions({ apiBase, key, timeoutMs, payload, idem
|
|
|
4523
4420
|
payload,
|
|
4524
4421
|
idempotencyKey,
|
|
4525
4422
|
clientSessionId,
|
|
4526
|
-
writeApproval,
|
|
4527
4423
|
});
|
|
4528
4424
|
}
|
|
4529
4425
|
|
|
4530
|
-
async function reviseProjectSuggestions({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId
|
|
4426
|
+
async function reviseProjectSuggestions({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId }) {
|
|
4531
4427
|
return postSuggestionsMutation({
|
|
4532
4428
|
apiBase,
|
|
4533
4429
|
key,
|
|
@@ -4536,11 +4432,10 @@ async function reviseProjectSuggestions({ apiBase, key, timeoutMs, payload, idem
|
|
|
4536
4432
|
payload,
|
|
4537
4433
|
idempotencyKey,
|
|
4538
4434
|
clientSessionId,
|
|
4539
|
-
writeApproval,
|
|
4540
4435
|
});
|
|
4541
4436
|
}
|
|
4542
4437
|
|
|
4543
|
-
async function reviewProjectSuggestions({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId
|
|
4438
|
+
async function reviewProjectSuggestions({ apiBase, key, timeoutMs, payload, idempotencyKey, clientSessionId }) {
|
|
4544
4439
|
return postSuggestionsMutation({
|
|
4545
4440
|
apiBase,
|
|
4546
4441
|
key,
|
|
@@ -4549,7 +4444,6 @@ async function reviewProjectSuggestions({ apiBase, key, timeoutMs, payload, idem
|
|
|
4549
4444
|
payload,
|
|
4550
4445
|
idempotencyKey,
|
|
4551
4446
|
clientSessionId,
|
|
4552
|
-
writeApproval,
|
|
4553
4447
|
});
|
|
4554
4448
|
}
|
|
4555
4449
|
|
|
@@ -4658,20 +4552,19 @@ async function runCreatePrd(args) {
|
|
|
4658
4552
|
|
|
4659
4553
|
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
4660
4554
|
|
|
4661
|
-
if (payloads.length === 1) {
|
|
4662
|
-
let data;
|
|
4663
|
-
|
|
4664
|
-
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4555
|
+
if (payloads.length === 1) {
|
|
4556
|
+
let data;
|
|
4557
|
+
let payload = payloads[0];
|
|
4558
|
+
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
4559
|
+
payload = withWriteApproval(args, payload, {
|
|
4560
|
+
artifactKind: "markdown",
|
|
4561
|
+
targets: [firstNonEmptyString(payload.client_ref, payload.title, "create-prd")],
|
|
4562
|
+
});
|
|
4563
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
4564
|
+
args,
|
|
4565
|
+
operation: "create_prd",
|
|
4668
4566
|
payload,
|
|
4669
4567
|
});
|
|
4670
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
4671
|
-
operation: "create_prd",
|
|
4672
|
-
artifactKind: "markdown",
|
|
4673
|
-
targets: prdApprovalTargets(payload),
|
|
4674
|
-
});
|
|
4675
4568
|
try {
|
|
4676
4569
|
data = await postSuggestionsMutation({
|
|
4677
4570
|
apiBase,
|
|
@@ -4681,7 +4574,6 @@ async function runCreatePrd(args) {
|
|
|
4681
4574
|
endpoint: "/project-assistant/create-prd",
|
|
4682
4575
|
idempotencyKey,
|
|
4683
4576
|
clientSessionId,
|
|
4684
|
-
writeApproval,
|
|
4685
4577
|
});
|
|
4686
4578
|
} catch (err) {
|
|
4687
4579
|
if (err?.name === "AbortError") {
|
|
@@ -4723,22 +4615,20 @@ async function runCreatePrd(args) {
|
|
|
4723
4615
|
failed_count: 0,
|
|
4724
4616
|
items: [],
|
|
4725
4617
|
};
|
|
4726
|
-
|
|
4727
|
-
try {
|
|
4728
|
-
|
|
4729
|
-
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4618
|
+
|
|
4619
|
+
try {
|
|
4620
|
+
let payload = { items: payloads };
|
|
4621
|
+
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
4622
|
+
payload = withWriteApproval(args, payload, {
|
|
4623
|
+
artifactKind: "markdown",
|
|
4624
|
+
targets: payloads.map((item, index) => firstNonEmptyString(item.client_ref, item.title, `index:${index}`)),
|
|
4625
|
+
batchCount: payloads.length,
|
|
4626
|
+
});
|
|
4627
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
4628
|
+
args,
|
|
4629
|
+
operation: "create_prds",
|
|
4733
4630
|
payload,
|
|
4734
4631
|
});
|
|
4735
|
-
const prdTargets = prdApprovalTargets(payload);
|
|
4736
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
4737
|
-
operation: "create_prds",
|
|
4738
|
-
artifactKind: "markdown",
|
|
4739
|
-
targets: prdTargets,
|
|
4740
|
-
batchCount: prdTargets.length,
|
|
4741
|
-
});
|
|
4742
4632
|
const data = await postSuggestionsMutation({
|
|
4743
4633
|
apiBase,
|
|
4744
4634
|
key,
|
|
@@ -4747,7 +4637,6 @@ async function runCreatePrd(args) {
|
|
|
4747
4637
|
endpoint: "/project-assistant/create-prds",
|
|
4748
4638
|
idempotencyKey,
|
|
4749
4639
|
clientSessionId,
|
|
4750
|
-
writeApproval,
|
|
4751
4640
|
});
|
|
4752
4641
|
aggregated.project_id = data.project_id || null;
|
|
4753
4642
|
aggregated.created_count = Number(data.created_count || 0);
|
|
@@ -5304,7 +5193,8 @@ async function runFeedbackValidateOrApply(args, mode) {
|
|
|
5304
5193
|
console.error("Missing MYTE_API_KEY (project key) in environment/.env");
|
|
5305
5194
|
process.exit(1);
|
|
5306
5195
|
}
|
|
5307
|
-
const { absPath, payload } = readFeedbackRefinementArtifact(args);
|
|
5196
|
+
const { absPath, payload: artifactPayload } = readFeedbackRefinementArtifact(args);
|
|
5197
|
+
let payload = artifactPayload;
|
|
5308
5198
|
const feedbackId = firstNonEmptyString(args["feedback-id"], args.feedbackId, args.feedback_id, payload.feedback_id);
|
|
5309
5199
|
if (!feedbackId) {
|
|
5310
5200
|
console.error("Feedback refinement artifact is missing feedback_id.");
|
|
@@ -5314,26 +5204,25 @@ async function runFeedbackValidateOrApply(args, mode) {
|
|
|
5314
5204
|
|
|
5315
5205
|
const timeoutMs = resolveTimeoutMs(args);
|
|
5316
5206
|
const apiBase = resolveApiBase(args);
|
|
5317
|
-
const clientSessionId = firstNonEmptyString(
|
|
5207
|
+
const clientSessionId = firstNonEmptyString(
|
|
5318
5208
|
args["client-session-id"],
|
|
5319
5209
|
args.clientSessionId,
|
|
5320
5210
|
args.client_session_id,
|
|
5321
5211
|
payload.client_session_id
|
|
5322
|
-
);
|
|
5323
|
-
|
|
5212
|
+
);
|
|
5213
|
+
if (mode === "apply") {
|
|
5214
|
+
payload = withWriteApproval(args, payload, {
|
|
5215
|
+
artifactKind: "yaml",
|
|
5216
|
+
targets: [feedbackId],
|
|
5217
|
+
});
|
|
5218
|
+
}
|
|
5219
|
+
const idempotencyKey = mode === "apply"
|
|
5324
5220
|
? resolveProjectMutationIdempotencyKey({
|
|
5325
5221
|
args,
|
|
5326
5222
|
operation: `feedback_refinement_apply:${feedbackId}`,
|
|
5327
5223
|
payload,
|
|
5328
5224
|
})
|
|
5329
5225
|
: null;
|
|
5330
|
-
const writeApproval = mode === "apply"
|
|
5331
|
-
? requireWriteApproval(args, payload, {
|
|
5332
|
-
operation: `feedback_refinement_apply:${feedbackId}`,
|
|
5333
|
-
artifactKind: "yaml",
|
|
5334
|
-
targets: [feedbackId],
|
|
5335
|
-
})
|
|
5336
|
-
: null;
|
|
5337
5226
|
|
|
5338
5227
|
let data;
|
|
5339
5228
|
try {
|
|
@@ -5346,7 +5235,6 @@ async function runFeedbackValidateOrApply(args, mode) {
|
|
|
5346
5235
|
payload,
|
|
5347
5236
|
idempotencyKey,
|
|
5348
5237
|
clientSessionId,
|
|
5349
|
-
writeApproval,
|
|
5350
5238
|
});
|
|
5351
5239
|
} catch (err) {
|
|
5352
5240
|
if (args.json) {
|
|
@@ -5458,7 +5346,8 @@ async function runFeedbackSubmit(args) {
|
|
|
5458
5346
|
console.error("Missing MYTE_API_KEY (project key) in environment/.env");
|
|
5459
5347
|
process.exit(1);
|
|
5460
5348
|
}
|
|
5461
|
-
const { absPath, payload } = readFeedbackRefinementArtifact(args);
|
|
5349
|
+
const { absPath, payload: artifactPayload } = readFeedbackRefinementArtifact(args);
|
|
5350
|
+
let payload = artifactPayload;
|
|
5462
5351
|
const feedbackId = firstNonEmptyString(args["feedback-id"], args.feedbackId, args.feedback_id, payload.feedback_id);
|
|
5463
5352
|
if (!feedbackId) {
|
|
5464
5353
|
console.error("Feedback refinement artifact is missing feedback_id.");
|
|
@@ -5466,22 +5355,21 @@ async function runFeedbackSubmit(args) {
|
|
|
5466
5355
|
}
|
|
5467
5356
|
const timeoutMs = resolveTimeoutMs(args);
|
|
5468
5357
|
const apiBase = resolveApiBase(args);
|
|
5469
|
-
const clientSessionId = firstNonEmptyString(
|
|
5358
|
+
const clientSessionId = firstNonEmptyString(
|
|
5470
5359
|
args["client-session-id"],
|
|
5471
5360
|
args.clientSessionId,
|
|
5472
5361
|
args.client_session_id,
|
|
5473
5362
|
payload.client_session_id
|
|
5474
|
-
);
|
|
5475
|
-
|
|
5363
|
+
);
|
|
5364
|
+
payload = withWriteApproval(args, payload, {
|
|
5365
|
+
artifactKind: "yaml",
|
|
5366
|
+
targets: [feedbackId],
|
|
5367
|
+
});
|
|
5368
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
5476
5369
|
args,
|
|
5477
5370
|
operation: `feedback_refinement_request_submit:${feedbackId}`,
|
|
5478
5371
|
payload,
|
|
5479
5372
|
});
|
|
5480
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
5481
|
-
operation: `feedback_refinement_request_submit:${feedbackId}`,
|
|
5482
|
-
artifactKind: "yaml",
|
|
5483
|
-
targets: [feedbackId],
|
|
5484
|
-
});
|
|
5485
5373
|
|
|
5486
5374
|
let data;
|
|
5487
5375
|
try {
|
|
@@ -5493,7 +5381,6 @@ async function runFeedbackSubmit(args) {
|
|
|
5493
5381
|
payload,
|
|
5494
5382
|
idempotencyKey,
|
|
5495
5383
|
clientSessionId,
|
|
5496
|
-
writeApproval,
|
|
5497
5384
|
});
|
|
5498
5385
|
} catch (err) {
|
|
5499
5386
|
if (args.json) {
|
|
@@ -5535,25 +5422,25 @@ async function runFeedbackRevise(args) {
|
|
|
5535
5422
|
console.error("Missing --request-id.");
|
|
5536
5423
|
process.exit(1);
|
|
5537
5424
|
}
|
|
5538
|
-
const { absPath, payload } = readFeedbackRefinementArtifact(args);
|
|
5425
|
+
const { absPath, payload: artifactPayload } = readFeedbackRefinementArtifact(args);
|
|
5426
|
+
let payload = artifactPayload;
|
|
5539
5427
|
const timeoutMs = resolveTimeoutMs(args);
|
|
5540
5428
|
const apiBase = resolveApiBase(args);
|
|
5541
|
-
const clientSessionId = firstNonEmptyString(
|
|
5429
|
+
const clientSessionId = firstNonEmptyString(
|
|
5542
5430
|
args["client-session-id"],
|
|
5543
5431
|
args.clientSessionId,
|
|
5544
5432
|
args.client_session_id,
|
|
5545
5433
|
payload.client_session_id
|
|
5546
|
-
);
|
|
5547
|
-
|
|
5434
|
+
);
|
|
5435
|
+
payload = withWriteApproval(args, payload, {
|
|
5436
|
+
artifactKind: "yaml",
|
|
5437
|
+
targets: [requestId],
|
|
5438
|
+
});
|
|
5439
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
5548
5440
|
args,
|
|
5549
5441
|
operation: `feedback_refinement_request_revise:${requestId}`,
|
|
5550
5442
|
payload,
|
|
5551
5443
|
});
|
|
5552
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
5553
|
-
operation: `feedback_refinement_request_revise:${requestId}`,
|
|
5554
|
-
artifactKind: "yaml",
|
|
5555
|
-
targets: [requestId],
|
|
5556
|
-
});
|
|
5557
5444
|
|
|
5558
5445
|
let data;
|
|
5559
5446
|
try {
|
|
@@ -5566,7 +5453,6 @@ async function runFeedbackRevise(args) {
|
|
|
5566
5453
|
payload,
|
|
5567
5454
|
idempotencyKey,
|
|
5568
5455
|
clientSessionId,
|
|
5569
|
-
writeApproval,
|
|
5570
5456
|
});
|
|
5571
5457
|
} catch (err) {
|
|
5572
5458
|
if (args.json) {
|
|
@@ -5684,13 +5570,18 @@ async function runFeedbackReviewDecision(args) {
|
|
|
5684
5570
|
process.exit(1);
|
|
5685
5571
|
}
|
|
5686
5572
|
const reason = firstNonEmptyString(args.reason, args["review-note"], args.reviewNote, args.review_note);
|
|
5687
|
-
|
|
5688
|
-
...(isPlainObject(filePayload) && !Array.isArray(filePayload) ? filePayload : {}),
|
|
5689
|
-
items,
|
|
5690
|
-
action,
|
|
5691
|
-
reason: reason || undefined,
|
|
5692
|
-
};
|
|
5693
|
-
|
|
5573
|
+
let payload = {
|
|
5574
|
+
...(isPlainObject(filePayload) && !Array.isArray(filePayload) ? filePayload : {}),
|
|
5575
|
+
items,
|
|
5576
|
+
action,
|
|
5577
|
+
reason: reason || undefined,
|
|
5578
|
+
};
|
|
5579
|
+
payload = withWriteApproval(args, payload, {
|
|
5580
|
+
artifactKind: "yaml",
|
|
5581
|
+
targets: items.map((item) => item.request_id || item.id).filter(Boolean),
|
|
5582
|
+
batchCount: items.length,
|
|
5583
|
+
});
|
|
5584
|
+
const timeoutMs = resolveTimeoutMs(args);
|
|
5694
5585
|
const apiBase = resolveApiBase(args);
|
|
5695
5586
|
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id, payload.client_session_id);
|
|
5696
5587
|
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
@@ -5698,15 +5589,6 @@ async function runFeedbackReviewDecision(args) {
|
|
|
5698
5589
|
operation: `feedback_review_batch:${action}:${items.map((item) => item.request_id || item.id || "").join(",")}`,
|
|
5699
5590
|
payload,
|
|
5700
5591
|
});
|
|
5701
|
-
const requestTargets = items
|
|
5702
|
-
.map((item, index) => firstNonEmptyString(item.request_id, item.id, item._id) || `index:${index}`)
|
|
5703
|
-
.filter(Boolean);
|
|
5704
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
5705
|
-
operation: `feedback_review_batch:${action}`,
|
|
5706
|
-
artifactKind: "yaml",
|
|
5707
|
-
targets: requestTargets,
|
|
5708
|
-
batchCount: items.length,
|
|
5709
|
-
});
|
|
5710
5592
|
|
|
5711
5593
|
let data;
|
|
5712
5594
|
try {
|
|
@@ -5717,7 +5599,6 @@ async function runFeedbackReviewDecision(args) {
|
|
|
5717
5599
|
payload,
|
|
5718
5600
|
idempotencyKey,
|
|
5719
5601
|
clientSessionId,
|
|
5720
|
-
writeApproval,
|
|
5721
5602
|
});
|
|
5722
5603
|
} catch (err) {
|
|
5723
5604
|
if (args.json) {
|
|
@@ -5745,8 +5626,8 @@ async function runFeedbackReviewDecision(args) {
|
|
|
5745
5626
|
process.exit(1);
|
|
5746
5627
|
}
|
|
5747
5628
|
|
|
5748
|
-
let payload;
|
|
5749
|
-
try {
|
|
5629
|
+
let payload;
|
|
5630
|
+
try {
|
|
5750
5631
|
payload = filePayload && !Array.isArray(filePayload?.items)
|
|
5751
5632
|
? buildFeedbackReviewDecisionPayload({ ...args, file: "" }, action)
|
|
5752
5633
|
: buildFeedbackReviewDecisionPayload(args, action);
|
|
@@ -5757,8 +5638,12 @@ async function runFeedbackReviewDecision(args) {
|
|
|
5757
5638
|
console.error(err?.message || err);
|
|
5758
5639
|
process.exit(1);
|
|
5759
5640
|
}
|
|
5760
|
-
const endpointAction = action === "request_changes" ? "request-changes" : action === "cancel" ? "cancel" : "review";
|
|
5761
|
-
|
|
5641
|
+
const endpointAction = action === "request_changes" ? "request-changes" : action === "cancel" ? "cancel" : "review";
|
|
5642
|
+
payload = withWriteApproval(args, payload, {
|
|
5643
|
+
artifactKind: "yaml",
|
|
5644
|
+
targets: [requestId],
|
|
5645
|
+
});
|
|
5646
|
+
const timeoutMs = resolveTimeoutMs(args);
|
|
5762
5647
|
const apiBase = resolveApiBase(args);
|
|
5763
5648
|
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id, payload.client_session_id);
|
|
5764
5649
|
const operationAction = action === "request_changes" ? "request_changes" : action;
|
|
@@ -5767,11 +5652,6 @@ async function runFeedbackReviewDecision(args) {
|
|
|
5767
5652
|
operation: `feedback_review_request_${operationAction}:${requestId}`,
|
|
5768
5653
|
payload,
|
|
5769
5654
|
});
|
|
5770
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
5771
|
-
operation: `feedback_review_request_${operationAction}:${requestId}`,
|
|
5772
|
-
artifactKind: "yaml",
|
|
5773
|
-
targets: [requestId],
|
|
5774
|
-
});
|
|
5775
5655
|
|
|
5776
5656
|
let data;
|
|
5777
5657
|
try {
|
|
@@ -5784,7 +5664,6 @@ async function runFeedbackReviewDecision(args) {
|
|
|
5784
5664
|
payload,
|
|
5785
5665
|
idempotencyKey,
|
|
5786
5666
|
clientSessionId,
|
|
5787
|
-
writeApproval,
|
|
5788
5667
|
});
|
|
5789
5668
|
} catch (err) {
|
|
5790
5669
|
if (args.json) {
|
|
@@ -5823,32 +5702,31 @@ async function runFeedbackMove(args) {
|
|
|
5823
5702
|
process.exit(1);
|
|
5824
5703
|
}
|
|
5825
5704
|
const fromState = firstNonEmptyString(args["from-state"], args.fromState, args.from_state) || undefined;
|
|
5826
|
-
|
|
5827
|
-
to_state: toState,
|
|
5828
|
-
reason: firstNonEmptyString(args.reason) || undefined,
|
|
5829
|
-
};
|
|
5705
|
+
let payload = {
|
|
5706
|
+
to_state: toState,
|
|
5707
|
+
reason: firstNonEmptyString(args.reason) || undefined,
|
|
5708
|
+
};
|
|
5830
5709
|
const timeoutMs = resolveTimeoutMs(args);
|
|
5831
5710
|
const apiBase = resolveApiBase(args);
|
|
5832
5711
|
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
5833
5712
|
const isBatch = feedbackIds.length > 1 || Boolean(firstNonEmptyString(args["feedback-ids"], args.feedbackIds, args.feedback_ids));
|
|
5834
|
-
if (isBatch) {
|
|
5835
|
-
payload.feedback_ids = feedbackIds;
|
|
5713
|
+
if (isBatch) {
|
|
5714
|
+
payload.feedback_ids = feedbackIds;
|
|
5836
5715
|
if (fromState) {
|
|
5837
5716
|
payload.from_states = Object.fromEntries(feedbackIds.map((id) => [id, fromState]));
|
|
5838
5717
|
}
|
|
5839
5718
|
const batchId = firstNonEmptyString(args["batch-id"], args.batchId, args.batch_id);
|
|
5840
|
-
if (batchId) payload.batch_id = batchId;
|
|
5841
|
-
|
|
5719
|
+
if (batchId) payload.batch_id = batchId;
|
|
5720
|
+
payload = withWriteApproval(args, payload, {
|
|
5721
|
+
artifactKind: "yaml",
|
|
5722
|
+
targets: feedbackIds,
|
|
5723
|
+
batchCount: feedbackIds.length,
|
|
5724
|
+
});
|
|
5725
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
5842
5726
|
args,
|
|
5843
5727
|
operation: `feedback_board_batch_move:${toState}:${feedbackIds.join(",")}`,
|
|
5844
5728
|
payload,
|
|
5845
5729
|
});
|
|
5846
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
5847
|
-
operation: `feedback_board_batch_move:${toState}`,
|
|
5848
|
-
artifactKind: "yaml",
|
|
5849
|
-
targets: feedbackIds,
|
|
5850
|
-
batchCount: feedbackIds.length,
|
|
5851
|
-
});
|
|
5852
5730
|
let data;
|
|
5853
5731
|
try {
|
|
5854
5732
|
data = await postFeedbackBatchBoardMutation({
|
|
@@ -5858,7 +5736,6 @@ async function runFeedbackMove(args) {
|
|
|
5858
5736
|
payload,
|
|
5859
5737
|
idempotencyKey,
|
|
5860
5738
|
clientSessionId,
|
|
5861
|
-
writeApproval,
|
|
5862
5739
|
});
|
|
5863
5740
|
} catch (err) {
|
|
5864
5741
|
if (args.json) {
|
|
@@ -5879,18 +5756,17 @@ async function runFeedbackMove(args) {
|
|
|
5879
5756
|
if (postSync?.error) console.error(`Feedback sync warning: ${postSync.error}`);
|
|
5880
5757
|
return;
|
|
5881
5758
|
}
|
|
5882
|
-
|
|
5883
|
-
payload.from_state = fromState;
|
|
5884
|
-
|
|
5759
|
+
|
|
5760
|
+
payload.from_state = fromState;
|
|
5761
|
+
payload = withWriteApproval(args, payload, {
|
|
5762
|
+
artifactKind: "yaml",
|
|
5763
|
+
targets: [feedbackId],
|
|
5764
|
+
});
|
|
5765
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
5885
5766
|
args,
|
|
5886
5767
|
operation: `feedback_board_move:${feedbackId}`,
|
|
5887
5768
|
payload,
|
|
5888
5769
|
});
|
|
5889
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
5890
|
-
operation: `feedback_board_move:${feedbackId}`,
|
|
5891
|
-
artifactKind: "yaml",
|
|
5892
|
-
targets: [feedbackId],
|
|
5893
|
-
});
|
|
5894
5770
|
|
|
5895
5771
|
let data;
|
|
5896
5772
|
try {
|
|
@@ -5903,7 +5779,6 @@ async function runFeedbackMove(args) {
|
|
|
5903
5779
|
payload,
|
|
5904
5780
|
idempotencyKey,
|
|
5905
5781
|
clientSessionId,
|
|
5906
|
-
writeApproval,
|
|
5907
5782
|
});
|
|
5908
5783
|
} catch (err) {
|
|
5909
5784
|
if (args.json) {
|
|
@@ -5944,12 +5819,16 @@ async function runFeedbackComment(args) {
|
|
|
5944
5819
|
process.exit(1);
|
|
5945
5820
|
}
|
|
5946
5821
|
|
|
5947
|
-
|
|
5948
|
-
const timeoutMs = resolveTimeoutMs(args);
|
|
5949
|
-
const apiBase = resolveApiBase(args);
|
|
5950
|
-
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
5951
|
-
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
5952
|
-
|
|
5822
|
+
let payload = { content };
|
|
5823
|
+
const timeoutMs = resolveTimeoutMs(args);
|
|
5824
|
+
const apiBase = resolveApiBase(args);
|
|
5825
|
+
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
5826
|
+
if (clientSessionId) payload.client_session_id = clientSessionId;
|
|
5827
|
+
payload = withWriteApproval(args, payload, {
|
|
5828
|
+
artifactKind: "markdown",
|
|
5829
|
+
targets: [feedbackId],
|
|
5830
|
+
});
|
|
5831
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
5953
5832
|
args,
|
|
5954
5833
|
operation: `feedback_comment_create:${feedbackId}`,
|
|
5955
5834
|
payload,
|
|
@@ -5960,12 +5839,6 @@ async function runFeedbackComment(args) {
|
|
|
5960
5839
|
return;
|
|
5961
5840
|
}
|
|
5962
5841
|
|
|
5963
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
5964
|
-
operation: `feedback_comment_create:${feedbackId}`,
|
|
5965
|
-
artifactKind: "markdown",
|
|
5966
|
-
targets: [feedbackId],
|
|
5967
|
-
});
|
|
5968
|
-
|
|
5969
5842
|
let data;
|
|
5970
5843
|
try {
|
|
5971
5844
|
data = await postFeedbackComment({
|
|
@@ -5976,7 +5849,6 @@ async function runFeedbackComment(args) {
|
|
|
5976
5849
|
payload,
|
|
5977
5850
|
idempotencyKey,
|
|
5978
5851
|
clientSessionId,
|
|
5979
|
-
writeApproval,
|
|
5980
5852
|
});
|
|
5981
5853
|
} catch (err) {
|
|
5982
5854
|
if (args.json) {
|
|
@@ -6025,27 +5897,20 @@ async function runFeedbackUndo(args) {
|
|
|
6025
5897
|
console.error("Missing --event-id.");
|
|
6026
5898
|
process.exit(1);
|
|
6027
5899
|
}
|
|
6028
|
-
|
|
6029
|
-
const timeoutMs = resolveTimeoutMs(args);
|
|
6030
|
-
const apiBase = resolveApiBase(args);
|
|
6031
|
-
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
6032
|
-
|
|
5900
|
+
let payload = { reason: firstNonEmptyString(args.reason) || undefined };
|
|
5901
|
+
const timeoutMs = resolveTimeoutMs(args);
|
|
5902
|
+
const apiBase = resolveApiBase(args);
|
|
5903
|
+
const clientSessionId = firstNonEmptyString(args["client-session-id"], args.clientSessionId, args.client_session_id);
|
|
5904
|
+
payload = withWriteApproval(args, payload, {
|
|
5905
|
+
artifactKind: "yaml",
|
|
5906
|
+
targets: [feedbackId, eventId],
|
|
5907
|
+
});
|
|
5908
|
+
const idempotencyKey = resolveProjectMutationIdempotencyKey({
|
|
6033
5909
|
args,
|
|
6034
5910
|
operation: `feedback_event_undo:${feedbackId}:${eventId}`,
|
|
6035
5911
|
payload,
|
|
6036
5912
|
});
|
|
6037
5913
|
|
|
6038
|
-
if (args["print-context"] || args.printContext || args["dry-run"] || args.dryRun) {
|
|
6039
|
-
console.log(JSON.stringify(payload, null, 2));
|
|
6040
|
-
return;
|
|
6041
|
-
}
|
|
6042
|
-
|
|
6043
|
-
const writeApproval = requireWriteApproval(args, payload, {
|
|
6044
|
-
operation: `feedback_event_undo:${feedbackId}:${eventId}`,
|
|
6045
|
-
artifactKind: "yaml",
|
|
6046
|
-
targets: [feedbackId, eventId],
|
|
6047
|
-
});
|
|
6048
|
-
|
|
6049
5914
|
let data;
|
|
6050
5915
|
try {
|
|
6051
5916
|
data = await postFeedbackBoardMutation({
|
|
@@ -6057,7 +5922,6 @@ async function runFeedbackUndo(args) {
|
|
|
6057
5922
|
payload,
|
|
6058
5923
|
idempotencyKey,
|
|
6059
5924
|
clientSessionId,
|
|
6060
|
-
writeApproval,
|
|
6061
5925
|
});
|
|
6062
5926
|
} catch (err) {
|
|
6063
5927
|
if (args.json) {
|
|
@@ -6343,14 +6207,20 @@ async function buildSuggestionsMutationContext(args, mode) {
|
|
|
6343
6207
|
if (clientSessionId && !payload.client_session_id) {
|
|
6344
6208
|
payload.client_session_id = clientSessionId;
|
|
6345
6209
|
}
|
|
6346
|
-
if (mode === "create") {
|
|
6347
|
-
validateSuggestionsCreatePayload(payload);
|
|
6348
|
-
} else if (mode === "revise") {
|
|
6349
|
-
validateSuggestionsRevisePayload(payload);
|
|
6350
|
-
}
|
|
6351
|
-
const
|
|
6352
|
-
|
|
6353
|
-
|
|
6210
|
+
if (mode === "create") {
|
|
6211
|
+
validateSuggestionsCreatePayload(payload);
|
|
6212
|
+
} else if (mode === "revise") {
|
|
6213
|
+
validateSuggestionsRevisePayload(payload);
|
|
6214
|
+
}
|
|
6215
|
+
const items = Array.isArray(payload?.items) ? payload.items : [];
|
|
6216
|
+
payload = withWriteApproval(args, payload, {
|
|
6217
|
+
artifactKind: "yaml",
|
|
6218
|
+
targets: suggestionWriteTargets(items),
|
|
6219
|
+
batchCount: items.length > 1 ? items.length : null,
|
|
6220
|
+
});
|
|
6221
|
+
const idempotencyKey = resolveSuggestionsIdempotencyKey({
|
|
6222
|
+
args,
|
|
6223
|
+
mode,
|
|
6354
6224
|
actorScope,
|
|
6355
6225
|
payload,
|
|
6356
6226
|
});
|
|
@@ -6436,14 +6306,6 @@ async function runSuggestionsCreate(args) {
|
|
|
6436
6306
|
return;
|
|
6437
6307
|
}
|
|
6438
6308
|
|
|
6439
|
-
const createTargets = suggestionApprovalTargets(context.payload);
|
|
6440
|
-
const writeApproval = requireWriteApproval(args, context.payload, {
|
|
6441
|
-
operation: "suggestions.create",
|
|
6442
|
-
artifactKind: "yaml",
|
|
6443
|
-
targets: createTargets,
|
|
6444
|
-
batchCount: createTargets.length > 1 ? createTargets.length : null,
|
|
6445
|
-
});
|
|
6446
|
-
|
|
6447
6309
|
let data;
|
|
6448
6310
|
try {
|
|
6449
6311
|
data = await createProjectSuggestions({
|
|
@@ -6453,7 +6315,6 @@ async function runSuggestionsCreate(args) {
|
|
|
6453
6315
|
payload: context.payload,
|
|
6454
6316
|
idempotencyKey: context.idempotencyKey,
|
|
6455
6317
|
clientSessionId: context.clientSessionId,
|
|
6456
|
-
writeApproval,
|
|
6457
6318
|
});
|
|
6458
6319
|
} catch (err) {
|
|
6459
6320
|
console.error("Suggestions create failed:", err?.message || err);
|
|
@@ -6530,14 +6391,6 @@ async function runSuggestionsRevise(args) {
|
|
|
6530
6391
|
return;
|
|
6531
6392
|
}
|
|
6532
6393
|
|
|
6533
|
-
const reviseTargets = suggestionApprovalTargets(context.payload);
|
|
6534
|
-
const writeApproval = requireWriteApproval(args, context.payload, {
|
|
6535
|
-
operation: "suggestions.revise",
|
|
6536
|
-
artifactKind: "yaml",
|
|
6537
|
-
targets: reviseTargets,
|
|
6538
|
-
batchCount: reviseTargets.length > 1 ? reviseTargets.length : null,
|
|
6539
|
-
});
|
|
6540
|
-
|
|
6541
6394
|
let data;
|
|
6542
6395
|
try {
|
|
6543
6396
|
data = await reviseProjectSuggestions({
|
|
@@ -6547,7 +6400,6 @@ async function runSuggestionsRevise(args) {
|
|
|
6547
6400
|
payload: context.payload,
|
|
6548
6401
|
idempotencyKey: context.idempotencyKey,
|
|
6549
6402
|
clientSessionId: context.clientSessionId,
|
|
6550
|
-
writeApproval,
|
|
6551
6403
|
});
|
|
6552
6404
|
} catch (err) {
|
|
6553
6405
|
console.error("Suggestions revise failed:", err?.message || err);
|
|
@@ -6622,14 +6474,6 @@ async function runSuggestionsReview(args) {
|
|
|
6622
6474
|
return;
|
|
6623
6475
|
}
|
|
6624
6476
|
|
|
6625
|
-
const reviewTargets = suggestionApprovalTargets(context.payload);
|
|
6626
|
-
const writeApproval = requireWriteApproval(args, context.payload, {
|
|
6627
|
-
operation: "suggestions.review",
|
|
6628
|
-
artifactKind: "yaml",
|
|
6629
|
-
targets: reviewTargets,
|
|
6630
|
-
batchCount: reviewTargets.length > 1 ? reviewTargets.length : null,
|
|
6631
|
-
});
|
|
6632
|
-
|
|
6633
6477
|
let data;
|
|
6634
6478
|
try {
|
|
6635
6479
|
data = await reviewProjectSuggestions({
|
|
@@ -6639,7 +6483,6 @@ async function runSuggestionsReview(args) {
|
|
|
6639
6483
|
payload: context.payload,
|
|
6640
6484
|
idempotencyKey: context.idempotencyKey,
|
|
6641
6485
|
clientSessionId: context.clientSessionId,
|
|
6642
|
-
writeApproval,
|
|
6643
6486
|
});
|
|
6644
6487
|
} catch (err) {
|
|
6645
6488
|
console.error("Suggestions review failed:", err?.message || err);
|