norn-cli 4.6.1 → 4.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +101 -11
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -166647,6 +166647,9 @@ function parseDurationToMs(rawValue, defaultUnit = "ms") {
|
|
|
166647
166647
|
}
|
|
166648
166648
|
|
|
166649
166649
|
// src/formUrlEncoded.ts
|
|
166650
|
+
function decodeFieldValue(value) {
|
|
166651
|
+
return isQuotedStringLiteral(value) ? decodeQuotedStringLiteral(value) : value;
|
|
166652
|
+
}
|
|
166650
166653
|
function parseEqualsField(segment) {
|
|
166651
166654
|
const eqIndex = segment.indexOf("=");
|
|
166652
166655
|
if (eqIndex <= 0) {
|
|
@@ -166654,9 +166657,53 @@ function parseEqualsField(segment) {
|
|
|
166654
166657
|
}
|
|
166655
166658
|
return {
|
|
166656
166659
|
key: segment.substring(0, eqIndex).trim(),
|
|
166657
|
-
value: segment.substring(eqIndex + 1).trim()
|
|
166660
|
+
value: decodeFieldValue(segment.substring(eqIndex + 1).trim())
|
|
166658
166661
|
};
|
|
166659
166662
|
}
|
|
166663
|
+
function splitAmpersandDelimitedLine(line2) {
|
|
166664
|
+
const segments = [];
|
|
166665
|
+
let current = "";
|
|
166666
|
+
let quote;
|
|
166667
|
+
let escaped = false;
|
|
166668
|
+
let inValue = false;
|
|
166669
|
+
let valueStarted = false;
|
|
166670
|
+
for (const char of line2) {
|
|
166671
|
+
if (escaped) {
|
|
166672
|
+
current += char;
|
|
166673
|
+
escaped = false;
|
|
166674
|
+
continue;
|
|
166675
|
+
}
|
|
166676
|
+
if (quote && char === "\\") {
|
|
166677
|
+
current += char;
|
|
166678
|
+
escaped = true;
|
|
166679
|
+
continue;
|
|
166680
|
+
}
|
|
166681
|
+
if ((char === '"' || char === "'") && (quote || inValue && !valueStarted)) {
|
|
166682
|
+
if (!quote) {
|
|
166683
|
+
quote = char;
|
|
166684
|
+
} else if (quote === char) {
|
|
166685
|
+
quote = void 0;
|
|
166686
|
+
}
|
|
166687
|
+
current += char;
|
|
166688
|
+
continue;
|
|
166689
|
+
}
|
|
166690
|
+
if (char === "&" && !quote) {
|
|
166691
|
+
segments.push(current.trim());
|
|
166692
|
+
current = "";
|
|
166693
|
+
inValue = false;
|
|
166694
|
+
valueStarted = false;
|
|
166695
|
+
continue;
|
|
166696
|
+
}
|
|
166697
|
+
current += char;
|
|
166698
|
+
if (!inValue && char === "=") {
|
|
166699
|
+
inValue = true;
|
|
166700
|
+
} else if (inValue && !/\s/.test(char)) {
|
|
166701
|
+
valueStarted = true;
|
|
166702
|
+
}
|
|
166703
|
+
}
|
|
166704
|
+
segments.push(current.trim());
|
|
166705
|
+
return segments;
|
|
166706
|
+
}
|
|
166660
166707
|
function isFormUrlEncodedContentType(contentType) {
|
|
166661
166708
|
return Boolean(contentType && contentType.toLowerCase().includes("application/x-www-form-urlencoded"));
|
|
166662
166709
|
}
|
|
@@ -166672,7 +166719,7 @@ function parseFormUrlEncodedLines(lines) {
|
|
|
166672
166719
|
const firstColonIndex = line2.indexOf(":");
|
|
166673
166720
|
if (firstEqIndex > 0 && (firstColonIndex === -1 || firstEqIndex < firstColonIndex)) {
|
|
166674
166721
|
if (line2.includes("&")) {
|
|
166675
|
-
const segments = line2
|
|
166722
|
+
const segments = splitAmpersandDelimitedLine(line2);
|
|
166676
166723
|
const hasInvalidSegment = segments.some((segment) => !parseEqualsField(segment));
|
|
166677
166724
|
if (hasInvalidSegment) {
|
|
166678
166725
|
errors.push({
|
|
@@ -166699,7 +166746,7 @@ function parseFormUrlEncodedLines(lines) {
|
|
|
166699
166746
|
if (firstColonIndex > 0) {
|
|
166700
166747
|
fields.push({
|
|
166701
166748
|
key: line2.substring(0, firstColonIndex).trim(),
|
|
166702
|
-
value: line2.substring(firstColonIndex + 1).trim()
|
|
166749
|
+
value: decodeFieldValue(line2.substring(firstColonIndex + 1).trim())
|
|
166703
166750
|
});
|
|
166704
166751
|
continue;
|
|
166705
166752
|
}
|
|
@@ -166723,10 +166770,13 @@ function encodeFormUrlEncodedBody(body) {
|
|
|
166723
166770
|
return { encodedBody: "", errors };
|
|
166724
166771
|
}
|
|
166725
166772
|
return {
|
|
166726
|
-
encodedBody: fields
|
|
166773
|
+
encodedBody: encodeFormUrlEncodedFields(fields),
|
|
166727
166774
|
errors: []
|
|
166728
166775
|
};
|
|
166729
166776
|
}
|
|
166777
|
+
function encodeFormUrlEncodedFields(fields) {
|
|
166778
|
+
return fields.map((field) => `${encodeURIComponent(field.key)}=${encodeURIComponent(field.value)}`).join("&");
|
|
166779
|
+
}
|
|
166730
166780
|
|
|
166731
166781
|
// src/sequenceCancellation.ts
|
|
166732
166782
|
var SEQUENCE_CANCELLED_MESSAGE = "Sequence run cancelled by user.";
|
|
@@ -166861,7 +166911,10 @@ async function sendRequestWithJar(request, jar, retryOptions, signal) {
|
|
|
166861
166911
|
);
|
|
166862
166912
|
const contentTypeValue = contentType ? headers[contentType] : "";
|
|
166863
166913
|
if (isFormUrlEncodedContentType(contentTypeValue)) {
|
|
166864
|
-
const encoded =
|
|
166914
|
+
const encoded = request.formUrlEncodedBody ? {
|
|
166915
|
+
encodedBody: encodeFormUrlEncodedFields(request.formUrlEncodedBody.fields),
|
|
166916
|
+
errors: request.formUrlEncodedBody.errors
|
|
166917
|
+
} : encodeFormUrlEncodedBody(currentBody);
|
|
166865
166918
|
if (encoded.errors.length > 0) {
|
|
166866
166919
|
throw new NornError({
|
|
166867
166920
|
category: "syntax",
|
|
@@ -168154,7 +168207,7 @@ function validatePreparedRequest(parsed, context) {
|
|
|
168154
168207
|
}
|
|
168155
168208
|
const contentType = getHeaderValueCaseInsensitive(parsed.headers, "Content-Type");
|
|
168156
168209
|
if (isFormUrlEncodedContentType(contentType)) {
|
|
168157
|
-
const
|
|
168210
|
+
const errors = parsed.formUrlEncodedBody?.errors ?? parseFormUrlEncodedBody(parsed.body).errors;
|
|
168158
168211
|
if (errors.length > 0) {
|
|
168159
168212
|
throw new NornError({
|
|
168160
168213
|
category: "syntax",
|
|
@@ -185378,6 +185431,25 @@ var McpSessionManager = class {
|
|
|
185378
185431
|
};
|
|
185379
185432
|
|
|
185380
185433
|
// src/requestPreparation.ts
|
|
185434
|
+
function getHeaderValueCaseInsensitive2(headers, name) {
|
|
185435
|
+
const target = name.toLowerCase();
|
|
185436
|
+
return Object.entries(headers).find(([headerName]) => headerName.toLowerCase() === target)?.[1];
|
|
185437
|
+
}
|
|
185438
|
+
function attachPreparedFormBody(request, authoredBody, variables) {
|
|
185439
|
+
const contentType = getHeaderValueCaseInsensitive2(request.headers, "Content-Type");
|
|
185440
|
+
if (!isFormUrlEncodedContentType(contentType) || !authoredBody) {
|
|
185441
|
+
return request;
|
|
185442
|
+
}
|
|
185443
|
+
const parsed = parseFormUrlEncodedBody(authoredBody);
|
|
185444
|
+
const prepared = {
|
|
185445
|
+
errors: parsed.errors,
|
|
185446
|
+
fields: parsed.fields.map((field) => ({
|
|
185447
|
+
key: substituteVariables(field.key, variables),
|
|
185448
|
+
value: substituteVariables(field.value, variables)
|
|
185449
|
+
}))
|
|
185450
|
+
};
|
|
185451
|
+
return { ...request, formUrlEncodedBody: prepared };
|
|
185452
|
+
}
|
|
185381
185453
|
function escapeRegExp(value) {
|
|
185382
185454
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
185383
185455
|
}
|
|
@@ -185421,7 +185493,8 @@ function resolveBareVariableRequestBody(request, variables) {
|
|
|
185421
185493
|
}
|
|
185422
185494
|
return {
|
|
185423
185495
|
...request,
|
|
185424
|
-
body: stringifyRequestValue(variables[bareVariableMatch[1]])
|
|
185496
|
+
body: stringifyRequestValue(variables[bareVariableMatch[1]]),
|
|
185497
|
+
formUrlEncodedBody: void 0
|
|
185425
185498
|
};
|
|
185426
185499
|
}
|
|
185427
185500
|
function applyHeaderGroupsToRequest(parsed, requestText, headerGroups, variables) {
|
|
@@ -185530,12 +185603,13 @@ function prepareRequestFromContent(requestContent, variables, apiDefinitions) {
|
|
|
185530
185603
|
for (const [headerName, headerValue] of Object.entries(apiRequest.inlineHeaders)) {
|
|
185531
185604
|
combinedHeaders[headerName] = substituteVariables(headerValue, variables);
|
|
185532
185605
|
}
|
|
185533
|
-
|
|
185606
|
+
let request2 = {
|
|
185534
185607
|
method: apiRequest.method,
|
|
185535
185608
|
url: resolvedPath,
|
|
185536
185609
|
headers: combinedHeaders,
|
|
185537
185610
|
body: apiRequest.body ? substituteVariables(apiRequest.body, variables) : void 0
|
|
185538
185611
|
};
|
|
185612
|
+
request2 = attachPreparedFormBody(request2, apiRequest.body, variables);
|
|
185539
185613
|
return {
|
|
185540
185614
|
request: request2,
|
|
185541
185615
|
description: `${apiRequest.endpointName}(${Object.values(resolvedParams).join(", ")}) -> ${request2.method} ${request2.url}`,
|
|
@@ -185544,9 +185618,12 @@ function prepareRequestFromContent(requestContent, variables, apiDefinitions) {
|
|
|
185544
185618
|
}
|
|
185545
185619
|
}
|
|
185546
185620
|
let request = parserHttpRequest(requestContent, variables);
|
|
185621
|
+
let authoredRequest = parserHttpRequest(requestContent, {});
|
|
185547
185622
|
if (apiDefinitions && apiDefinitions.headerGroups.length > 0) {
|
|
185548
185623
|
request = applyHeaderGroupsToRequest(request, requestContent, apiDefinitions.headerGroups, variables);
|
|
185624
|
+
authoredRequest = applyHeaderGroupsToRequest(authoredRequest, requestContent, apiDefinitions.headerGroups, {});
|
|
185549
185625
|
}
|
|
185626
|
+
request = attachPreparedFormBody(request, authoredRequest.body, variables);
|
|
185550
185627
|
return {
|
|
185551
185628
|
request,
|
|
185552
185629
|
description: `${request.method} ${request.url}`
|
|
@@ -200666,7 +200743,20 @@ ${TOOL_RESULT_RECOVERY_INSTRUCTIONS}`;
|
|
|
200666
200743
|
retry2.correctedByInvocationId = child.invocationId;
|
|
200667
200744
|
}
|
|
200668
200745
|
outputContractFailures = 0;
|
|
200669
|
-
|
|
200746
|
+
const returnedOutput = Object.prototype.hasOwnProperty.call(child.output, "body") ? child.output.body : child.output.text;
|
|
200747
|
+
if (this.rootInvocationId && this.options.onJournalEvent && !this.options.signal?.aborted) {
|
|
200748
|
+
this.options.onJournalEvent({
|
|
200749
|
+
type: "return",
|
|
200750
|
+
timestamp: Date.now(),
|
|
200751
|
+
rootInvocationId: this.rootInvocationId,
|
|
200752
|
+
invocationId: child.invocationId,
|
|
200753
|
+
parentInvocationId: parentHop.invocationId,
|
|
200754
|
+
agent: child.agent,
|
|
200755
|
+
parentAgent: parentHop.agent,
|
|
200756
|
+
output: returnedOutput
|
|
200757
|
+
});
|
|
200758
|
+
}
|
|
200759
|
+
return returnedOutput;
|
|
200670
200760
|
}));
|
|
200671
200761
|
}
|
|
200672
200762
|
const offeredJournal = requestToolsOverride?.find((tool) => tool.kind === "journal" && tool.name === "report_progress");
|
|
@@ -208190,7 +208280,7 @@ ${describeUnmetExpectations(verdict).map((line2) => ` - ${line2}`).join("\n")}`
|
|
|
208190
208280
|
let requestText = `${parsed.method} ${parsed.url}`;
|
|
208191
208281
|
const contentLines = step.content.split("\n");
|
|
208192
208282
|
if (contentLines.length > 1) {
|
|
208193
|
-
const extraLines = contentLines.slice(1)
|
|
208283
|
+
const extraLines = contentLines.slice(1);
|
|
208194
208284
|
const hasExplicitBlank = extraLines.some((line2) => line2.trim() === "");
|
|
208195
208285
|
const firstNonEmpty = extraLines.find((line2) => line2.trim() !== "");
|
|
208196
208286
|
const startsWithHeader = firstNonEmpty ? /^[A-Za-z0-9\-_]+\s*:/.test(firstNonEmpty.trim()) : false;
|
|
@@ -214822,7 +214912,7 @@ async function main() {
|
|
|
214822
214912
|
}
|
|
214823
214913
|
const args = rawArgs[0] === "run" ? rawArgs.slice(1) : rawArgs;
|
|
214824
214914
|
if (args.length === 1 && (args[0] === "--version" || args[0] === "-V")) {
|
|
214825
|
-
console.log(`Norn CLI ${"4.6.
|
|
214915
|
+
console.log(`Norn CLI ${"4.6.1"}`);
|
|
214826
214916
|
return;
|
|
214827
214917
|
}
|
|
214828
214918
|
if (args.length === 0) {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "norn-cli",
|
|
3
3
|
"displayName": "Norn",
|
|
4
4
|
"description": "Build version-controlled agentic flows in VS Code and run them from the CLI or CI.",
|
|
5
|
-
"version": "4.6.
|
|
5
|
+
"version": "4.6.2",
|
|
6
6
|
"publisher": "Norn-PeterKrustanov",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Peter Krastanov"
|