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.
Files changed (2) hide show
  1. package/dist/cli.js +101 -11
  2. 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.split("&").map((segment) => segment.trim());
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.map((field) => `${encodeURIComponent(field.key)}=${encodeURIComponent(field.value)}`).join("&"),
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 = encodeFormUrlEncodedBody(currentBody);
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 { errors } = parseFormUrlEncodedBody(parsed.body);
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
- const request2 = {
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
- return Object.prototype.hasOwnProperty.call(child.output, "body") ? child.output.body : child.output.text;
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).map((line2) => substituteVariables(line2, runtimeVariables));
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.0"}`);
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.1",
5
+ "version": "4.6.2",
6
6
  "publisher": "Norn-PeterKrustanov",
7
7
  "author": {
8
8
  "name": "Peter Krastanov"