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.InnerandOuter.createInner.Local. An addressable nested class constructed explicitly asnew 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 inexposebecome callable workflows, and all methods route through one shared service host; const name = expression, expression statements, andreturn 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, anddebugwith one argument;- calls to known source workflows, and the documented
Promisecombinators/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.