Skip to content

Feature Proposal: Fully Functional JsCodeNode with JSONPath & Logic Branching #82

@sunk926

Description

@sunk926

Hi ,

I’m writing to share a set of advanced features I’ve implemented in my local fork of Cannoli. I have heavily modified the core logic to transform Cannoli into a powerful logic engine capable of executing JavaScript and handling complex JSON data flows.

Reason for not submitting a PR: These changes involve invasive modifications to factory.ts, node type mappings, and the execution loop (e.g., handling Mock vs. Real runs). Because this might introduce instability or conflict with your core roadmap, I am not submitting a Pull Request. However, I hope these concepts might inspire future official features.

Here is the technical summary of what I implemented:

  1. JsCodeNode (Mapped to Red Color "1")
    I repurposed the Red node to act as a JavaScript sandbox with full access to the Obsidian environment.

Capabilities: Supports async/await, app (Obsidian API), plugins, and Cannoli context variables.

Execution Safety: I solved the issue where code ran twice (during validation and execution) by checking if (this.run.isMock) return; inside the execution logic.

Context Handling: Solved JS reserved keyword conflicts by exposing the node context as _this instead of this.

  1. Advanced Logic Branching
    The JsCodeNode acts as a decision engine. It supports two return types to control "Choice Arrows" (Yellow/3):

Simple String Return:

Returns "success" → Triggers the arrow labeled success.

Object Return (Logic + Payload):

Returns { choice: "next", data: [1,2,3], user: "me" }.

The choice property dictates the path.

The rest of the object is passed as a payload to the next node.

  1. Enhanced Data Access in Content/Formatter Nodes
    I implemented a parser that allows downstream nodes to access the JSON objects returned by the JsCodeNode using both Dot Notation and JSONPath.

Example Scenario:

JsCodeNode Returns: { "choice": "next", "times": [1, 2, 3], "name": "test", "store": {...} }

Downstream Node Syntax Support:

Handlebars

{{option}} // Returns the full JSON object string
{{option.times}} // Returns "[1, 2, 3]" (Dot Notation)
{{option.name}} // Returns "test"
{{option.$.times}} // Returns "[1, 2, 3]" (JSONPath support)
{{option.$.store.book[*].author}} // Complex JSONPath queries
4. Smart Context Variables (Text-Generator style)
I also included {{TG_SELECTION}}, {{PREV_LINE}}, and {{NEXT_LINE}} to give the LLM/Code nodes better awareness of the user's cursor position in the active note.Similar to obsidian-textgenerator-plugin

These changes make Cannoli significantly more powerful for automation tasks that require real logic programming alongside LLM generation. I’m happy to share specific snippets (like the JSONPath implementation or the Mock run fix) if you are interested.

Thanks for building such an extensible tool!

Best regards,

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions