human-to-code 0.1.13 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/Readme.md +21 -43
  2. package/SECURITY.md +16 -1
  3. package/dist/agents/direct/application.d.ts +10 -0
  4. package/dist/agents/direct/application.d.ts.map +1 -0
  5. package/dist/agents/direct/application.js +51 -0
  6. package/dist/agents/direct/application.js.map +1 -0
  7. package/dist/agents/direct/candidate-validation.d.ts +8 -0
  8. package/dist/agents/direct/candidate-validation.d.ts.map +1 -0
  9. package/dist/agents/direct/candidate-validation.js +125 -0
  10. package/dist/agents/direct/candidate-validation.js.map +1 -0
  11. package/dist/agents/direct/declarations.d.ts +3 -0
  12. package/dist/agents/direct/declarations.d.ts.map +1 -0
  13. package/dist/agents/direct/declarations.js +36 -0
  14. package/dist/agents/direct/declarations.js.map +1 -0
  15. package/dist/agents/direct/discovery.d.ts +6 -0
  16. package/dist/agents/direct/discovery.d.ts.map +1 -0
  17. package/dist/agents/direct/discovery.js +144 -0
  18. package/dist/agents/direct/discovery.js.map +1 -0
  19. package/dist/agents/direct/file-memory.d.ts +20 -0
  20. package/dist/agents/direct/file-memory.d.ts.map +1 -0
  21. package/dist/agents/direct/file-memory.js +170 -0
  22. package/dist/agents/direct/file-memory.js.map +1 -0
  23. package/dist/agents/direct/generation-client.d.ts +4 -0
  24. package/dist/agents/direct/generation-client.d.ts.map +1 -0
  25. package/dist/agents/direct/generation-client.js +56 -0
  26. package/dist/agents/direct/generation-client.js.map +1 -0
  27. package/dist/agents/direct/index.d.ts +13 -0
  28. package/dist/agents/direct/index.d.ts.map +1 -0
  29. package/dist/agents/direct/index.js +13 -0
  30. package/dist/agents/direct/index.js.map +1 -0
  31. package/dist/agents/direct/languages.d.ts +5 -0
  32. package/dist/agents/direct/languages.d.ts.map +1 -0
  33. package/dist/agents/direct/languages.js +17 -0
  34. package/dist/agents/direct/languages.js.map +1 -0
  35. package/dist/agents/direct/marker-parser.d.ts +8 -0
  36. package/dist/agents/direct/marker-parser.d.ts.map +1 -0
  37. package/dist/agents/direct/marker-parser.js +83 -0
  38. package/dist/agents/direct/marker-parser.js.map +1 -0
  39. package/dist/agents/direct/presentation.d.ts +7 -0
  40. package/dist/agents/direct/presentation.d.ts.map +1 -0
  41. package/dist/agents/direct/presentation.js +42 -0
  42. package/dist/agents/direct/presentation.js.map +1 -0
  43. package/dist/agents/direct/replacement.d.ts +10 -0
  44. package/dist/agents/direct/replacement.d.ts.map +1 -0
  45. package/dist/agents/direct/replacement.js +19 -0
  46. package/dist/agents/direct/replacement.js.map +1 -0
  47. package/dist/agents/direct/types.d.ts +87 -0
  48. package/dist/agents/direct/types.d.ts.map +1 -0
  49. package/dist/agents/direct/types.js +2 -0
  50. package/dist/agents/direct/types.js.map +1 -0
  51. package/dist/agents/guided/api-grounding.d.ts +6 -0
  52. package/dist/agents/guided/api-grounding.d.ts.map +1 -0
  53. package/dist/agents/guided/api-grounding.js +158 -0
  54. package/dist/agents/guided/api-grounding.js.map +1 -0
  55. package/dist/agents/guided/index.d.ts +7 -0
  56. package/dist/agents/guided/index.d.ts.map +1 -0
  57. package/dist/agents/guided/index.js +7 -0
  58. package/dist/agents/guided/index.js.map +1 -0
  59. package/dist/agents/guided/patch-diff.d.ts +4 -0
  60. package/dist/agents/guided/patch-diff.d.ts.map +1 -0
  61. package/dist/agents/guided/patch-diff.js +31 -0
  62. package/dist/agents/guided/patch-diff.js.map +1 -0
  63. package/dist/agents/guided/types.d.ts +55 -0
  64. package/dist/agents/guided/types.d.ts.map +1 -0
  65. package/dist/agents/guided/types.js +2 -0
  66. package/dist/agents/guided/types.js.map +1 -0
  67. package/dist/agents/guided/workflow.d.ts +17 -0
  68. package/dist/agents/guided/workflow.d.ts.map +1 -0
  69. package/dist/agents/guided/workflow.js +1360 -0
  70. package/dist/agents/guided/workflow.js.map +1 -0
  71. package/dist/agents/guided/workspace-policy.d.ts +9 -0
  72. package/dist/agents/guided/workspace-policy.d.ts.map +1 -0
  73. package/dist/agents/guided/workspace-policy.js +83 -0
  74. package/dist/agents/guided/workspace-policy.js.map +1 -0
  75. package/dist/cli.d.ts.map +1 -1
  76. package/dist/cli.js +22 -61
  77. package/dist/cli.js.map +1 -1
  78. package/dist/index.d.ts +3 -1
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +4 -1
  81. package/dist/index.js.map +1 -1
  82. package/dist/pipeline/file-memory.d.ts.map +1 -1
  83. package/dist/pipeline/file-memory.js +42 -1
  84. package/dist/pipeline/file-memory.js.map +1 -1
  85. package/dist/pipeline/simple.d.ts +3 -160
  86. package/dist/pipeline/simple.d.ts.map +1 -1
  87. package/dist/pipeline/simple.js +3 -502
  88. package/dist/pipeline/simple.js.map +1 -1
  89. package/dist/pipeline/workflow.d.ts +5 -66
  90. package/dist/pipeline/workflow.d.ts.map +1 -1
  91. package/dist/pipeline/workflow.js +5 -1642
  92. package/dist/pipeline/workflow.js.map +1 -1
  93. package/dist/prompts/direct-conversion.d.ts +13 -0
  94. package/dist/prompts/direct-conversion.d.ts.map +1 -0
  95. package/dist/prompts/direct-conversion.js +35 -0
  96. package/dist/prompts/direct-conversion.js.map +1 -0
  97. package/dist/prompts/guided-patch.d.ts +14 -0
  98. package/dist/prompts/guided-patch.d.ts.map +1 -0
  99. package/dist/prompts/guided-patch.js +41 -0
  100. package/dist/prompts/guided-patch.js.map +1 -0
  101. package/dist/prompts/guided-repair.d.ts +12 -0
  102. package/dist/prompts/guided-repair.d.ts.map +1 -0
  103. package/dist/prompts/guided-repair.js +30 -0
  104. package/dist/prompts/guided-repair.js.map +1 -0
  105. package/dist/prompts/index.d.ts +6 -0
  106. package/dist/prompts/index.d.ts.map +1 -0
  107. package/dist/prompts/index.js +6 -0
  108. package/dist/prompts/index.js.map +1 -0
  109. package/dist/prompts/provider-output.d.ts +4 -0
  110. package/dist/prompts/provider-output.d.ts.map +1 -0
  111. package/dist/prompts/provider-output.js +12 -0
  112. package/dist/prompts/provider-output.js.map +1 -0
  113. package/dist/providers/providers.d.ts.map +1 -1
  114. package/dist/providers/providers.js +2 -10
  115. package/dist/providers/providers.js.map +1 -1
  116. package/docs/ARCHITECTURE.md +42 -35
  117. package/docs/MODULES.md +51 -11
  118. package/docs/SCALABILITY.md +11 -9
  119. package/docs/roadmap/README.md +3 -2
  120. package/docs/roadmap/ruby.md +3 -4
  121. package/package.json +5 -8
  122. package/dist/pipeline/agent-tools.d.ts +0 -348
  123. package/dist/pipeline/agent-tools.d.ts.map +0 -1
  124. package/dist/pipeline/agent-tools.js +0 -542
  125. package/dist/pipeline/agent-tools.js.map +0 -1
  126. package/dist/pipeline/agent-tui.d.ts +0 -15
  127. package/dist/pipeline/agent-tui.d.ts.map +0 -1
  128. package/dist/pipeline/agent-tui.js +0 -133
  129. package/dist/pipeline/agent-tui.js.map +0 -1
  130. package/dist/pipeline/deep-agent.d.ts +0 -61
  131. package/dist/pipeline/deep-agent.d.ts.map +0 -1
  132. package/dist/pipeline/deep-agent.js +0 -395
  133. package/dist/pipeline/deep-agent.js.map +0 -1
package/Readme.md CHANGED
@@ -54,10 +54,12 @@ npx human-to-code .
54
54
  By default this runs the **direct converter**, not an instruction to rewrite the whole directory. It:
55
55
 
56
56
  1. Loads config and scans the project for `.human` files and inline `@human` markers, without importing application modules or executing project configuration.
57
- 2. Prints a receipt (language, provider, model, and the exact worklist) and asks for confirmation. Nothing is written until you confirm or pass `-y`/`--yes`. If no request is found it returns `NEEDS_INPUT`.
58
- 3. On confirmation, converts each item with one model completion per unit and writes the result: a whole `.human` file becomes a sibling source file; an inline `@human` marker is replaced in place. Each item is independent a failing one is skipped with a reason rather than aborting the rest.
57
+ 2. Reports marker-shaped requests in unsupported file types and refuses a `.human` request whose sibling output already exists. Intentionally ignored directories and symlinks remain outside discovery.
58
+ 3. Prints a receipt (language, provider, model, and the exact worklist) and asks for confirmation. Nothing is written until you confirm or pass `-y`/`--yes`. If no request is found it returns `NEEDS_INPUT`.
59
+ 4. On confirmation, converts each item with one model completion per unit, extracts one unambiguous code block, and validates the complete candidate before writing. JavaScript and TypeScript use the TypeScript parser; other supported languages receive a deterministic structural syntax check.
60
+ 5. Applies each accepted item defensively: new sibling files use exclusive creation, inline markers must still match the bytes found during discovery, and multi-line replacements inherit the marker's indentation. A failing or stale item is skipped with a reason rather than aborting the rest.
59
61
 
60
- The direct converter writes code straight to the working tree. It does **not** create a `.strict.human.json` change contract, run sandbox validation, produce a `VERIFIED` run, or perform the guided pipeline's repository-wide secret scan — only the indexed declarations it attaches to an inline prompt as context are secret-scanned (a finding is `SECURITY_BLOCKED`). For the reviewed contract → grounding → sandbox-validation lifecycle — where the `.strict.human.json` contract and the `VERIFIED`/`apply`/`rollback` machinery live — use `human-to-code guided` (see [The reviewed change contract](#the-reviewed-change-contract) and the [CLI](#cli) table).
62
+ The direct converter writes code straight to the working tree. Its syntax gate catches malformed output; it does **not** prove API correctness, run project builds or tests, execute code in a sandbox, create a `.strict.human.json` change contract, produce a `VERIFIED` run, or perform the guided pipeline's repository-wide secret scan — only the indexed declarations it attaches to an inline prompt as context are secret-scanned (a finding is `SECURITY_BLOCKED`). For the reviewed contract → grounding → sandbox-validation lifecycle — where the `.strict.human.json` contract and the `VERIFIED`/`apply`/`rollback` machinery live — use `human-to-code guided` (see [The reviewed change contract](#the-reviewed-change-contract) and the [CLI](#cli) table).
61
63
 
62
64
  No configured provider is needed to scan and preview. A default run selects loopback-local Ollama with `qwen2.5-coder:7b`, so a fresh `npx human-to-code .` never transmits code remotely by default. The model must already be installed; the tool never pulls it implicitly. To use another local model, OpenAI, or Ollama Cloud, create and edit a config (the command never overwrites one):
63
65
 
@@ -99,13 +101,20 @@ node dist/cli.js .
99
101
 
100
102
  Node.js 24 or newer is required.
101
103
 
102
- ## Generation engines
104
+ ## Generation engine
103
105
 
104
106
  The direct `npx human-to-code .` flow discovers work (whole `.human` files and
105
107
  inline `@human` markers), prints a receipt, and — after you confirm — converts
106
- it. Two engines are available.
108
+ them with the deterministic direct engine.
107
109
 
108
- ### Default: fast deterministic engine
110
+ Inline discovery currently supports `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`,
111
+ `.cjs`, `.py`, `.rs`, `.go`, `.java`, `.rb`, `.cs`, `.cpp`, `.cc`, `.c`, `.h`,
112
+ and `.hpp`. A marker-shaped `@human` request in another regular file up to
113
+ 1 MiB is reported as unsupported. Ignored/dot directories and symlinks are
114
+ intentionally excluded from the direct walk; oversized unsupported files are
115
+ not opened merely to produce a notice.
116
+
117
+ ### Fast deterministic engine
109
118
 
110
119
  The host does the orchestration; the model only writes code. For each unit the
111
120
  host issues **one plain model completion** (no tool calls) and applies the
@@ -119,7 +128,11 @@ tool-calling, models that can only do plain text generation work fine.
119
128
  the other markers still convert. One failure never aborts the run.
120
129
  - **FileMemory** — declarations already in the file are shown to the model as
121
130
  read-only context (with few-shot examples) so it reuses rather than
122
- re-declares them.
131
+ re-declares them. Its static scanner understands JavaScript regex literals,
132
+ and the redeclaration guard covers type-led C, C++, C#, and Java forms.
133
+ - **Candidate and write guards** — ambiguous fenced responses and malformed
134
+ candidates are retried; existing sibling files, stale inline markers, and
135
+ unsafe indentation changes are refused before mutation.
123
136
  - **Clear, stable output** — a single truncated status line per marker
124
137
  (`✓ app.ts (inline @human, line 12)` / `⊘ skipped … : <reason>`), plus an
125
138
  in-place elapsed spinner while a completion is in flight.
@@ -127,43 +140,9 @@ tool-calling, models that can only do plain text generation work fine.
127
140
  This engine cannot produce `VERIFIED` runs; for the reviewed, sandbox-validated
128
141
  pipeline use `human-to-code guided`.
129
142
 
130
- ### `--agent`: LangGraph deep agent
131
-
132
- `--agent` runs a LangChain/LangGraph agent with an explicit coding-tool surface:
133
- `Task`, `Bash`, `Glob`, `Grep`,
134
- `LS`, `ExitPlanMode`, `Read`, `Edit`, `MultiEdit`, `Write`, `NotebookEdit`,
135
- `WebFetch`, `TodoWrite`, `WebSearch`, `BashOutput`, and `KillBash`. File tools
136
- are project-confined, reads are required before edits, protected paths are
137
- denied, multi-edits are atomic, shell output is bounded, and secret-bearing
138
- environment variables are removed from commands.
139
-
140
- In an interactive terminal, agent mode uses a two-column dashboard: the current
141
- todo list stays on the left while tool calls, command output, and git-style
142
- green `+` / red `-` file changes stream on the right. Non-TTY and `--json`
143
- usage remains line-oriented and machine-readable.
144
-
145
- The agent prompt includes concrete JSON tool-call examples intended to help
146
- very small models, including 0.8B-class models. Model size is not treated as a
147
- capability guarantee: the model must reliably support structured tool calling.
148
- If a model repeats the same call four times, claims completion without changing
149
- every worklist item, or reaches the bounded graph step limit, the run stops with
150
- a concise incomplete result instead of continuing to the framework recursion
151
- error. When the host observes that every discovered item is implemented, it
152
- stops the graph even if the model forgets to provide a final response.
153
-
154
- The engine is reached through the OpenAI-compatible chat client (Ollama via its
155
- `/v1` endpoint). Its `Bash` tool executes development commands on the host from
156
- the project root; it is bounded and guarded but is not a strong sandbox. Use
157
- the guided pipeline when hash-bound patches and container validation are
158
- required. Agent mode pulls the runtime dependencies `langchain`,
159
- `@langchain/core`, and `@langchain/openai`.
160
-
161
143
  ```bash
162
- # Fast deterministic engine (default) — works with small models:
144
+ # Deterministic engine — works with small models:
163
145
  npx human-to-code . --yes --model qwen2.5-coder:1.5b
164
-
165
- # Agent dashboard — needs reliable JSON tool calling:
166
- npx human-to-code . --yes --agent --model qwen2.5-coder:7b
167
146
  ```
168
147
 
169
148
  ## The reviewed change contract
@@ -185,7 +164,6 @@ The draft is deliberately conservative. Do not remove its review question until
185
164
  | Command | Behavior |
186
165
  | --- | --- |
187
166
  | `human-to-code [root]` | Default direct flow: discover `.human` files and `@human` markers, show a receipt, and on confirmation convert them with the **fast deterministic engine** (one plain model completion per marker; see below). `npx human-to-code .` is the normal entry point. |
188
- | `human-to-code [root] --agent` | Same direct flow using the tool-rich **LangGraph agent dashboard** (todos, filesystem, shell, diffs, and subagents). Needs reliable structured tool calling; model size alone is not a capability guarantee. |
189
167
  | `human-to-code guided [root]` | Reviewed contract → grounding → sandbox-validation lifecycle. The only path that can reach `VERIFIED`. |
190
168
  | `human-to-code analyze [root] [--json]` | Produce a deterministic multi-workspace project profile and diagnostics. `SUPPORTED` means statically recognized, not certified. |
191
169
  | `human-to-code plan <file.human> [--root <root>]` | Write a review-blocked `ChangeContractV1` draft. |
package/SECURITY.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  `human-to-code` reads attacker-controlled repositories, sends selected evidence to an LLM provider, and may execute project validation commands. The project therefore treats repository content, model output, documentation, provider endpoints, and build/test tooling as untrusted.
4
4
 
5
- Version `0.1.0` is a preview. The shipped ecosystem and provider/model combinations are not certified, so generated runs do not reach `VERIFIED` through the CLI and automatic application/rollback remain unreachable for normal generated runs. Do not weaken that boundary to make a preview run appear successful.
5
+ Version `0.1.15` is a preview. The shipped ecosystem and provider/model combinations are not certified, so guided generated runs do not reach `VERIFIED` through the CLI and guided automatic application/rollback remain unreachable for normal generated runs. The default direct converter is a separate convenience path that writes accepted units to the working tree after confirmation; it never claims `VERIFIED`. Do not weaken either boundary to make a preview run appear successful.
6
6
 
7
7
  ## Trust boundaries
8
8
 
@@ -24,6 +24,21 @@ The analyzer reads bounded regular files and statically recognizes React, NestJS
24
24
 
25
25
  Unreadable roots, non-directories, symlinked roots, scan truncation, conflicting project managers, multiple plausible targets, or unsupported dynamic metadata must return a non-success status. An empty or partial scan must never look like a supported project.
26
26
 
27
+ ### Direct conversion has guarded writes, not sandbox verification
28
+
29
+ The direct converter treats model text as untrusted before writing: it accepts
30
+ at most one unambiguous fenced code block, validates the complete candidate's
31
+ syntax/structure, refuses existing sibling targets using both discovery checks
32
+ and exclusive creation, verifies exact inline marker bytes again at apply time,
33
+ and preserves marker indentation. Invalid or stale units are retried within the
34
+ bounded generation policy and then skipped without mutation.
35
+
36
+ These controls prevent the specific malformed-output, overwrite, stale-range,
37
+ and indentation failures they check. They do not prove external APIs, types,
38
+ project-wide behavior, security properties, or test success, and they do not
39
+ execute the candidate in a sandbox. Use the guided contract and validation path
40
+ when those stronger boundaries are required.
41
+
27
42
  ### The reviewed contract owns authority
28
43
 
29
44
  The model cannot choose its own target, allowed files, operations, acceptance criteria, validation commands, or elevated risks. A `ChangeContractV1` is bound to the `.human` source hash and static project fingerprint. Material unresolved questions block generation.
@@ -0,0 +1,10 @@
1
+ import { dirname } from "node:path";
2
+ import type { ConversionUnit } from "./types.ts";
3
+ export declare class DirectApplicationError extends Error {
4
+ constructor(message: string);
5
+ }
6
+ /** Apply one already-generated unit and return the project-relative path changed. */
7
+ export declare function applyUnit(root: string, unit: ConversionUnit, code: string): Promise<string>;
8
+ export declare function pathExists(target: string): Promise<boolean>;
9
+ export { dirname };
10
+ //# sourceMappingURL=application.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../../src/agents/direct/application.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAgB,MAAM,WAAW,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED,qFAAqF;AACrF,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BjG;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOjE;AAED,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { readFile, stat, writeFile } from "node:fs/promises";
2
+ import { dirname, resolve, sep } from "node:path";
3
+ import { replaceInlineMarker } from "./replacement.js";
4
+ export class DirectApplicationError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "DirectApplicationError";
8
+ }
9
+ }
10
+ /** Apply one already-generated unit and return the project-relative path changed. */
11
+ export async function applyUnit(root, unit, code) {
12
+ const absoluteRoot = resolve(root);
13
+ if (unit.kind === "file") {
14
+ const target = resolve(absoluteRoot, unit.outputPath);
15
+ if (!target.startsWith(absoluteRoot + sep)) {
16
+ throw new Error(`Refusing to write outside the project root: ${unit.outputPath}`);
17
+ }
18
+ try {
19
+ await writeFile(target, code.endsWith("\n") ? code : `${code}\n`, { flag: "wx" });
20
+ }
21
+ catch (error) {
22
+ if (error.code === "EEXIST") {
23
+ throw new DirectApplicationError(`Refusing to overwrite existing generated target: ${unit.outputPath}`);
24
+ }
25
+ throw error;
26
+ }
27
+ return unit.outputPath;
28
+ }
29
+ const original = await readFile(unit.absoluteSource, "utf8");
30
+ const { start, end } = unit.range;
31
+ let replaced;
32
+ try {
33
+ replaced = replaceInlineMarker(original, { start, end }, unit.expectedMarker, code);
34
+ }
35
+ catch (error) {
36
+ throw new DirectApplicationError(`${unit.sourcePath}: ${error instanceof Error ? error.message : String(error)}`);
37
+ }
38
+ await writeFile(unit.absoluteSource, replaced);
39
+ return unit.sourcePath;
40
+ }
41
+ export async function pathExists(target) {
42
+ try {
43
+ await stat(target);
44
+ return true;
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
50
+ export { dirname };
51
+ //# sourceMappingURL=application.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application.js","sourceRoot":"","sources":["../../../src/agents/direct/application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGvD,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,IAAoB,EAAE,IAAY;IAC9E,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,UAAW,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,GAAG,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,+CAA+C,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACpF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,IAAI,sBAAsB,CAAC,oDAAoD,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAC1G,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC,UAAW,CAAC;IAC1B,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC7D,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,KAAM,CAAC;IACnC,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,mBAAmB,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IACtF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,sBAAsB,CAC9B,GAAG,IAAI,CAAC,UAAU,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAChF,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC,UAAU,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc;IAC7C,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ConversionUnit } from "./types.ts";
2
+ export declare class DirectCandidateValidationError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare function candidateTextForUnit(unit: ConversionUnit, code: string): Promise<string>;
6
+ /** Validate the complete candidate file before any direct-agent write occurs. */
7
+ export declare function validateGeneratedUnit(unit: ConversionUnit, code: string): Promise<void>;
8
+ //# sourceMappingURL=candidate-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidate-validation.d.ts","sourceRoot":"","sources":["../../../src/agents/direct/candidate-validation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,qBAAa,8BAA+B,SAAQ,KAAK;gBAC3C,OAAO,EAAE,MAAM;CAI5B;AA4FD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI9F;AAED,iFAAiF;AACjF,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS7F"}
@@ -0,0 +1,125 @@
1
+ /** Pre-write direct-candidate syntax checks; this is not semantic or sandbox verification. */
2
+ import { readFile } from "node:fs/promises";
3
+ import { extname } from "node:path";
4
+ import ts from "typescript";
5
+ import { replaceInlineMarker } from "./replacement.js";
6
+ export class DirectCandidateValidationError extends Error {
7
+ constructor(message) {
8
+ super(message);
9
+ this.name = "DirectCandidateValidationError";
10
+ }
11
+ }
12
+ const TYPESCRIPT_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
13
+ function validateBalancedSyntax(text, sourcePath) {
14
+ const stack = [];
15
+ let quote;
16
+ let triple;
17
+ let blockComment = false;
18
+ let escaped = false;
19
+ const extension = extname(sourcePath).toLowerCase();
20
+ const hashComments = extension === ".py" || extension === ".rb";
21
+ for (let index = 0; index < text.length; index += 1) {
22
+ const char = text[index];
23
+ const next = text[index + 1];
24
+ if (blockComment) {
25
+ if (char === "*" && next === "/") {
26
+ blockComment = false;
27
+ index += 1;
28
+ }
29
+ continue;
30
+ }
31
+ if (triple) {
32
+ if (text.startsWith(triple, index)) {
33
+ index += 2;
34
+ triple = undefined;
35
+ }
36
+ continue;
37
+ }
38
+ if (quote) {
39
+ if (escaped)
40
+ escaped = false;
41
+ else if (char === "\\")
42
+ escaped = true;
43
+ else if (char === quote)
44
+ quote = undefined;
45
+ continue;
46
+ }
47
+ if (char === "/" && next === "*") {
48
+ blockComment = true;
49
+ index += 1;
50
+ continue;
51
+ }
52
+ if (char === "/" && next === "/") {
53
+ index = text.indexOf("\n", index + 2);
54
+ if (index === -1)
55
+ break;
56
+ continue;
57
+ }
58
+ if (hashComments && char === "#") {
59
+ index = text.indexOf("\n", index + 1);
60
+ if (index === -1)
61
+ break;
62
+ continue;
63
+ }
64
+ if (extension === ".py" && (text.startsWith("'''", index) || text.startsWith('"""', index))) {
65
+ triple = text.startsWith("'''", index) ? "'''" : '"""';
66
+ index += 2;
67
+ continue;
68
+ }
69
+ if (char === "'" || char === '"' || char === "`") {
70
+ quote = char;
71
+ continue;
72
+ }
73
+ if (char === "(" || char === "[" || char === "{")
74
+ stack.push(char);
75
+ else if (char === ")" || char === "]" || char === "}") {
76
+ const expected = char === ")" ? "(" : char === "]" ? "[" : "{";
77
+ if (stack.pop() !== expected) {
78
+ throw new DirectCandidateValidationError(`${sourcePath}: generated candidate has mismatched delimiters.`);
79
+ }
80
+ }
81
+ }
82
+ if (quote || triple || blockComment || stack.length > 0) {
83
+ throw new DirectCandidateValidationError(`${sourcePath}: generated candidate has an unterminated string, comment, or delimiter.`);
84
+ }
85
+ }
86
+ function validateTypeScriptSyntax(text, sourcePath) {
87
+ const extension = extname(sourcePath).toLowerCase();
88
+ const jsx = extension === ".tsx" || extension === ".jsx";
89
+ const result = ts.transpileModule(text, {
90
+ fileName: sourcePath,
91
+ reportDiagnostics: true,
92
+ compilerOptions: {
93
+ target: ts.ScriptTarget.ES2023,
94
+ module: ts.ModuleKind.ESNext,
95
+ ...(jsx ? { jsx: ts.JsxEmit.Preserve } : {}),
96
+ allowJs: true,
97
+ },
98
+ });
99
+ const error = result.diagnostics?.find((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error);
100
+ if (error) {
101
+ const message = ts.flattenDiagnosticMessageText(error.messageText, " ");
102
+ throw new DirectCandidateValidationError(`${sourcePath}: generated candidate failed syntax validation: ${message}`);
103
+ }
104
+ }
105
+ export async function candidateTextForUnit(unit, code) {
106
+ if (unit.kind === "file")
107
+ return code.endsWith("\n") ? code : `${code}\n`;
108
+ const source = await readFile(unit.absoluteSource, "utf8");
109
+ return replaceInlineMarker(source, unit.range, unit.expectedMarker, code);
110
+ }
111
+ /** Validate the complete candidate file before any direct-agent write occurs. */
112
+ export async function validateGeneratedUnit(unit, code) {
113
+ if (code.trim().length === 0)
114
+ throw new DirectCandidateValidationError(`${unit.sourcePath}: model returned no code.`);
115
+ if (/```/u.test(code)) {
116
+ throw new DirectCandidateValidationError(`${unit.sourcePath}: model formatting remained in generated source.`);
117
+ }
118
+ const sourcePath = unit.kind === "file" ? unit.outputPath : unit.sourcePath;
119
+ const candidate = await candidateTextForUnit(unit, code);
120
+ if (TYPESCRIPT_EXTENSIONS.has(extname(sourcePath).toLowerCase()))
121
+ validateTypeScriptSyntax(candidate, sourcePath);
122
+ else
123
+ validateBalancedSyntax(candidate, sourcePath);
124
+ }
125
+ //# sourceMappingURL=candidate-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidate-validation.js","sourceRoot":"","sources":["../../../src/agents/direct/candidate-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Extract declared names for FileMemory conflict detection across supported languages. */
2
+ export declare function declaredIdentifiers(sourcePath: string, code: string): Set<string>;
3
+ //# sourceMappingURL=declarations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declarations.d.ts","sourceRoot":"","sources":["../../../src/agents/direct/declarations.ts"],"names":[],"mappings":"AAMA,2FAA2F;AAC3F,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA2BjF"}
@@ -0,0 +1,36 @@
1
+ /** Language-aware declaration names used by the direct FileMemory conflict guard. */
2
+ import { extname } from "node:path";
3
+ const TYPED_C_EXTENSIONS = new Set([".c", ".cc", ".cpp", ".h", ".hpp", ".cs", ".java"]);
4
+ const CONTROL_WORDS = new Set(["if", "for", "foreach", "while", "switch", "catch", "return", "throw", "new"]);
5
+ /** Extract declared names for FileMemory conflict detection across supported languages. */
6
+ export function declaredIdentifiers(sourcePath, code) {
7
+ const identifiers = new Set();
8
+ const keywordDeclaration = /^[ \t]*(?:(?:export|default|declare|public|private|protected|async|pub)\s+)*(?:const|let|var|function|class|interface|enum|struct|trait|fn|def|static|type)\s+([A-Za-z_$][A-Za-z0-9_$]*)/gmu;
9
+ for (const match of code.matchAll(keywordDeclaration)) {
10
+ if (match[1])
11
+ identifiers.add(match[1]);
12
+ }
13
+ if (!TYPED_C_EXTENSIONS.has(extname(sourcePath).toLowerCase()))
14
+ return identifiers;
15
+ for (const rawLine of code.split(/\r?\n/u)) {
16
+ const line = rawLine
17
+ .trim()
18
+ .replace(/^(?:\[[^\]]+\]\s*)+/u, "")
19
+ .replace(/^(?:(?:public|private|protected|internal|static|final|abstract|virtual|override|sealed|extern|async|inline|constexpr|consteval|constinit|volatile|mutable|friend|typedef|partial|unsafe|readonly)\s+)*/u, "");
20
+ const namedType = /^(?:class|interface|enum|record|struct|union|namespace)\s+([A-Za-z_$][A-Za-z0-9_$]*)/u.exec(line);
21
+ if (namedType?.[1]) {
22
+ identifiers.add(namedType[1]);
23
+ continue;
24
+ }
25
+ const functionName = /^[A-Za-z_][A-Za-z0-9_:<>,.?*\[\]&\s]+\s+([A-Za-z_$][A-Za-z0-9_$]*)\s*\(/u.exec(line)?.[1];
26
+ if (functionName && !CONTROL_WORDS.has(functionName)) {
27
+ identifiers.add(functionName);
28
+ continue;
29
+ }
30
+ const variableName = /^[A-Za-z_][A-Za-z0-9_:<>,.?*\[\]&\s]+\s+([A-Za-z_$][A-Za-z0-9_$]*)\s*(?:=|;|\{)/u.exec(line)?.[1];
31
+ if (variableName && !CONTROL_WORDS.has(variableName))
32
+ identifiers.add(variableName);
33
+ }
34
+ return identifiers;
35
+ }
36
+ //# sourceMappingURL=declarations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declarations.js","sourceRoot":"","sources":["../../../src/agents/direct/declarations.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AACxF,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAE9G,2FAA2F;AAC3F,MAAM,UAAU,mBAAmB,CAAC,UAAkB,EAAE,IAAY;IAClE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,MAAM,kBAAkB,GAAG,6LAA6L,CAAC;IACzN,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACtD,IAAI,KAAK,CAAC,CAAC,CAAC;YAAE,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;QAAE,OAAO,WAAW,CAAC;IACnF,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,OAAO;aACjB,IAAI,EAAE;aACN,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC;aACnC,OAAO,CAAC,yMAAyM,EAAE,EAAE,CAAC,CAAC;QAC1N,MAAM,SAAS,GAAG,uFAAuF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrH,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnB,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,SAAS;QACX,CAAC;QACD,MAAM,YAAY,GAAG,0EAA0E,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAChH,IAAI,YAAY,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;YACrD,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC9B,SAAS;QACX,CAAC;QACD,MAAM,YAAY,GAAG,kFAAkF,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxH,IAAI,YAAY,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC;YAAE,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { ConversionUnit, DirectDiscoveryResult } from "./types.ts";
2
+ /** Discover units plus actionable notices for marker text that cannot run safely. */
3
+ export declare function discoverDirectUnits(root: string, language: string): Promise<DirectDiscoveryResult>;
4
+ /** Compatibility helper returning only runnable units. */
5
+ export declare function discoverUnits(root: string, language: string): Promise<ConversionUnit[]>;
6
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/agents/direct/discovery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAmCxE,qFAAqF;AACrF,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAwFxG;AAED,0DAA0D;AAC1D,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAE7F"}
@@ -0,0 +1,144 @@
1
+ import { readdir, readFile, stat } from "node:fs/promises";
2
+ import { basename, extname, join, relative, resolve, sep } from "node:path";
3
+ import { languageProfile } from "./languages.js";
4
+ import { extractInlineMarkers } from "./marker-parser.js";
5
+ const SCANNED_EXTENSIONS = new Set([
6
+ ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs",
7
+ ".py", ".rs", ".go", ".java", ".rb", ".cs", ".cpp", ".cc", ".c", ".h", ".hpp",
8
+ ]);
9
+ const DEFAULT_IGNORES = new Set([
10
+ "node_modules", ".git", "dist", "build", ".next", "target", ".venv", "venv",
11
+ "coverage", ".human-to-code",
12
+ ]);
13
+ async function walk(root, ignores) {
14
+ const results = [];
15
+ const visit = async (dir, depth) => {
16
+ if (depth > 40)
17
+ return;
18
+ let entries;
19
+ try {
20
+ entries = await readdir(dir, { withFileTypes: true });
21
+ }
22
+ catch {
23
+ return;
24
+ }
25
+ for (const entry of entries) {
26
+ if (entry.name.startsWith(".") && entry.name !== ".human-to-code" && entry.isDirectory())
27
+ continue;
28
+ if (ignores.has(entry.name))
29
+ continue;
30
+ const full = join(dir, entry.name);
31
+ if (entry.isSymbolicLink())
32
+ continue;
33
+ if (entry.isDirectory())
34
+ await visit(full, depth + 1);
35
+ else if (entry.isFile())
36
+ results.push(full);
37
+ }
38
+ };
39
+ await visit(root, 0);
40
+ return results.sort();
41
+ }
42
+ /** Discover units plus actionable notices for marker text that cannot run safely. */
43
+ export async function discoverDirectUnits(root, language) {
44
+ const absoluteRoot = resolve(root);
45
+ const profile = languageProfile(language);
46
+ const files = await walk(absoluteRoot, DEFAULT_IGNORES);
47
+ const units = [];
48
+ const notices = [];
49
+ for (const absolute of files) {
50
+ const rel = relative(absoluteRoot, absolute).split(sep).join("/");
51
+ const name = basename(absolute);
52
+ if (name.endsWith(".strict.human"))
53
+ continue;
54
+ if (name.endsWith(".human")) {
55
+ let content;
56
+ try {
57
+ content = await readFile(absolute, "utf8");
58
+ }
59
+ catch {
60
+ continue;
61
+ }
62
+ const prompt = content.trim();
63
+ if (prompt.length === 0)
64
+ continue;
65
+ const outputPath = `${rel.slice(0, -".human".length)}.${profile.ext}`;
66
+ try {
67
+ await stat(join(absoluteRoot, ...outputPath.split("/")));
68
+ notices.push({
69
+ code: "TARGET_EXISTS",
70
+ sourcePath: rel,
71
+ message: `${rel} was skipped because ${outputPath} already exists; existing files are never overwritten.`,
72
+ });
73
+ continue;
74
+ }
75
+ catch (error) {
76
+ if (error.code !== "ENOENT")
77
+ throw error;
78
+ }
79
+ units.push({
80
+ kind: "file",
81
+ sourcePath: rel,
82
+ absoluteSource: absolute,
83
+ prompt,
84
+ outputPath,
85
+ describe: `${rel} -> ${outputPath}`,
86
+ });
87
+ continue;
88
+ }
89
+ if (!SCANNED_EXTENSIONS.has(extname(absolute).toLowerCase())) {
90
+ let info;
91
+ try {
92
+ info = await stat(absolute);
93
+ }
94
+ catch {
95
+ continue;
96
+ }
97
+ if (info.size > 1024 * 1024)
98
+ continue;
99
+ let unsupportedContent;
100
+ try {
101
+ unsupportedContent = await readFile(absolute, "utf8");
102
+ }
103
+ catch {
104
+ continue;
105
+ }
106
+ if (unsupportedContent.includes("@human")) {
107
+ notices.push({
108
+ code: "UNSUPPORTED_MARKER_FILE",
109
+ sourcePath: rel,
110
+ message: `${rel} contains @human text but ${extname(absolute) || "extensionless files"} is not supported for inline conversion.`,
111
+ });
112
+ }
113
+ continue;
114
+ }
115
+ let content;
116
+ try {
117
+ content = await readFile(absolute, "utf8");
118
+ }
119
+ catch {
120
+ continue;
121
+ }
122
+ if (!content.includes("@human"))
123
+ continue;
124
+ for (const marker of extractInlineMarkers(content)) {
125
+ const line = content.slice(0, marker.start).split("\n").length;
126
+ units.push({
127
+ kind: "inline",
128
+ sourcePath: rel,
129
+ absoluteSource: absolute,
130
+ prompt: marker.prompt,
131
+ range: { start: marker.start, end: marker.end },
132
+ expectedMarker: content.slice(marker.start, marker.end),
133
+ line,
134
+ describe: `${rel} (inline @human, line ${line}) -> ${rel}`,
135
+ });
136
+ }
137
+ }
138
+ return { units, notices };
139
+ }
140
+ /** Compatibility helper returning only runnable units. */
141
+ export async function discoverUnits(root, language) {
142
+ return (await discoverDirectUnits(root, language)).units;
143
+ }
144
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/agents/direct/discovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { ConversionUnit, FileMemoryEntry, GeneratedConversionUnit, GenerateUnitsOptions, UnitGenerationContext } from "./types.ts";
2
+ export declare class FileMemoryConflictError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ /** Ephemeral declaration memory shared by markers in one source file. */
6
+ export declare class FileMemory {
7
+ #private;
8
+ readonly sourcePath: string;
9
+ constructor(sourcePath: string, sourceText: string);
10
+ get entries(): readonly FileMemoryEntry[];
11
+ rememberReplacement(range: {
12
+ start: number;
13
+ end: number;
14
+ }, code: string): void;
15
+ render(): string;
16
+ normalizeReplacement(code: string): string;
17
+ }
18
+ /** Generate each unit without mutating source files. */
19
+ export declare function generateConversionUnits(units: readonly ConversionUnit[], generator: (unit: ConversionUnit, context: UnitGenerationContext) => Promise<string>, options?: GenerateUnitsOptions): Promise<GeneratedConversionUnit[]>;
20
+ //# sourceMappingURL=file-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-memory.d.ts","sourceRoot":"","sources":["../../../src/agents/direct/file-memory.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,EAAE,MAAM;CAI5B;AAeD,yEAAyE;AACzE,qBAAa,UAAU;;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAMhB,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAMlD,IAAI,OAAO,IAAI,SAAS,eAAe,EAAE,CAWxC;IAED,mBAAmB,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAqB9E,MAAM,IAAI,MAAM;IAchB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAkC3C;AAED,wDAAwD;AACxD,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,SAAS,cAAc,EAAE,EAChC,SAAS,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,qBAAqB,KAAK,OAAO,CAAC,MAAM,CAAC,EACpF,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAqDpC"}