You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .github/issue-proposals/apply-approach-1-function-injection.md
+13-17Lines changed: 13 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,8 +24,8 @@ This is the simplest possible design: no new abstractions, no DSL, and no framew
24
24
An apply script is a TypeScript file with one or more named function exports:
25
25
26
26
```ts
27
-
//repl/sold-pets.ts
28
-
importtype { ApplyContext } from"counterfact";
27
+
//scenarios/sold-pets.ts
28
+
importtype { ApplyContext } from"./types";
29
29
30
30
exportfunction soldPets($:ApplyContext) {
31
31
$.context.petService.reset();
@@ -38,6 +38,8 @@ export function soldPets($: ApplyContext) {
38
38
39
39
### The `ApplyContext` type
40
40
41
+
`ApplyContext` is a generated type that lives in `./types/`. In this first iteration it is always the same shape. In future iterations it will incorporate types from `_.context.ts` files, providing route-specific context types.
The argument to `.apply` is a slash-separated path. The last segment is the **function name** to call; everything before it is the **file path** (resolved relative to `<basePath>/repl/`, with `index.ts` as the default file):
58
+
The argument to `.apply` is a slash-separated path. The last segment is the **function name** to call; everything before it is the **file path** (resolved relative to `<basePath>/scenarios/`, with `index.ts` as the default file):
After execution, Counterfact compares the environment state before and after the script runs and prints a diff summary:
68
+
After execution, the REPL prints:
67
69
68
70
```
69
71
Applied sold-pets/soldPets
70
-
71
-
Routes added:
72
-
getSoldPets
73
72
```
74
73
75
-
Context diffs are not automatically tracked in this approach — the script author is responsible for noting any context changes in a comment or in the summary.
76
-
77
74
---
78
75
79
76
## Implementation sketch
@@ -82,7 +79,6 @@ Context diffs are not automatically tracked in this approach — the script auth
82
79
2. Split the argument on `/`: the last segment is the function name; the rest form the file path.
83
80
3. Dynamically import the resolved module (using `tsx` or the existing transpiler if the file is TypeScript).
84
81
4. Look up the named export matching the function name and call it with the live environment objects.
85
-
5. Snapshot `routes` before/after and print the diff.
86
82
87
83
---
88
84
@@ -100,11 +96,11 @@ Context diffs are not automatically tracked in this approach — the script auth
100
96
101
97
## Acceptance criteria
102
98
103
-
-[ ]`.apply foo` resolves `repl/index.ts` and calls the exported `foo` function
104
-
-[ ]`.apply foo/bar` resolves `repl/foo.ts` and calls the exported `bar` function
105
-
-[ ]`.apply foo/bar/baz` resolves `repl/foo/bar.ts` and calls the exported `baz` function
99
+
-[ ]`.apply foo` resolves `scenarios/index.ts` and calls the exported `foo` function
100
+
-[ ]`.apply foo/bar` resolves `scenarios/foo.ts` and calls the exported `bar` function
101
+
-[ ]`.apply foo/bar/baz` resolves `scenarios/foo/bar.ts` and calls the exported `baz` function
106
102
-[ ] The function receives `$` with `{ context, loadContext, routes, route }` as properties
107
103
-[ ] Routes injected by the script are available in the REPL after the command runs
108
-
-[ ] The REPL prints a summary of routes added and removed after each apply
104
+
-[ ] The REPL prints `Applied <path>`after each successful apply
109
105
-[ ] A meaningful error is shown when the file cannot be found or the export is not a function
110
106
-[ ] Existing REPL commands and behavior are unaffected
Copy file name to clipboardExpand all lines: docs/adr/001-apply-command-with-function-injection.md
+5-4Lines changed: 5 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -93,7 +93,8 @@ Identical surface syntax to Solution 1, but Counterfact wraps `context` and `rou
93
93
94
94
## Advice
95
95
96
-
-**Apply this decision** whenever a new scenario management capability is considered for the REPL. Start with a named function in a `.ts` file; reach for classes or proxy wrappers only when a concrete need for lifecycle or auto-tracking is demonstrated.
97
-
-**Revisit this decision** if the lack of teardown creates significant friction for users who need to reset state cleanly, or if the absence of automatic context diffing makes scripts hard to audit.
98
-
-**Prefer Solution 2 or 3** when: (a) scenarios need deterministic cleanup, (b) dependency ordering between scenarios must be enforced automatically, or (c) context mutation tracking is required for auditing or debugging.
99
-
-**Rule of thumb:** keep scripts as plain TypeScript. If you find yourself writing setup/teardown boilerplate repeatedly, that is the signal to revisit lifecycle support. If you find yourself commenting every context change for reviewers, that is the signal to revisit proxy-based diffing.
96
+
-**Apply this decision** whenever a new scenario management capability is considered for the REPL. Start with a named function in a `.ts` file; reach for classes or proxy wrappers only when a concrete need for lifecycle or auto-tracking is demonstrated. (Copilot/Claude)
97
+
-**Revisit this decision** if the lack of teardown creates significant friction for users who need to reset state cleanly, or if the absence of automatic context diffing makes scripts hard to audit. (Copilot/Claude)
98
+
-**Prefer Solution 2 or 3** when: (a) scenarios need deterministic cleanup, (b) dependency ordering between scenarios must be enforced automatically, or (c) context mutation tracking is required for auditing or debugging. (Copilot/Claude)
99
+
-**Rule of thumb:** keep scripts as plain TypeScript. If you find yourself writing setup/teardown boilerplate repeatedly, that is the signal to revisit lifecycle support. If you find yourself commenting every context change for reviewers, that is the signal to revisit proxy-based diffing. (Copilot/Claude)
100
+
-**A natural extension point is the return value of the function** (currently `void`). It could be an optional string used to summarize the changes made by the script. It could also return an object containing a `teardown()` function, providing a lightweight path to lifecycle support without requiring a full class interface. (@pmcelhaney)
0 commit comments