diff --git a/AGENTS.md b/AGENTS.md index 19e909c1..2c90cfac 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -63,8 +63,8 @@ Python entry points are `pineforge_codegen.transpile()` and `pineforge_codegen.transpile_full()`; the Pyodide package ships the `gate/glue.py` JSON protocol. See `docs/PUBLIC_CONTRACT.md`. -This is the **source-available** half of the PineForge stack (PineForge -Source License 1.2 — see `LICENSE`). The runtime half (`pineforge-engine`, +This is the **source-available** half of the PineForge stack (Tunaxis +Source License 1.3 — see `LICENSE`). The runtime half (`pineforge-engine`, Apache-2.0) lives in a sibling repo and is typically checked out at `../pineforge-engine`. From 1.0.0 on, a released codegen `X.Y.Z` pairs only with engine `vX.Y.Z`; prereleases match exactly. Codegen 1.3.0 pairs with diff --git a/CHANGELOG.md b/CHANGELOG.md index 20b0d997..864243f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,19 @@ supported as exact pairs; on the 0.x line they are independent. See the the release commit. A prerelease note describes changes since the preceding prerelease or stable tag; the final stable note consolidates the series. +## Unreleased + +### Renamed to Tunaxis + +- The product is named **Tunaxis**. +- The distribution is `tunaxis-codegen`, the import is `tunaxis_codegen`, the + CLI is `tunaxis-cpp-allowlist`, and the npm package is `@tunaxis/codegen-pyodide`. +- The old names keep working through forwarding packages; legacy imports and + CLI names remain available. +- The C++ namespace, headers, macros, environment variables and C ABI remain + unchanged for now. +- The license is now the **Tunaxis Source License 1.3** (the PineForge Source License 1.2, renamed), with the same terms. + ## 1.6.1 — 2026-10-18 A patch release of the exact engine/codegen pair, paired with engine `v1.6.1` diff --git a/CLAUDE.md b/CLAUDE.md index 9e693b35..58952c1e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -63,8 +63,8 @@ Python entry points are `pineforge_codegen.transpile()` and `pineforge_codegen.transpile_full()`; the Pyodide package ships the `gate/glue.py` JSON protocol. See `docs/PUBLIC_CONTRACT.md`. -This is the **source-available** half of the PineForge stack (PineForge -Source License 1.2 — see `LICENSE`). The runtime half (`pineforge-engine`, +This is the **source-available** half of the PineForge stack (Tunaxis +Source License 1.3 — see `LICENSE`). The runtime half (`pineforge-engine`, Apache-2.0) lives in a sibling repo and is typically checked out at `../pineforge-engine`. From 1.0.0 on, a released codegen `X.Y.Z` pairs only with engine `vX.Y.Z`; prereleases match exactly. Codegen 1.3.0 pairs with diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 964f50de..0f63e581 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to pineforge-codegen +# Contributing to Tunaxis Codegen This is the source-available PineScript v6 to C++ translator. Read the [license and contribution terms](LEGAL.md) before sending a material change. @@ -10,8 +10,9 @@ contact luis@4pass.com.tw before opening a material pull request. ## Local setup Use Python 3.11 or newer, Node 22, a C++17 compiler, CMake, and a matching -[`pineforge-engine`](https://github.com/pineforge-4pass/pineforge-engine) -checkout. Clone codegen and engine as siblings, then install the development +checkout of the Tunaxis engine (repository +[`pineforge-engine`](https://github.com/pineforge-4pass/pineforge-engine)). +Clone codegen and engine as siblings, then install the development dependencies from this repository: ```bash diff --git a/LEGAL.md b/LEGAL.md index 419414dd..9a492445 100644 --- a/LEGAL.md +++ b/LEGAL.md @@ -1,29 +1,29 @@ # Legal information -Summary of licensing, third-party components, and trademarks for `pineforge-codegen`. **Not** legal advice; consult counsel for your use case. +Summary of licensing, third-party components, and trademarks for `tunaxis-codegen` (formerly published as `pineforge-codegen`). **Not** legal advice; consult counsel for your use case. ## License -`pineforge-codegen` is **source-available**, **not** OSI "open source." It is distributed under the **PineForge Source License 1.2** — see [LICENSE](LICENSE), which is the controlling text. +`tunaxis-codegen` is **source-available**, **not** OSI "open source." It is distributed under the **Tunaxis Source License 1.3** — see [LICENSE](LICENSE), which is the controlling text. - **Noncommercial use** — any noncommercial purpose, and use by a charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization or government institution for its teaching, research and other operations, is free. - **Personal Trading** — free for a natural person to research, develop or backtest strategies and trade their **own** account with their **own** capital. Household, joint and retirement accounts and ordinary margin count as their own; a company's or fund's account does not, even a company they wholly own. An account that a proprietary-trading firm or funded-trader program provides or allocates to them, including a challenge, evaluation or simulated account, does not count as their own either. - **Investment management** — managing, advising on or trading investment capital, or researching strategies for it (a friend's, clients' or investors' capital, an endowment, a pension fund, a public fund, a foundation's treasury, or an account a proprietary-trading firm or funded-trader program provides or allocates, including challenge, evaluation and simulated accounts), is **Commercial Use for every individual and every organization**, noncommercial organizations included, except Personal Trading. -- **Commercial Use** — investment management and any other use that is not free, such as use by or for a company or fund, embedding the software or its output in a product or service for others, or operating a hosted/public-facing service with it, requires a **commercial license** (email **enterprise@pineforge.dev**; the commercial-license store is coming soon). +- **Commercial Use** — investment management and any other use that is not free, such as use by or for a company or fund, embedding the software or its output in a product or service for others, or operating a hosted/public-facing service with it, requires a **commercial license** (email **enterprise@tunaxis.com**; the commercial-license store is coming soon). Describe this project as **"source-available"** rather than "open source." The runtime it targets, [`pineforge-engine`](https://github.com/pineforge-4pass/pineforge-engine), is separate and **Apache-2.0**. -Releases up to and including 1.1.0 were published under the license text that came with them (the PolyForm Noncommercial License 1.0.0 with a PineForge supplement); copies of those releases keep that license. The PineForge Source License is a separate license and is not a PolyForm license. +Releases up to and including 1.1.0 were published under the license text that came with them (the PolyForm Noncommercial License 1.0.0 with a Tunaxis supplement); copies of those releases keep that license. The Tunaxis Source License is a separate license and is not a PolyForm license. -The PineForge Source License 1.1 replaced 1.0, and 1.2 replaces 1.1, for the code on `main` and in releases from 1.3.0 on. Version 1.1 clarified one point, that distributing the software or its output, changed or not, embedded in or bundled with a product or service made available to others is Commercial Use, not free distribution, unless it is for a permitted purpose. Version 1.2 makes two points explicit: an account a proprietary-trading firm or funded-trader program provides or allocates, including a challenge, evaluation or simulated account, is not a person's own account or capital, so trading it is not Personal Trading; and the capital in such an account, real or simulated, is investment capital, so trading it is investment management, which is Commercial Use. It changes nothing else. Release 1.2.0 was published under 1.1 and keeps that text; 1.3.0 is the first release published under 1.2. +The PineForge Source License 1.1 replaced 1.0, and the Tunaxis Source License 1.2 (formerly named the PineForge Source License) replaces 1.1, for the code on `main` and in releases from 1.3.0 on. Version 1.1 clarified one point, that distributing the software or its output, changed or not, embedded in or bundled with a product or service made available to others is Commercial Use, not free distribution, unless it is for a permitted purpose. Version 1.2 makes two points explicit: an account a proprietary-trading firm or funded-trader program provides or allocates, including a challenge, evaluation or simulated account, is not a person's own account or capital, so trading it is not Personal Trading; and the capital in such an account, real or simulated, is investment capital, so trading it is investment management, which is Commercial Use. It changes nothing else. Release 1.2.0 was published under 1.1 and keeps that text; 1.3.0 is the first release published under 1.2. The Tunaxis Source License 1.3, dated 2026-10-29, replaces 1.2 for the code on `main` and in releases after that date; compared with 1.2, it renames the licensor's product to Tunaxis and changes the commercial contact address, and the terms are unchanged. ## Copyright and licensor -The licensor is **PINEFORGE LLC**, a Delaware limited liability company. It holds the copyright in `pineforge-codegen`; the founder's rights in the software are assigned to it. Commercial licenses are granted by PINEFORGE LLC. +The licensor is **PINEFORGE LLC**, a Delaware limited liability company. It holds the copyright in `tunaxis-codegen` (formerly published as `pineforge-codegen`); the founder's rights in the software are assigned to it. Commercial licenses are granted by PINEFORGE LLC. ## What this repository is -A pure-Python PineScript v6 → C++ transpiler that emits source against the public PineForge engine C-ABI. It implements PineScript v6 from **TradingView's publicly published language documentation**; it does **not** incorporate TradingView proprietary source. Names like "PineScript v6" are used **nominatively** to describe the input language. +A pure-Python PineScript v6 → C++ transpiler that emits source against the public Tunaxis engine C-ABI. It implements PineScript v6 from **TradingView's publicly published language documentation**; it does **not** incorporate TradingView proprietary source. Names like "PineScript v6" are used **nominatively** to describe the input language. ## Third-party components @@ -31,7 +31,7 @@ The transpiler has **no runtime dependencies** (`transpile()` and `transpile_ful ## Trademarks and affiliation -**TradingView** and **PineScript** are trademarks of their respective owners. `pineforge-codegen` is **not** affiliated with, endorsed by, or certified by TradingView. References to "PineScript v6" and any compatibility/parity statements are **nominative** and factual — compatibility and technical testing only, not a partnership or certification. +**TradingView** and **PineScript** are trademarks of their respective owners. `tunaxis-codegen` is **not** affiliated with, endorsed by, or certified by TradingView. References to "PineScript v6" and any compatibility/parity statements are **nominative** and factual — compatibility and technical testing only, not a partnership or certification. ## Contributions diff --git a/README.md b/README.md index ab2608d7..150c9c84 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,16 @@ -# pineforge-codegen +Tunaxis -> PineScript v6 → C++ transpiler that emits against the [pineforge-engine](https://github.com/pineforge-4pass/pineforge-engine) runtime. +# Tunaxis Codegen -[![PyPI](https://img.shields.io/pypi/v/pineforge-codegen.svg)](https://pypi.org/project/pineforge-codegen/) -[![Python](https://img.shields.io/pypi/pyversions/pineforge-codegen.svg)](https://pypi.org/project/pineforge-codegen/) -[![License](https://img.shields.io/badge/license-PineForge%20Source%201.2-orange.svg)](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/LICENSE) +> PineScript v6 → C++ transpiler that emits against the Tunaxis engine (repository [pineforge-engine](https://github.com/pineforge-4pass/pineforge-engine)). + +[![PyPI](https://img.shields.io/pypi/v/tunaxis-codegen.svg)](https://pypi.org/project/tunaxis-codegen/) +[![Python](https://img.shields.io/pypi/pyversions/tunaxis-codegen.svg)](https://pypi.org/project/tunaxis-codegen/) +[![License](https://img.shields.io/badge/license-Tunaxis%20Source%201.3-orange.svg)](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/LICENSE) [![Personal use](https://img.shields.io/badge/personal%20trading-free-22c55e.svg)](#license) A pure-Python library that turns a PineScript v6 strategy into a complete C++ -source file you can compile against the [`pineforge-engine`](https://github.com/pineforge-4pass/pineforge-engine) -runtime. +source file you can compile against the [engine](https://github.com/pineforge-4pass/pineforge-engine). **Measured 2026-10-07** on main engine `b3192bfc` with codegen-oss `bfc4ddce` (baseline `pineforge-parity-baseline-20261007-engine-b3192bfc`, snapshot `28ba8dbd`): 7,983 of 7,989 TradingView probes graded excellent and 6 strong, with 0 below strong; 17 more probes are held out as TradingView-side anomalies. @@ -39,6 +40,13 @@ for the changes in each release from 1.0.0 on and the release-note policy. `transpile_full()` returns nonfatal warnings and, since 1.5.0, notes for supported scripts, including those with documented approximations. +## Formerly PineForge + +`pineforge-codegen` on PyPI now forwards to `tunaxis-codegen`. +`import pineforge_codegen` and `pf-cpp-allowlist` keep working; the import +prints a `DeprecationWarning`. `@pineforge/codegen-pyodide` forwards to +`@tunaxis/codegen-pyodide`. + ## Releases and this README -This README ships with each release as its package description on PyPI -(`pineforge-codegen`); releases from 0.7.0 on are also on npm as -`@pineforge/codegen-pyodide`. It describes 1.6.1 (2026-10-18) +This README ships with each release as its package description on PyPI. +The package names are `tunaxis-codegen` on PyPI and +`@tunaxis/codegen-pyodide` on npm; the Pyodide package has shipped on npm +since 0.7.0. This README describes 1.6.1 (2026-10-18) and what changed since 0.10.4. The 1.4.0 release's behavior was validated before tagging on codegen `bfc4ddce` with engine `b3192bfc`, excluding engine request #356; those validation builds reported `1.3.0`. Historical measurements @@ -135,7 +144,7 @@ the engine's [architecture notes](https://github.com/pineforge-4pass/pineforge-e ## Install ```bash -pip install pineforge-codegen +pip install tunaxis-codegen ``` This installs the latest release. Requires Python ≥ 3.11. No runtime @@ -152,7 +161,7 @@ pip install -e ".[dev]" ## Quick start ```python -from pineforge_codegen import transpile +from tunaxis_codegen import transpile pine = """ //@version=6 @@ -191,7 +200,7 @@ transpile( ``` Returns the generated C++ source as a string. Raises -`pineforge_codegen.errors.CompileError` on a rejected construct and, since 1.0.0, +`tunaxis_codegen.errors.CompileError` on a rejected construct and, since 1.0.0, on a syntax error or an input limit (0.10.4 recovers from some syntax errors and has no input limits). It does not return nonfatal diagnostics (warnings and, since 1.5.0, notes); use `transpile_full()` to inspect them. @@ -257,8 +266,8 @@ warnings; since 1.1.0 the success envelope also carries `requests`. Since 1.5.0, informational level described under [Diagnostic codes](#diagnostic-codes), travel in the same `diagnostics` lists with `"severity": "note"`. See the [1.0 public contract](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/docs/PUBLIC_CONTRACT.md) -for the exact fields, severity values, and input key rules. There is no -installed CLI or exit-code contract. +for the exact fields, severity values, and input key rules. Transpilation has +no installed CLI or exit-code contract. ### Diagnostic codes @@ -278,20 +287,18 @@ lowered to `na`). Every other diagnostic keeps its severity, the other visual-only and display-only ones included; the catalog is authoritative. ```python -from pineforge_codegen import diagnostics_catalog, transpile_full +from tunaxis_codegen import diagnostics_catalog, transpile_full for d in transpile_full(source)["diagnostics"]: - print(d.code, d.args, d.message) -# PF-W1067 {'name': 'bar_index'} bar_index diverges from TradingView semantics in PineForge. + print(d.code, d.args) +# PF-W1067 {'name': 'bar_index'} entry = diagnostics_catalog()["codes"]["PF-W1067"] -# {'severity': 'warning', 'area': 'support', -# 'message': '{name} diverges from TradingView semantics in PineForge.', -# 'hint': '...', 'explanation': '...', 'args': {'name': {'kind': 'identifier'}}, -# 'user_message': '...'} +print(entry["severity"], entry["args"]) +# warning {'name': {'kind': 'identifier'}} ``` -The catalog (`pineforge_codegen/diagnostics_catalog.json`, also attached to +The catalog (`tunaxis_codegen/diagnostics_catalog.json`, also attached to each GitHub release) gives each code its severity, English ICU MessageFormat `message` and `hint` templates, a one-line explanation and a short `user_message` template; rendering the `message` and `hint` templates with @@ -311,7 +318,7 @@ symbol string and timeframe, matched byte for byte. `transpile_full()`'s request site: ```python -from pineforge_codegen import transpile_full +from tunaxis_codegen import transpile_full full = transpile_full(open("my_strategy.pine").read()) for request in full["requests"]: @@ -325,7 +332,7 @@ for request in full["requests"]: The symbol is a `literal` (its `value`), an `input` (its override key `title` and its `default`: the run keys the feed on the override, else the default), `computed` (its `expr`, the `value` at the inputs' defaults when it can be -computed, and the `inputs` it reads) or `unresolvable` (a request PineForge +computed, and the `inputs` it reads) or `unresolvable` (a request Tunaxis cannot key before the first bar: the run stops where its value is read). The timeframe is a `literal` in the engine's spelling (whole minutes such as `"240"`, `D|W|M|S` such as `"1D"`, Pine's bare `"D"` as `"1D"`), the @@ -340,7 +347,7 @@ expression (`timeframe.period`, a variable's name). Request discovery and feed keys use the engine's spelling, in which Pine's bare `"D"` / `"W"` / `"M"` / `"S"` are `"1D"` / `"1W"` / `"1M"` / `"1S"` and any other text is kept. Discovery folds `literal` and `computed` values -(`pineforge_codegen.request_discovery.canonical_timeframe`); the engine folds +(`tunaxis_codegen.request_discovery.canonical_timeframe`); the engine folds the requested timeframe when it looks a feed up, so a script's `"D"` and `"1D"` read the same feed, keyed `"1D"`. An `input` timeframe's `default` and its override are raw: fold them the same way. To match a receipt's request to a @@ -353,27 +360,35 @@ gives every field. ```python from pathlib import Path -from pineforge_codegen import transpile +from tunaxis_codegen import transpile pine = Path("strategy.pine") cpp = transpile(pine.read_text(), filename=pine.name) # filename → better errors Path("strategy.generated.cpp").write_text(cpp) ``` +### Check generated C++ + +The installed `tunaxis-cpp-allowlist` command checks generated C++ against the +codegen allowlist: + +```bash +tunaxis-cpp-allowlist strategy.generated.cpp +``` + ### Handle unsupported features The support checker raises a `CompileError` with the exact source location instead of emitting broken C++: ```python -from pineforge_codegen import transpile -from pineforge_codegen.errors import CompileError +from tunaxis_codegen import transpile +from tunaxis_codegen.errors import CompileError try: transpile('//@version=6\nindicator("x")\n') except CompileError as e: print(e) - # :2:1: indicator() declarations are not supported; PineForge runs strategies only. try: transpile('//@version=6\nstrategy("x")\n' @@ -405,7 +420,7 @@ faithfully: ```python from pathlib import Path -from pineforge_codegen import transpile +from tunaxis_codegen import transpile src = Path("strategy.pine").read_text() cpp = transpile(src, check_support=False) @@ -420,7 +435,7 @@ engine's `strategy_set_trace_enabled()`; the values come back in the report's against TradingView: ```python -from pineforge_codegen import transpile +from tunaxis_codegen import transpile pine = """ //@version=6 @@ -448,7 +463,7 @@ context. These classes are outside the [1.0 public contract](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/docs/PUBLIC_CONTRACT.md): ```python -from pineforge_codegen import ( +from tunaxis_codegen import ( Lexer, Parser, Analyzer, CodeGen, extract_pf_trace_pragmas, check_support_or_raise, ) @@ -472,7 +487,7 @@ quick-start strategy. These limits are new in 1.0.0; 0.10.4 has none of them. They turn a crash or a hang on untrusted source into a `CompileError` with a Pine `file:line:col` -location. Where TradingView documents a limit, PineForge's is at least as +location. Where TradingView documents a limit, Tunaxis's is at least as large. Exceeding one does not return partial C++, and `check_support=False` does not bypass them. @@ -518,7 +533,7 @@ pine source The passes run again, from pass 1, when the generated C++ needs a renamed block-local declaration or a per-call-site clone of a function that reads -`session.[k]`; `_generate` in `pineforge_codegen/__init__.py` holds the +`session.[k]`; `_generate` in `tunaxis_codegen/__init__.py` holds the loop. 0.10.4 runs passes 1, 2, 4, 6 and 7 once, with only the bounded TA length rewrite of pass 5. @@ -645,7 +660,7 @@ use `python -m pytest --collect-only -q` for the current collection count. ## License -Source-available under the [PineForge Source License 1.2](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/LICENSE); +Source-available under the [Tunaxis Source License 1.3](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/LICENSE); the `LICENSE` file is the controlling text. The licensor is PINEFORGE LLC. - **Free for noncommercial use:** any noncommercial purpose, and use by a @@ -689,7 +704,7 @@ Commercial licenses are annual: Solo for one person, Team for an organization's own use, Fund for managers of others' capital and for institutional investment capital such as endowments and pension or public funds (by assets under management), and OEM / Embedded for products and -hosted services. Email **enterprise@pineforge.dev** with questions or for a +hosted services. Email **enterprise@tunaxis.com** with questions or for a quote. The commercial-license store (coming soon) will take orders online. ## Explicit Pine execution attachment diff --git a/docs/PUBLIC_CONTRACT.md b/docs/PUBLIC_CONTRACT.md index 08b1abe5..243162d8 100644 --- a/docs/PUBLIC_CONTRACT.md +++ b/docs/PUBLIC_CONTRACT.md @@ -1,7 +1,8 @@ # Public contract for 1.0 -The supported Python/JSON contract began in 1.0.0; the sections below identify -later additions. This revision includes the 1.6.1 pair (2026-10-18). +The supported Tunaxis (formerly PineForge) Python/JSON contract began in +1.0.0; the sections below identify later additions. This revision includes +the 1.6.1 pair (2026-10-18). Text marked **since 1.5.0** describes diagnostic additions that 1.4.0 and earlier releases do not have: the `note` severity, the `user_message` template @@ -9,8 +10,9 @@ and the eleven codes that became notes. ## Optional compiled execution capabilities -Availability: **since 1.2.0**, with engine `v1.2.0`'s capability extension and -the receipt-based admission policy of its live runner. +Availability: **since 1.2.0**, with the capability extension of the Tunaxis engine +(repository `pineforge-engine`) at `v1.2.0` and the receipt-based admission policy +of its live runner. The receipt proves declarations only, not general live-versus-batch equivalence. Its `strategy()` positional arguments follow Pine signature order independently @@ -115,7 +117,7 @@ expression (`timeframe.period`, a variable's name). [Request discovery](#request-discovery) and feed keys use the engine's spelling, in which Pine's bare `"D"` / `"W"` / `"M"` / `"S"` are `"1D"` / `"1W"` / `"1M"` / `"1S"` and any other text is kept. Discovery folds `literal` and `computed` -values (`pineforge_codegen.request_discovery.canonical_timeframe`); the engine +values (`tunaxis_codegen.request_discovery.canonical_timeframe`); the engine folds the requested timeframe when it looks a feed up, so a script's `"D"` and `"1D"` read the same feed, keyed `"1D"`. An `input` timeframe's `default` and its override are raw: fold them the same way. To match a receipt's request to a @@ -323,7 +325,7 @@ generated code computes them before the first bar: | --- | --- | | `line` | The 1-based line of the `request.security` call. A helper's request is listed once per symbol and timeframe its call paths pass, each at the request's line. | | `fn` | The Pine function, `"request.security"`. | -| `symbol` | `{"kind": "literal", "value"}`: the exact key, exchange prefix and suffix kept (`"BINANCE:ETHUSDT.P"`). `{"kind": "input", "title", "default"}`: an `input.symbol`, `input.string` or string `input()` (`ticker.standard` / `ticker.inherit` of one too); the key is the run's value of the input, overridden under `title` (the manifest's override key), else `default`. `{"kind": "computed", "expr"[, "value"][, "inputs"]}`: `expr` spells the expression as written, `value` is its key at the inputs' defaults when literals and inputs compute it (string `+`, `==`, `!=`, `and`, `or`, `not`, `?:`; never the chart's own `syminfo.*` strings), and `inputs` names the override keys of the inputs it reads. `{"kind": "unresolvable", "expr"}`: a request whose symbol, timeframe or expression PineForge cannot key before the first bar; no feed serves it, and the run stops where its value is read. | +| `symbol` | `{"kind": "literal", "value"}`: the exact key, exchange prefix and suffix kept (`"BINANCE:ETHUSDT.P"`). `{"kind": "input", "title", "default"}`: an `input.symbol`, `input.string` or string `input()` (`ticker.standard` / `ticker.inherit` of one too); the key is the run's value of the input, overridden under `title` (the manifest's override key), else `default`. `{"kind": "computed", "expr"[, "value"][, "inputs"]}`: `expr` spells the expression as written, `value` is its key at the inputs' defaults when literals and inputs compute it (string `+`, `==`, `!=`, `and`, `or`, `not`, `?:`; never the chart's own `syminfo.*` strings), and `inputs` names the override keys of the inputs it reads. `{"kind": "unresolvable", "expr"}`: a request whose symbol, timeframe or expression Tunaxis cannot key before the first bar; no feed serves it, and the run stops where its value is read. | | `timeframe` | `{"kind": "literal", "value"}` in the engine's spelling: whole minutes (`"240"`), `D`, `W`, `M` or `S` (`"1D"`), Pine's bare `"D"` / `"W"` / `"M"` / `"S"` as `"1D"` / `"1W"` / `"1M"` / `"1S"`; other text is kept as written and no feed matches it. `{"kind": "chart"}`: `timeframe.period`, `timeframe.main_period` or `""`, the chart's timeframe (a run that reads another symbol's feed takes the chart's bars unaggregated). `{"kind": "input", "title", "default"}`: an input's raw value, spelled by the same rule, `""` the chart's. `{"kind": "computed", "expr"[, "value"][, "inputs"]}` as for the symbol, a `switch` of one-expression arms included (no matching arm and no default is the chart's); an empty `value` is the chart's timeframe. | | `lookahead`, `gaps` | Booleans: `barmerge.lookahead_on`, `barmerge.gaps_on`. | | `ignore_invalid_symbol` | `false` when omitted, else its value (at the inputs' defaults), `null` when not computable. | @@ -348,7 +350,7 @@ above added: `transpile_full()`'s result and the JSON success envelope gain result key or envelope is removed or renamed. 1.2.0, released 2026-10-05, implements it with the compiled execution capabilities and the diagnostic codes described here added: each `Diagnostic` and each JSON diagnostic gain -`code` and `args`, and `pineforge_codegen` exports `diagnostics_catalog()` +`code` and `args`, and `tunaxis_codegen` exports `diagnostics_catalog()` and `render_diagnostic()`. No argument, result key or envelope is removed or renamed. 1.3.0, released 2026-10-06, implements it unchanged, with the confirmed-bar and order-shapes receipts described here added to the generated @@ -357,7 +359,7 @@ The last 0.x release, 0.10.4, has neither the `libraries` argument nor the `diagnostics` key described below. The supported programmatic entry points are the Python functions -`pineforge_codegen.transpile` and `pineforge_codegen.transpile_full`, plus the +`tunaxis_codegen.transpile` and `tunaxis_codegen.transpile_full`, plus the `gate/glue.py` `transpile_json` protocol shipped in the Pyodide package. The pipeline classes shown in the [README](../README.md#advanced-run-the-pipeline-stages-directly) are for advanced inspection and are not part of this 1.0 stability promise. @@ -375,7 +377,7 @@ transpile_full(pine_source: str, *, check_support: bool = True, ``` `transpile()` returns one complete C++ source string. It raises -`pineforge_codegen.errors.CompileError` for a located parse, support, analysis, +`tunaxis_codegen.errors.CompileError` for a located parse, support, analysis, or generation error; its `diagnostics` attribute carries `Diagnostic` objects. `filename` appears in their source locations and in `str(error)`. `transpile()` returns no nonfatal diagnostics, neither warnings nor (since @@ -568,7 +570,7 @@ Every `Diagnostic` (in `transpile_full(...)["diagnostics"]`, in a travels with `args.name = "plot"`; a receiver renders or translates it. `diagnostics_catalog()` returns the catalog, which ships as -`pineforge_codegen/diagnostics_catalog.json` (schema +`tunaxis_codegen/diagnostics_catalog.json` (schema `pineforge-diagnostics-catalog/v1`, whose id the 1.5.0 additions do not change) and is attached to each GitHub release (`diagnostics_catalog-v1.3.0.json` for 1.3.0). @@ -658,7 +660,8 @@ inside a `switch` arm also say that PineForge keeps the arm's lowering, and PF-W1067 to PF-W1072, which warn everywhere, name no arm. No warning or note template says that PineForge refuses or rejects something, though one may say what TradingView refuses or rejects. Beyond these checks a template's exact -wording is not pinned. A text no template +wording is not pinned. The user-visible message strings will be renamed to +Tunaxis in a later release. A text no template renders carries `PF-E0000` / `PF-W0000` with the text in `args.message` (and `args.hint`); the test suite refuses it. The `message` text itself is unchanged and stays the English rendering; `runtime.error` text a strategy @@ -681,10 +684,11 @@ the support gate and can produce C++ that fails to compile or does not match Pine behavior; the 1.0 compatibility promise applies with the default `check_support=True`. -There is no installed command-line interface. This package makes no -process-exit-code promises for a CLI, shell wrapper, or gate script. Consumers -should use the Python exception and return-value contract or the JSON -`ok`/`diagnostics` contract. +There is no installed command-line interface for transpilation. +`tunaxis-cpp-allowlist` checks generated C++ against the codegen allowlist. +This contract makes no process-exit-code promises for a CLI, shell wrapper, +or gate script. Consumers should use the Python exception and return-value +contract or the JSON `ok`/`diagnostics` contract for transpilation. Generated C++ has a separate runtime pairing requirement: from 1.0.0 on, codegen `X.Y.Z` supports only engine `vX.Y.Z` with that release's generated diff --git a/docs/codegen-coverage-gaps.md b/docs/codegen-coverage-gaps.md index 1fb1ab32..97e291c2 100644 --- a/docs/codegen-coverage-gaps.md +++ b/docs/codegen-coverage-gaps.md @@ -13,8 +13,8 @@ > "Libraries and requests for outside data"). `AGENTS.md` describes the current > support contracts. -Tracks fallthrough paths in `pineforge_codegen/codegen/visit_call.py` and -`pineforge_codegen/codegen/visit_expr.py` that emit a literal `"false"` / +Tracks fallthrough paths in `tunaxis_codegen/codegen/visit_call.py` and +`tunaxis_codegen/codegen/visit_expr.py` that emit a literal `"false"` / `"0"` / `"na()"` for an unrecognized construct, and whether the analyzer (`support_checker.py`) already rejects the construct before codegen ever sees it. @@ -22,8 +22,9 @@ codegen ever sees it. A gap appears here only when **both** are true: 1. The fallthrough is reachable from a valid Pine v6 construct. -2. The fallthrough produces silently-wrong behavior (not a defensive - sentinel that the engine ignores). +2. The fallthrough produces silently-wrong behavior; a defensive sentinel + that the Tunaxis engine (repository `pineforge-engine`) ignores does not + qualify. If only (1) is true but the analyzer rejects the construct, the fallthrough is defensive-only and is intentionally left in place as a @@ -35,9 +36,9 @@ No additional gaps found beyond what Phase B closed (B1–B6). ### Audit method -Ran `grep -n 'return "false"\|return "0"' pineforge_codegen/codegen/visit_call.py pineforge_codegen/codegen/visit_expr.py` -and triaged each of the 34 matches against the analyzer's rejection -tables (`HARD_REJECT_FUNC`, `HARD_REJECT_NAMESPACE`, `NOT_YET_FUNC`, +The audit searched `codegen/visit_call.py` and `codegen/visit_expr.py` for +`return "false"` and `return "0"`, and triaged each of the 34 matches against +the analyzer's rejection tables (`HARD_REJECT_FUNC`, `HARD_REJECT_NAMESPACE`, `NOT_YET_FUNC`, `UNSUPPORTED_BARE_FUNCS`, `UNSUPPORTED_NAMESPACES`, `UNSUPPORTED_MEMBERS`, `UNSUPPORTED_NAMESPACE_VARS`, `SUPPORTED_TIMEFRAME_FUNC`, `SUPPORTED_SYMINFO`, `SUPPORTED_MATH`, @@ -96,7 +97,7 @@ No new follow-up work identified by this audit. 2025-04-08 used the operation's result in each order signal. An earlier unobserved probe let TradingView eliminate the operation and was discarded. -| Operation | TradingView evidence | PineForge behavior | +| Operation | TradingView evidence | Tunaxis behavior | |---|---|---| | Primitive `array` slice, then write through slice and source | 32/32 entries signal `both-alias`; covered tape SHA-256 `fbd83309262bfd1a8a06e8f3cc82228fad1b1358b03b135b200246d5f4cfb7c0` | The same source run against the built engine signals `no-alias`. Both syntax forms emit a located warning in `transpile_full` / `transpile_json`. | | `array.fill(a, 9, 2, 1)` on `[1,2,3]` | 32/32 entries signal `123` (no-op); covered tape SHA-256 `83243e37dd66678e1b9127baac2ba42ef74815d31097c0c2095a08efffca575e` | Guarded no-op, without invalid STL iterator arithmetic. | diff --git a/docs/pine-cap-activation.md b/docs/pine-cap-activation.md index f6bb4f21..c3ea9c97 100644 --- a/docs/pine-cap-activation.md +++ b/docs/pine-cap-activation.md @@ -4,7 +4,8 @@ This note came with the explicit cap attachment ([#127](https://github.com/pineforge-4pass/pineforge-codegen-oss/pull/127)). It now also covers the execution-adapter attachment that followed ([#128](https://github.com/pineforge-4pass/pineforge-codegen-oss/pull/128)) and -describes the codegen 1.4.0 / engine `v1.4.0` pair (2026-10-08). +describes the codegen 1.4.0 pair with the Tunaxis engine (repository +`pineforge-engine`) at `v1.4.0` (2026-10-08). Pre-tag validation used codegen `bfc4ddce` and engine `b3192bfc`, whose version files then read `1.3.0`. diff --git a/pyproject.toml b/pyproject.toml index 68a4432d..efe66b51 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ requires-python = ">=3.11" authors = [ { name = "PineForge", email = "luis@4pass.com.tw" }, ] -# PineForge Source License 1.2 (source-available); see LICENSE. +# Tunaxis Source License 1.3 (source-available); see LICENSE. license = { file = "LICENSE" } readme = "README.md" keywords = ["pinescript", "transpiler", "trading", "backtesting", "tradingview"]