Skip to content

docs: add workflow automation recipes#12

Merged
SebaSOFT merged 2 commits into
mainfrom
growth/njs-growth-06-publish-workflow-automation-recipes
Jun 22, 2026
Merged

docs: add workflow automation recipes#12
SebaSOFT merged 2 commits into
mainfrom
growth/njs-growth-06-publish-workflow-automation-recipes

Conversation

@SebaSOFT

@SebaSOFT SebaSOFT commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Implements NJS-GROWTH-06. Adds n8n and LangGraph deterministic decision recipes, runnable examples, docs navigation, AI-readable discovery links, and contract tests.

Validation:

  • yarn lint — passed
  • yarn test — passed (10 files / 54 tests)
  • yarn examples — passed (all five examples, including n8n and LangGraph recipes)
  • yarn docs:build — passed
  • npm pack --dry-run — passed; tarball includes examples/n8n-code-node, examples/langgraph-decision-node, ai/skills/neuron-js/SKILL.md, schemas, README.md, and dist

Release policy:

  • No package.json version change; package remains 0.5.2.
  • No changeset included: docs/examples-only growth work; no package release expected.

Do not merge automatically; Sebastián will verify.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces integration recipes and documentation for using Neuron-JS as a deterministic decision node in n8n and LangGraph workflows, including new runnable examples, tests, and updated AI-readable documentation. The feedback highlights two critical issues across the newly added code and documentation snippets: a potential runtime TypeError when spreading potentially undefined errors arrays during validation failures, and a prototype pollution vulnerability in the readStatePath helper function that lacks guards against keys like __proto__ or constructor.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +136 to +145
"Invalid string comparison input",
]);
}

if (comp !== "=" && comp !== "!=") {
return new ExecutionResult(false, context, false, [
`Unsupported string comparator: ${comp}`,
]);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If only one of the validations fails (e.g., scriptValidation.ok is true but contextValidation.ok is false), then scriptValidation.errors will be undefined. Attempting to spread undefined using the spread operator (...scriptValidation.errors) will throw a runtime TypeError: Spread syntax requires all elements to be iterable. Use the nullish coalescing operator (?? []) to safely default to an empty array.

if (!scriptValidation.ok || !contextValidation.ok) {
  console.error(
    JSON.stringify(
      { ok: false, errors: [...(scriptValidation.errors ?? []), ...(contextValidation.errors ?? [])] },
      null,
      2,
    ),
  );
  process.exit(1);
}

Comment on lines +226 to +235
if (!scriptValidation.ok || !contextValidation.ok) {
console.error(
JSON.stringify(
{ ok: false, errors: [...scriptValidation.errors, ...contextValidation.errors] },
null,
2,
),
);
process.exit(1);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If only one of the validations fails (e.g., scriptValidation.ok is true but contextValidation.ok is false), then scriptValidation.errors will be undefined. Attempting to spread undefined using the spread operator (...scriptValidation.errors) will throw a runtime TypeError: Spread syntax requires all elements to be iterable. Use the nullish coalescing operator (?? []) to safely default to an empty array.

if (!scriptValidation.ok || !contextValidation.ok) {
  console.error(
    JSON.stringify(
      { ok: false, errors: [...(scriptValidation.errors ?? []), ...(contextValidation.errors ?? [])] },
      null,
      2,
    ),
  );
  process.exit(1);
}

Comment on lines +19 to +26
function readStatePath(context: ExecutionContext, path: string): unknown {
return path.split(".").reduce<unknown>((current, segment) => {
if (current && typeof current === "object" && segment in current) {
return (current as Record<string, unknown>)[segment];
}
return undefined;
}, context.state);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The readStatePath helper splits the path by . and traverses the object. If the path contains keys like __proto__, constructor, or prototype, it can lead to prototype traversal or unexpected behavior. Guard against these special keys to ensure safe object property resolution.

function readStatePath(context: ExecutionContext, path: string): unknown {
  return path.split(".").reduce<unknown>((current, segment) => {
    if (segment === "__proto__" || segment === "constructor" || segment === "prototype") {
      return undefined;
    }
    if (current && typeof current === "object" && segment in current) {
      return (current as Record<string, unknown>)[segment];
    }
    return undefined;
  }, context.state);
}

Comment on lines +19 to +26
function readStatePath(context: ExecutionContext, path: string): unknown {
return path.split(".").reduce<unknown>((current, segment) => {
if (current && typeof current === "object" && segment in current) {
return (current as Record<string, unknown>)[segment];
}
return undefined;
}, context.state);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The readStatePath helper splits the path by . and traverses the object. If the path contains keys like __proto__, constructor, or prototype, it can lead to prototype traversal or unexpected behavior. Guard against these special keys to ensure safe object property resolution.

function readStatePath(context: ExecutionContext, path: string): unknown {
  return path.split(".").reduce<unknown>((current, segment) => {
    if (segment === "__proto__" || segment === "constructor" || segment === "prototype") {
      return undefined;
    }
    if (current && typeof current === "object" && segment in current) {
      return (current as Record<string, unknown>)[segment];
    }
    return undefined;
  }, context.state);
}

const contextValidation = validateExecutionContext(context);

if (!scriptValidation.ok || !contextValidation.ok) {
return { ...state, neuronDecision: { ok: false, errors: [...scriptValidation.errors, ...contextValidation.errors] } };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If only one of the validations fails (e.g., scriptValidation.ok is true but contextValidation.ok is false), then scriptValidation.errors will be undefined. Attempting to spread undefined using the spread operator (...scriptValidation.errors) will throw a runtime TypeError: Spread syntax requires all elements to be iterable. Use the nullish coalescing operator (?? []) to safely default to an empty array.

Suggested change
return { ...state, neuronDecision: { ok: false, errors: [...scriptValidation.errors, ...contextValidation.errors] } };
return { ...state, neuronDecision: { ok: false, errors: [...(scriptValidation.errors ?? []), ...(contextValidation.errors ?? [])] } };

Comment thread docs/integrations/n8n.md
const contextValidation = validateExecutionContext(context);

if (!scriptValidation.ok || !contextValidation.ok) {
return [{ json: { ok: false, errors: [...scriptValidation.errors, ...contextValidation.errors] } }];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If only one of the validations fails (e.g., scriptValidation.ok is true but contextValidation.ok is false), then scriptValidation.errors will be undefined. Attempting to spread undefined using the spread operator (...scriptValidation.errors) will throw a runtime TypeError: Spread syntax requires all elements to be iterable. Use the nullish coalescing operator (?? []) to safely default to an empty array.

Suggested change
return [{ json: { ok: false, errors: [...scriptValidation.errors, ...contextValidation.errors] } }];
return [{ json: { ok: false, errors: [...(scriptValidation.errors ?? []), ...(contextValidation.errors ?? [])] } }];

Comment on lines +53 to +61
if (!scriptValidation.ok || !contextValidation.ok) {
return {
...state,
neuronDecision: {
ok: false,
errors: [...scriptValidation.errors, ...contextValidation.errors],
},
};
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If only one of the validations fails (e.g., scriptValidation.ok is true but contextValidation.ok is false), then scriptValidation.errors will be undefined. Attempting to spread undefined using the spread operator (...scriptValidation.errors) will throw a runtime TypeError: Spread syntax requires all elements to be iterable. Use the nullish coalescing operator (?? []) to safely default to an empty array.

Suggested change
if (!scriptValidation.ok || !contextValidation.ok) {
return {
...state,
neuronDecision: {
ok: false,
errors: [...scriptValidation.errors, ...contextValidation.errors],
},
};
}
if (!scriptValidation.ok || !contextValidation.ok) {
return {
...state,
neuronDecision: {
ok: false,
errors: [...(scriptValidation.errors ?? []), ...(contextValidation.errors ?? [])],
},
};
}

Comment on lines +65 to +72
if (!scriptValidation.ok || !contextValidation.ok) {
return [{
json: {
ok: false,
errors: [...scriptValidation.errors, ...contextValidation.errors],
},
}];
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If only one of the validations fails (e.g., scriptValidation.ok is true but contextValidation.ok is false), then scriptValidation.errors will be undefined. Attempting to spread undefined using the spread operator (...scriptValidation.errors) will throw a runtime TypeError: Spread syntax requires all elements to be iterable. Use the nullish coalescing operator (?? []) to safely default to an empty array.

Suggested change
if (!scriptValidation.ok || !contextValidation.ok) {
return [{
json: {
ok: false,
errors: [...scriptValidation.errors, ...contextValidation.errors],
},
}];
}
if (!scriptValidation.ok || !contextValidation.ok) {
return [{
json: {
ok: false,
errors: [...(scriptValidation.errors ?? []), ...(contextValidation.errors ?? [])],
},
}];
}

@SebaSOFT SebaSOFT merged commit f7a5c1a into main Jun 22, 2026
2 checks passed
@SebaSOFT SebaSOFT deleted the growth/njs-growth-06-publish-workflow-automation-recipes branch June 22, 2026 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant