@llm4ts/shell 2.36.0 → 2.37.0

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.
@@ -26,9 +26,10 @@ another pair copies one of these and replaces the rulebook, the pitfall card,
26
26
  `target:`, the diagnostics command, the ledger regex and the two test
27
27
  commands.
28
28
 
29
- | Pack | Source → target | Diagnostics | Ledger units |
30
- | ---------- | ------------------------------- | ----------------------------------- | ------------------------ |
31
- | `zig-rust` | Zig → Rust | `cargo check --message-format=json` | pointer and slice fields |
32
- | `scala-ts` | Scala 3 / ZIO 2 → TS / Effect 4 | `tsc --pretty false` | classes, objects, traits |
29
+ | Pack | Source → target | Diagnostics | Ledger units |
30
+ | ----------------------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------- | --------------------------------- |
31
+ | `zig-rust` | Zig → Rust | `cargo check --message-format=json` | pointer and slice fields |
32
+ | `scala-ts` | Scala 3 / ZIO 2 → TS / Effect 4 | `tsc --pretty false` | classes, objects, traits |
33
+ | `cobol-springboot-port` | COBOL → Java / Spring Boot 3 (file by file; the clean-room sibling is `mainframe-java/cobol-springboot`) | `mvn -q -B -DskipTests compile` (javac) | level-01 records, FDs, paragraphs |
33
34
 
34
35
  `## Diagnostics` reads `json` (one object per line), `cargo` (`--message-format=json`), `tsc` (`--pretty false`) or `javac` (javac's and Maven's error lines, the Maven module as the unit).
@@ -0,0 +1,48 @@
1
+ # Pack: cobol-springboot-port
2
+
3
+ source: cobol
4
+ sources: .*\.(cbl|cob|cpy|CBL|COB|CPY)$
5
+ exclude: (^|/)(target|build|\.git|node_modules)/
6
+ target: src/main/java/legacy/{{dir}}/{{base}}.java
7
+ comment: //
8
+ specs-dir: docs/port
9
+ features-dir: docs/port/features
10
+
11
+ ## Gates
12
+
13
+ - compile: mvn -q -B -DskipTests compile
14
+ - test: mvn -q -B test
15
+
16
+ ## Diagnostics
17
+
18
+ - command: mvn -q -B -DskipTests compile
19
+ - format: javac
20
+
21
+ ## Ledger
22
+
23
+ - unit: ^\s{0,7}(?:01|77)\s+([A-Z][A-Z0-9-]*)|^\s{0,7}FD\s+([A-Z][A-Z0-9-]*)|^\s{0,7}([A-Z0-9][A-Z0-9-]*)\s*(?:SECTION)?\.\s*$
24
+ - classes: RECORD, FILE, PARAGRAPH, SQL, CICS, COPYBOOK, REPORT, UTIL, UNKNOWN
25
+ - question: What does this COBOL unit become in a Spring Boot port? RECORD (a level-01 or 77 data item → a Java record or class with BigDecimal for numerics), FILE (an FD / SELECT → a JPA entity with a Spring Data repository, or a reader for a flat file), PARAGRAPH (a paragraph or section → a private method on the program's @Service), SQL (a paragraph whose body is EXEC SQL → a repository query), CICS (EXEC CICS send/receive → a controller endpoint or a service boundary), COPYBOOK (a shared record → a class in the copybook package, ported once), REPORT (a print layout → a formatter), UTIL (a pure routine).
26
+
27
+ ## Differential
28
+
29
+ - tests: ^tests/.*\.(txt|dat|json)$
30
+ - legacy: scripts/legacy-run.sh {{file}}
31
+ - target: scripts/target-run.sh {{file}}
32
+ - timeout: 120
33
+
34
+ ## Audit
35
+
36
+ - dimensions: data division and record layouts, PIC clauses and numeric semantics, files and embedded SQL, control flow (PERFORM, GO TO, fall-through), copybooks and shared records, batch versus online (CICS), transaction boundaries, test idioms, what not to translate
37
+
38
+ ## Review rules
39
+
40
+ A `double` or `float` holding money, a quantity or any `COMP-3` field is a
41
+ finding: numerics are `BigDecimal` with the PIC's scale, or `long` for
42
+ unsigned integer PICs. A `MOVE` whose truncation or padding the source relied
43
+ on must be written out, not assumed. `GO TO` is flattened into structured
44
+ control flow with a `// PORTED: GO TO` note, never a `while (true)` with a
45
+ state variable unless the source was a state machine. Every file and SQL
46
+ access sits behind a Spring Data repository or a dedicated reader; every
47
+ program that commits has one `@Transactional` boundary. A paragraph the
48
+ source has that the draft lacks is a finding.
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: COBOL → Java/Spring Boot pitfalls — alike on the page, different at runtime
3
+ matches: .
4
+ tags: port, cobol, java, spring-boot
5
+ ---
6
+ 1. **Decimal scale.** `PIC S9(7)V99 COMP-3` has an implied point: `1234567.89`
7
+ is stored as nine digits. A `double` loses cents; a `BigDecimal` without
8
+ `setScale(2)` prints `1234567.9`.
9
+ 2. **Truncation on MOVE.** Moving `PIC X(10)` into `PIC X(5)` keeps the left
10
+ five characters; moving `PIC 9(5)` into `PIC 9(3)` keeps the right three
11
+ digits. Java assignment keeps everything.
12
+ 3. **Padding.** An alphanumeric field is space-padded to its width, so
13
+ `"ABC" = "ABC "` is true in COBOL and false in Java. Trim or pad at the
14
+ boundary, in one place.
15
+ 4. **Signed overpunch.** `PIC S9(3)` in display format carries the sign in
16
+ the last byte (`12}` is `-120`). Parse it; never `Long.parseLong` the raw
17
+ bytes.
18
+ 5. **PERFORM THRU and fall-through.** Control falls into the next paragraph
19
+ unless something stops it; a `PERFORM A THRU C` runs `B` too. A method per
20
+ paragraph needs the range written out.
21
+ 6. **GO TO out of a PERFORM.** The paragraph's exit point moves. Flatten with
22
+ care, and say which exit the source used.
23
+ 7. **REDEFINES.** Two layouts over the same bytes; writing one view changes
24
+ the other. Two Java fields are two values; make the conversion explicit.
25
+ 8. **OCCURS DEPENDING ON.** The table's length is another field's value at
26
+ that moment; a fixed array hides out-of-range reads the source tolerated.
27
+ 9. **88-levels and VALUE.** A condition name tests the parent's current
28
+ value; `SET name TO TRUE` writes the first `VALUE`. Keep both directions.
29
+ 10. **Zero-based indexing.** COBOL subscripts start at 1. Every `OCCURS`
30
+ access shifts by one.
31
+ 11. **ROUNDED and ON SIZE ERROR.** `COMPUTE` truncates by default and
32
+ rounds only with `ROUNDED`; `RoundingMode.HALF_UP` is not the default.
33
+ 12. **Dates.** `YYMMDD` with a century window, `ACCEPT FROM DATE` in local
34
+ time: pin the rule and the clock.
35
+ 13. **Sequential file state.** `READ ... AT END` and `FILE STATUS` codes are
36
+ the control flow; a reader that throws on end-of-file changes it.
@@ -0,0 +1,92 @@
1
+ You are translating one COBOL source unit (a program or a copybook) to Java
2
+ on Spring Boot 3. Read this whole document before writing any code. The first
3
+ pass is a **draft** `.java` at the path the flow gives you, that captures the
4
+ logic faithfully; it does **not** need to compile. The compile pass makes it
5
+ compile module by module.
6
+
7
+ ## Ground rules
8
+
9
+ - Same unit, same names, same order. The public class is named exactly as
10
+ the file the flow asked for (Java requires it); paragraphs become private
11
+ methods in the order they appear, named in camelCase after the paragraph
12
+ (`2000-READ-INPUT` → `readInput2000`, the number kept as a suffix so the
13
+ reviewer can diff the two files side by side). Data items keep their names
14
+ in camelCase (`WS-TOTAL-AMT` → `wsTotalAmt`).
15
+ - A program is one `@Service` bean. Its `PROCEDURE DIVISION` is a public
16
+ `run(...)` method whose parameters are the `ACCEPT`ed values and the
17
+ `LINKAGE SECTION` items; its `WORKING-STORAGE` becomes fields on a private
18
+ state class created per run, never static fields.
19
+ - A copybook is one class in the `legacy.copybook` package, ported once and
20
+ imported by every program that `COPY`s it. Do not inline it.
21
+ - Numerics are exact. `PIC S9(7)V99 COMP-3` is `BigDecimal` with scale 2;
22
+ `PIC 9(5)` is `long`; `PIC X(n)` is `String` with the width recorded in a
23
+ comment. Money is never `double`.
24
+ - Files and SQL are repositories. An `FD` with `SELECT ... ASSIGN` becomes a
25
+ JPA `@Entity` plus a Spring Data repository when the file is a keyed VSAM
26
+ or DB table, or a dedicated reader class for a sequential flat file.
27
+ `EXEC SQL` becomes a repository method; the host variables are its
28
+ parameters. One `@Transactional` on `run` where the program `COMMIT`s at
29
+ the end; explicit boundaries where it commits mid-way.
30
+ - `EXEC CICS` is the online boundary: `SEND MAP` / `RECEIVE MAP` become a
31
+ request and response record on a `@RestController` that calls the service;
32
+ `LINK` / `XCTL` become a call to the other program's service bean.
33
+ - `DISPLAY` is a logger call at `info`; `DISPLAY` of an error is `warn`.
34
+ `ACCEPT FROM DATE` is `LocalDate.now(clock)` with an injected `Clock`.
35
+ `STOP RUN` is a `return`; `GOBACK` is a `return` from the program method.
36
+ - Leave `// TODO(port): <reason>` for anything you cannot translate
37
+ confidently. Do not guess.
38
+ - Do not translate JCL, compile options, SORT control cards or `IDENTIFICATION
39
+ DIVISION` metadata; note them as `// SKIPPED(port): <what>`.
40
+
41
+ ## Type map
42
+
43
+ | COBOL | Java / Spring Boot |
44
+ | ---------------------------------- | --------------------------------------------------- |
45
+ | `PIC X(n)` | `String` (width `n` noted; pad or trim on `MOVE`) |
46
+ | `PIC 9(n)` | `long` (`int` when `n` ≤ 9 and the source never exceeds it) |
47
+ | `PIC S9(n)V9(m)`, `COMP-3` | `BigDecimal` with scale `m`, `RoundingMode.DOWN` unless `ROUNDED` |
48
+ | `COMP` / `BINARY` | `int` or `long` by the PIC |
49
+ | level-01 record | a `record` when read-only after construction, else a class |
50
+ | `OCCURS n` | an array or `List` sized `n`; `OCCURS DEPENDING ON` → `List` |
51
+ | `REDEFINES` | a second view class with explicit conversion methods |
52
+ | 88-level condition name | a `boolean` method on the owning record (`isActive()`) |
53
+ | `FD` + `SELECT` | `@Entity` + `JpaRepository`, or a flat-file reader |
54
+ | `EXEC SQL` | a repository method or `JdbcTemplate` call |
55
+ | `EXEC CICS SEND/RECEIVE MAP` | `@RestController` request/response records |
56
+ | `CALL 'PROG' USING ...` | a call to `Prog.run(...)` on the injected bean |
57
+ | `PERFORM para` | a method call |
58
+ | `PERFORM para THRU other` | calls to each paragraph in source order, in a method named after the range |
59
+ | `PERFORM ... UNTIL cond` | `while (!cond) { … }` (test before) or `do { … } while` (`WITH TEST AFTER`) |
60
+ | `PERFORM VARYING` | a `for` loop |
61
+ | `EVALUATE` | `switch` with pattern matching, or an `if` chain for `EVALUATE TRUE` |
62
+ | `GO TO` | structured flow with a `// PORTED: GO TO` note |
63
+ | `STRING` / `UNSTRING` | `StringBuilder` / `split` with the delimiters written out |
64
+ | `INSPECT ... TALLYING/REPLACING` | explicit counting / `replace` |
65
+ | `SORT` / `MERGE` | `Comparator` on a `List`, or a stream `sorted` |
66
+ | `DISPLAY` / `ACCEPT` | `log.info` / a method parameter |
67
+
68
+ ## Idiom map
69
+
70
+ - A `MOVE` between items of different widths truncates on the right for
71
+ alphanumerics and on the left for numerics; write the truncation out
72
+ (`substring`, `remainder`) where the source relies on it, and say so.
73
+ - `ON SIZE ERROR` is an explicit range check before the assignment.
74
+ - `ADD 1 TO WS-COUNT` is `wsCount++` only when the PIC cannot overflow;
75
+ otherwise the modulus the PIC implies.
76
+ - A paragraph that is both `PERFORM`ed and fallen into is split: the
77
+ fall-through becomes an explicit call at the end of the preceding method.
78
+ - Dates `PIC 9(6)` `YYMMDD` become `LocalDate` with the century rule the
79
+ program used, written in one place.
80
+ - `FILE STATUS` checks become typed exceptions on the reader or repository.
81
+
82
+ ## Output format
83
+
84
+ End the file with the trailer the flow reads:
85
+
86
+ ```java
87
+ // PORT STATUS
88
+ // source: <path>.cbl
89
+ // confidence: high | medium | low
90
+ // todos: <count of TODO(port)>
91
+ // notes: <one line>
92
+ ```
@@ -0,0 +1,15 @@
1
+ ---
2
+ files: \.java$
3
+ ---
4
+ Review a Java draft against the rulebook as a port reviewer would, with the
5
+ COBOL source in mind: the diff is the draft. Report as findings: a paragraph,
6
+ data item or 88-level the source has that the draft lacks; a `double` or
7
+ `float` holding a `COMP-3`, money or quantity field; a `BigDecimal` whose
8
+ scale differs from the PIC; a `MOVE` truncation or padding the source relied
9
+ on that the draft assumes away; a `GO TO` turned into a state variable loop
10
+ when the flow was structured; a `PERFORM THRU` range that skips a paragraph;
11
+ file or SQL access outside a repository or reader; a program that commits
12
+ with no `@Transactional` boundary; `WORKING-STORAGE` turned into static
13
+ fields; a copybook inlined instead of imported; a guessed translation where a
14
+ `TODO(port)` was honest. Do not report imports or beans that cannot resolve
15
+ yet: the compile pass owns those.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llm4ts/shell",
3
- "version": "2.36.0",
3
+ "version": "2.37.0",
4
4
  "description": "Interactive shell and CLI for llm4ts: flow discovery, run-a-flow, and view",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -52,9 +52,9 @@
52
52
  "dependencies": {
53
53
  "@effect/platform-node": "4.0.0",
54
54
  "@effect/platform-node-shared": "4.0.0",
55
- "@llm4ts/runner": "2.36.0",
56
- "@llm4ts/core": "2.36.0",
57
- "@llm4ts/flow": "2.36.0"
55
+ "@llm4ts/core": "2.37.0",
56
+ "@llm4ts/flow": "2.37.0",
57
+ "@llm4ts/runner": "2.37.0"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "effect": "4.0.0"