Files
feuerwerk/tests/editor/variable-choices.test.ts
T
adminandClaude Opus 5.5 0d8fd6ff52
feuerwerk / gate (push) Successful in 5m10s
feuerwerk / suite (push) Failing after 18m49s
Let the agent use the graph, scene and project commands (#429)
The agent knew 23 of the editor's commands. It could not point a
Variables node at a variable, group nodes, edit ports, transitions,
containers, colliders or the project settings. Stage 5a brings the
catalog to 85 commands in five areas and keeps every answer short.

- The catalog lists names and descriptions only. With a query (an
  area or command names) it adds the arguments. All schemas at once
  would pass the 60 000 character limit of one answer.
- add_port points a Variables node at a variable. The port takes the
  variable's kind, and an unknown name is refused with the list of
  the ones that exist.
- add_group and add_comment take nodes instead of coordinates. They
  follow the nodes after the arrange step, in the same undo step.
- The rule for which list a port picks from moved into portChoices.ts.
  Inspector and agent now share it.
- The frame of a group around nodes moved into annotationDrag.ts, so
  the button and the agent get the same frame.
- list_assets returns the project settings. get_asset shows the
  content of placed containers with the ids overrides need. get_graph
  shows declared ports and frame colors.
- A new node is placed at the height of its port, in the free spot
  whose links cross the fewest others. A source goes left of the node
  it feeds. Before, new nodes always went right of the rest.
- Arrange breaks a tie in crossings by putting the flow on top, and
  exec links pull harder when a column is sorted.
- A comment over a group keeps clear of the group's title bar.
- The agent's instructions and lint_graph ask to look at crossings
  too and to call arrange_graph when there are more than needed.

Left out on purpose: file assets (no upload), paste from the
clipboard, internal wrapper commands and switching plugins on.

Found on the way:
- Variable commands on a Struct asset did not run through
  WithStructTypes. New fields did not reach variables of that type.
- A query "variables" also matched set_variables_scope. A word that
  names an area now means only that area.

Tests:
- agent-catalog (new, 10), agent-edit, graph-arrange (3 new) and
  relay green. 11 bends of the code, all red.
- e2e 71 on atx: 22/22, the new check sees port speed and a group
  around all 4 drawn nodes.
- Live on a test project: a speed variable of 300 moved the player
  to x 150.03 in 0.5 s. A re-placed Variables node landed below Axis
  input with 4 crossings instead of 7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:01:15 +02:00

43 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* What `+ Variable` offers on a Variables node. The node's own setting decides: empty means the
* behavior it sits in, a Variables asset means that asset's declarations – which is the only way
* one graph reaches a value another graph writes.
*/
import { describe, expect, it } from 'vitest';
import { CreateAssetCommand } from '../../src/core/commands/assetCommands';
import { AddNodeCommand } from '../../src/core/commands/graphCommands';
import { AddVariableCommand } from '../../src/core/commands/variableCommands';
import { VARIABLES, VARIABLES_PARAM } from '../../src/core/graph';
import { variableChoices } from '../../src/editor/graph/portChoices';
import { makeBehavior, makeProject } from '../helpers';
describe('the variables a node offers', () => {
const scene = () => {
const f = makeProject();
const behavior = makeBehavior(f, 'Counter', ['own']);
const shared = new CreateAssetCommand('variables', 'Score');
f.stack.execute(shared);
f.stack.execute(new AddVariableCommand(shared.asset.id, 'score', 'number'));
const add = (source: string) => {
const command = new AddNodeCommand(behavior.id, VARIABLES, 0, 0, { [VARIABLES_PARAM]: source });
f.stack.execute(command);
return variableChoices(f.project, behavior.id, command.node).map((def) => def.key);
};
return { add, sharedId: shared.asset.id };
};
it('offers the behavior’s own when no asset is named', () => {
expect(scene().add('')).toEqual(['own']);
});
it('offers the asset’s declarations when one is named, and not the behavior’s', () => {
const { add, sharedId } = scene();
expect(add(sharedId)).toEqual(['score']);
});
/** Falling back to the behavior would offer names the node cannot reach at runtime. */
it('offers nothing when the named asset is gone', () => {
expect(scene().add('no-such-asset')).toEqual([]);
});
});