Octonode Playbook

Source workflow grammar

Canonical Octonode repository documentation.

Source workflow grammar

parseFunctionToWorkflow imports a deliberately small TypeScript subset. It either maps the whole function to a workflow or throws ParseError; it never substitutes unsupported source with a custom-code node.

Project-file import adds a second, explicit lane: when semantic lowering rejects a function, the importer records the warning and compiles the selected project dependency closure into one content-addressed code.source-function node. Imports, helpers, decorators, stateful classes, side-effect imports, CommonJS modules, static local require()/import() calls, module initialization, loops, branches, exceptions, Array methods, and async/await retain their runtime behavior. Cyclic runtime imports and generators are rejected with precise diagnostics. Dynamic module specifiers in the selected fallback closure are rejected before materialization. Structured control statements are also indexed as nested editable source regions; they never become cyclic ordinary DAG edges. See TypeScript and JavaScript coverage.

Two-way orchestration sync requires every saved node to be reachable from one entry/Start node. Disconnected drafts are rejected before graph or generated-code artifacts change.

Supported forms:

  • named functions, function expressions, and arrow functions with identifier parameters;
  • statically named methods on an explicitly instantiated local class or class expression, addressed as <Class>.<method> workflows; constructors, inheritance, fields, and method bodies execute together in the source-function fallback;
  • class declarations and class expressions nested in static or instance fields, methods, constructors, accessors, static blocks, functions, and deeper classes. The index gives them stable qualified identities such as Outer.Inner and Outer.createInner.Local. An addressable nested class constructed explicitly as new Outer.Inner() can expose method workflows; method-local classes execute through their containing workflow because they have no module-level callable instance;
  • methods exposed by a local defineService({ create, expose, lifecycle }); only names in expose become callable workflows, and all methods route through one shared service host;
  • const name = expression, expression statements, and return expression;
  • identifiers, serializable constants, number/string/boolean literals, and parentheses;
  • binary arithmetic, comparison, and boolean operators only when their native node has the same JavaScript semantics; loose equality, short-circuit value operators, and ambiguous string + use the source-function lane;
  • console.log, info, warn, error, and debug with one argument;
  • calls to known source workflows, and the documented Promise combinators/chains.

Unsupported forms in the strict graph lane include destructuring, control flow, dynamic/computed dispatch, arbitrary property access, mutation, and unsupported expressions. Those forms use the source-function lane when their runtime closure can be compiled. Destructured parameters are represented as positional argN workflow inputs so their schema and adapter agree. Add a parser fixture and a semantic round-trip test before extending the strict lane.

Jest, Vitest, and Playwright files use the same source-preservation rule but a different visual projection. The workflow named after the test file represents module evaluation and the whole-file runner batch. Its Start owns the file's unique imports, then follows every executable top-level statement in source order. Direct tests and describe/suite workflows fan out in parallel; any later statement joins those branches before the file flow continues. Standalone helper declarations remain separate selectable workflows instead of becoming file-flow steps. Each describe Start branches in parallel to only its direct nested describe and test workflow references instead of flattening descendants upward. Each test workflow begins with Start Test (or Start Test Each for parameterized cases) and derives its ordered helper/service calls, mock operations, and runner-native expect assertions from the callback body. Playwright uses the same projection for test.describe, page calls, and expect. Named local functions, function-valued constants, and local classes are lexical helper workflows, and Studio can add a named helper with revision-safe source write-back. Helpers declared inside a test remain inside that test's source closure. Tests are independent workflow roots, so folder membership is never lowered into test-to-test control edges. Mocks, hooks, and typed fixture data remain runner-owned source constructs, with support editing available in the scope sidebar. Imported project type declarations seed the fixture editor: Form and JSON modes round-trip the same object and apply the same Zod validation before a revision-checked source edit.

On this page