@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.
- package/kits/port/README.md +5 -4
- package/kits/port/packs/cobol-springboot-port/pack.md +48 -0
- package/kits/port/packs/cobol-springboot-port/patterns/pitfalls-cobol-springboot-port.md +36 -0
- package/kits/port/packs/cobol-springboot-port/prompts/porting.md +92 -0
- package/kits/port/packs/cobol-springboot-port/reviewers/spring-fidelity.md +15 -0
- package/package.json +4 -4
package/kits/port/README.md
CHANGED
|
@@ -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
|
|
30
|
-
|
|
|
31
|
-
| `zig-rust`
|
|
32
|
-
| `scala-ts`
|
|
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.
|
|
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/
|
|
56
|
-
"@llm4ts/
|
|
57
|
-
"@llm4ts/
|
|
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"
|