GX-TXT 0.9.8.10-dev-031 Script Module Builder 1.0.2 Python + GNU Octave Plugin Install ZIP

GX-TXT — Guida completa a Script Module Builder

Script Module Builder trasforma uno script scientifico Python o GNU Octave in un normale modulo Analysis installabile in GX-TXT, preservando i byte del sorgente originale e costruendo attorno ad esso descriptor, configurazione, bundle, documentazione, checksum, provenance e — se richiesto — una API pubblica.

Indice

1. Che cosa fa e che cosa non fa

Fa

Prende un autorevole .py o .m, genera un modulo Analysis standard, conserva il sorgente byte-per-byte, espone i normali controlli Analysis e costruisce uno ZIP installabile con Plugin Install.

Non fa

Non traduce il codice, non corregge formule, non riscrive la matematica, non crea una GUI privata, non sostituisce le API pubbliche con accessi a file interni e non trasforma automaticamente un prototipo in un modulo “production grade”.

Principio fondamentale
Il research script rimane autorevole. Il Builder costruisce l'integrazione GX-TXT attorno a quel sorgente, senza modificarne i byte.

2. Dove si apre

La superficie ufficiale è Modules → Script Module Builder…. Il tool è un modulo CORE non selezionabile, di tipo tool, gruppo Scripting / Development.

Nota: la panoramica della GUI resta utile per orientarsi, ma per il contenuto del progetto JSON è ora presente anche una vista dedicata ingrandita.

La stessa implementazione è disponibile da command line attraverso tools/gxtxt_module_builder.py.

Edizione corretta per leggibilità immagini
Le immagini in questa revisione sono state sostituite con versioni più leggibili: ritagliate, appiattite su fondo bianco e ingrandite nelle aree che contengono testo fitto, in particolare la sezione Project JSON.

3. Anatomia della GUI

GX-TXT Script Module Builder con aree principali numerate
Ricostruzione fedele della GUI definita da builder.py nella dev-031. I controlli, le etichette e l'organizzazione corrispondono all'implementazione corrente.
Zoom leggibile della sezione Project JSON del Module Builder
Zoom Project JSON. Vista ravvicinata dell’area progetto: percorso del progetto, output directory, editor JSON e tabella delle Analysis Sources rilevate dallo script.
1Project e output. Percorso del progetto JSON e directory nella quale scrivere il pacchetto.
2Inizio del progetto JSON. Il progetto è direttamente leggibile e modificabile.
3Editor JSON. Qui sono visibili anche impostazioni avanzate non esposte da un dialog dedicato.
4Analysis Sources dichiarate dallo script. Discovery statica: lo script non viene eseguito.
5Creazione e metadata. Nuovo progetto, import registered script, Details, source e variable bindings.
6Validate e Build ZIP. Due passaggi distinti: validazione prima, package dopo.
7Risoluzione dichiarazioni. Review, uso della dichiarazione script oppure mantenimento esplicito delle sorgenti manuali.
Zoom leggibile dell'editor Project JSON del Script Module Builder
Vista ingrandita del riquadro Project JSON. Questa immagine è dedicata alla leggibilità del contenuto dell’editor.

4. Il progetto JSON

Il file di lavoro usa schema_version: 1. È intenzionalmente semplice e versionabile. Il Builder lo può riaprire e ricostruire.

{
  "schema_version": 1,
  "id": "research.scale_signal",
  "name": "Scale signal",
  "description": "Scale one canonical Dataset variable.",
  "version": "1.0.0",
  "group": "Research",
  "license": "GPL-3.0-or-later",
  "profile": "A",
  "language": "Python",
  "source": "scale_signal.py",
  "sources": [
    {
      "id": "primary",
      "required": true,
      "contracts": "timeseries.table"
    }
  ],
  "bindings": [
    {
      "id": "signal",
      "label": "Signal variable",
      "required": true
    }
  ],
  "fields": [
    {
      "id": "scale",
      "type": "number",
      "label": "Scale",
      "default": "2",
      "required": true
    }
  ],
  "required_apis": [
    "DATASET_VARIABLE_SCHEMA_API_v3@3",
    "CANONICAL_DATASET_API_v2@2"
  ],
  "outputs": {
    "datasets": ["research.scale_signal.derived"],
    "files": []
  }
}

4.1 Campi essenziali

CampoFunzioneRegola principale
idID stabile del moduloDeve iniziare con una lettera; ammessi lettere, cifre, punto, underscore e trattino.
versionVersione del moduloFormato esatto major.minor.patch.
name, description, group, licenseMetadata del descriptorObbligatori e a singola riga.
profileProfilo di maturitàA oppure B.
languageRuntime scientificoPython oppure Octave.
sourceSorgente autorevoleDeve esistere ed avere estensione coerente: .py o .m.

5. New from script e New from registered

5.1 New from script…

Scegli direttamente un .py o .m. Il Builder:

5.2 New from registered…

Questa strada parte da un script.ini già registrato nella Script Library o nella Sessione. Il Builder legge metadata, language e required_apis, trova source.py oppure source.m accanto al registry e ne calcola il SHA-256.

Quando scegliere l'una o l'altra
Usa New from script per un file di ricerca esterno. Usa New from registered quando il lavoro è già passato dal workflow degli Script Workspace e vuoi trasformare quella copia registrata in un modulo.

6. Module details

Finestra Module details del Script Module Builder
Dialog Details…: ID, nome, descrizione, versione, gruppo, licenza, Profile e Language.

Il cambio di lingua non converte il sorgente: la sorgente deve già avere l'estensione corretta. Un progetto Python deve puntare a un .py; un progetto Octave a un .m.

Versione
Il Builder rifiuta di sovrascrivere uno ZIP già esistente. Se sorgente o contratto cambiano, incrementa la versione e crea un nuovo package.

7. Analysis Sources

Le Analysis Sources sono i Dataset logici richiesti dal modulo. Devono includere primary, che deve essere required.

ProprietàSignificato
idNome logico della sorgente, per esempio primary, reference, calibration.
requiredSe il Dataset deve essere selezionato prima del Run.
contractsContratti Dataset ammessi, separabili con ;.
labelEtichetta leggibile mostrata all'utente.
purposeDescrizione dello scopo della sorgente.
dataset_idDataset canonico preferito/default, se registrato e compatibile.

Il modulo generato usa il normale Analysis Source Map; non viene creato un meccanismo alternativo.

8. Dichiarare le Analysis Sources direttamente nello script

Python e Octave possono dichiarare le sorgenti con una singola riga JSON UTF-8. La discovery legge il testo: non importa e non esegue lo script.

Python

# GX-TXT-ANALYSIS-SOURCES-V1: {"api_version":1,"sources":[{"id":"primary","label":"Measured series","required":true,"contracts":["timeseries.table"],"purpose":"Data to analyze"},{"id":"reference","label":"Reference spectrum","required":false,"contracts":["spectrum.table"],"purpose":"Optional comparison"}]}

GNU Octave

% GX-TXT-ANALYSIS-SOURCES-V1: {"api_version":1,"sources":[{"id":"primary","label":"Measured series","required":true,"contracts":["timeseries.table"],"purpose":"Data to analyze"},{"id":"reference","label":"Reference spectrum","required":false,"contracts":["spectrum.table"],"purpose":"Optional comparison"}]}

Regole principali: massimo una dichiarazione; primary presente e required; ogni sorgente ha id, label, booleano JSON required e array non vuoto contracts. purpose e preferred_dataset sono opzionali.

Sicurezza della discovery
Il parser autorevole è framework-owned e lavora sul file come testo. La riga di metadata non può quindi eseguire codice di ricerca durante la creazione del progetto.

9. Quando script e progetto dichiarano sorgenti diverse

Module Builder con conflitto fra Analysis Sources del progetto e dello script
Il Builder blocca la validazione finché il conflitto non viene risolto esplicitamente.

Le due scelte sono:

Use script declaration

Le sorgenti del progetto vengono sostituite con quelle dichiarate dal sorgente autorevole.

Keep manual source settings

Mantieni le impostazioni manuali. Il Builder registra la scelta insieme al fingerprint SHA-256 della dichiarazione esaminata.

Se in seguito cambia la dichiarazione nello script, il fingerprint non coincide più e il conflitto deve essere riesaminato. Questo impedisce che una vecchia decisione manuale resti valida silenziosamente dopo una modifica del contratto.

10. Variable bindings

Add variable… crea un normale variable selector del framework. I campi sono ID, Visible label, Required e Semantic role opzionale.

A runtime la selezione appare in ctx.parameters come valore qualificato dalla sorgente, per esempio primary.measured_V. Lo script deve risolvere il Variable ID stabile attraverso l'API pubblica dello schema Dataset prima di leggere i dati canonici.

Perché non usare il nome della colonna fisica
Il binding rappresenta identità scientifica e selezione utente. Il file CSV/HDF5 e i suoi nomi fisici sono dettagli del provider di storage, non l'interfaccia del modulo.

11. Configuration fields

Dialog Configuration field del Module Builder
Il dialog crea i campi comuni. Per strutture avanzate, in particolare le colonne delle tabelle, il JSON è l'autorità finale.

Tipi supportati dal Builder 1.0.2:

TipoUso tipico
datasetSelettore Dataset.
selectionSelezione persistente del framework.
temporal_setSet/intervalli temporali.
number, integerParametri numerici.
string, textTesto breve/lungo.
booleanFlag.
choiceScelta da lista; richiede values.
file, pathRisorse/file selezionati dall'utente.
unitSelettore unità.
modelRiferimento a un modello registrato.
tableTabella ripetibile nativa del framework.

12. Repeatable table

Il Builder 1.0.1+ genera colonne native del normale editor tabellare. Il dialog consente di iniziare rapidamente, ma per assegnare tipo, source e altri dettagli alle singole colonne conviene modificare il JSON.

{
  "id": "samples",
  "type": "table",
  "label": "Samples",
  "min_rows": 1,
  "columns": [
    {
      "id": "variable",
      "type": "variable",
      "source": "primary",
      "required": true
    },
    {
      "id": "weight",
      "type": "number",
      "default": "1"
    },
    {
      "id": "mode",
      "type": "choice",
      "values": "include;exclude"
    }
  ]
}

Tipi di colonna ammessi: variable, model, choice, integer, number, string, text, unit.

In Python le righe arrivano in ctx["parameters"]["samples"] come lista di dizionari. In Octave la stessa struttura arriva in ctx.parameters.samples tramite il Bridge. I numeri nelle celle sono stringhe e vanno convertiti dal codice scientifico quando necessario.

13. Required APIs

Require API… aggiunge una dichiarazione di preflight. Ogni API pubblica effettivamente usata dallo script dovrebbe essere dichiarata.

Forma generale:

API_ID@major:provider+capability|capability

Provider e capability sono opzionali. Esempi:

CANONICAL_DATASET_API_v2@2
DATASET_VARIABLE_SCHEMA_API_v3@3
DATASET_PUBLICATION_API_v2@2
PLOT_DATASET_API_v3@3:plot.dataset+plotspec|render

Il Bridge verifica i requisiti prima del calcolo scientifico. Se un requisito non è disponibile, il Run fallisce con diagnostica invece di proseguire in modo parziale.

14. gxtxt_context(): inputs e parameters

inputs

Contiene le Analysis Sources risolte. Esempio: ctx["inputs"]["primary"]["dataset_id"].

parameters

Contiene config fields e variable bindings risolti. Esempio: ctx["parameters"]["scale"] e ctx["parameters"]["signal"].

14.1 Python

# GX-TXT-ANALYSIS-SOURCES-V1: {"api_version":1,"sources":[{"id":"primary","label":"Measured series","required":true,"contracts":["timeseries.table"],"purpose":"Dataset to transform"}]}

from gxtxt import gxtxt_context, gxtxt_api_require, gxtxt_api_call

gxtxt_api_require([
    "DATASET_VARIABLE_SCHEMA_API_v3@3",
    "CANONICAL_DATASET_API_v2@2",
    "DATASET_PUBLICATION_API_v2@2",
])

ctx = gxtxt_context()
dataset_id = ctx["inputs"]["primary"]["dataset_id"]
signal_name = ctx["parameters"]["signal"].split(".", 1)[-1]
scale = float(ctx["parameters"]["scale"])

variables = gxtxt_api_call(
    "DATASET_VARIABLE_SCHEMA_API_v3", "list", [dataset_id]
)
signal_id = next(
    item["variable_id"] for item in variables
    if item["canonical"] == signal_name
)

block = gxtxt_api_call(
    "CANONICAL_DATASET_API_v2",
    "read_range",
    [dataset_id, [signal_id], 0, 0],
)

values = block[signal_id]["values"]
scaled = [float(value) * scale for value in values]

# Publish with the public Dataset Publication API.
# The exact publication payload depends on the Dataset contract you choose.
print(f"Prepared {len(scaled)} scaled values.")

14.2 GNU Octave

% GX-TXT-ANALYSIS-SOURCES-V1: {"api_version":1,"sources":[{"id":"primary","label":"Measured series","required":true,"contracts":["timeseries.table"],"purpose":"Dataset to transform"}]}

gxtxt_api_require({
  'DATASET_VARIABLE_SCHEMA_API_v3@3',
  'CANONICAL_DATASET_API_v2@2'
});

ctx = gxtxt_context();
dataset_id = ctx.inputs.primary.dataset_id;

parts = strsplit(ctx.parameters.signal, '.');
signal_name = parts{end};
scale = str2double(ctx.parameters.scale);

variables = gxtxt_api_call(
  'DATASET_VARIABLE_SCHEMA_API_v3',
  'list',
  {dataset_id}
);

signal_id = '';
for k = 1:numel(variables)
  if (strcmp(variables{k}.canonical, signal_name))
    signal_id = variables{k}.variable_id;
    break;
  endif
endfor

block = gxtxt_api_call(
  'CANONICAL_DATASET_API_v2',
  'read_range',
  {dataset_id, {signal_id}, 0, 0}
);

values = block.(signal_id).values;
scaled = values .* scale;
printf('Prepared %d scaled values.\n', numel(scaled));
Runtime portabile
Lo script installato non deve dipendere dalla directory originale del ricercatore. Il Builder porta con sé il main script e il bundle, e il shared runner fornisce il contesto necessario.

15. Output e pubblicazione

Dialog Outputs and documentation del Module Builder
Outputs & notes… dichiara Dataset ID attesi, file attesi e note del ricercatore.

La dichiarazione outputs serve a descrivere ciò che il modulo dovrebbe produrre. La pubblicazione effettiva deve avvenire tramite le API pubbliche appropriate.

16. Bundle e risorse

Il bundle serve per helper, tabelle di lookup e risorse statiche che devono viaggiare insieme allo script.

"bundle": [
  {"source": "helper.py", "target": "helper.py"},
  {"source": "reference/coefficients.csv",
   "target": "reference/coefficients.csv"}
]

Il Builder copia ogni file byte-per-byte e crea un inventario SHA-256. Gli helper di codice devono usare lo stesso linguaggio del main script. I target devono essere relativi e sicuri: niente path assoluti, .. o collisioni case-insensitive.

Python

Gli helper sono importabili dal bundle directory per la durata del Run. Le risorse statiche sono raggiungibili da ctx["bundle_dir"].

Octave

Il bundle directory viene aggiunto temporaneamente al path Octave del Run; la risorsa è in ctx.bundle_dir.

Il bundle non viene aggiunto a un path globale e non crea dipendenze permanenti dall'ambiente originale.

17. Profile A e Profile B

ProfiloScopoRequisiti
APackaging di un research workflow.Può usare normali librerie scientifiche Python/Octave e mantenere l'impostazione di ricerca originaria.
BTarget esplicito di produzione.Richiede almeno scientific_method; è pensato per metodo dichiarato, input/output chiari, test più forti e uso appropriato dei servizi pubblici.
Nessuna “promozione” matematica automatica
Il Builder non riscrive un Profile A per farlo sembrare Profile B. Il passaggio di maturità scientifica rimane responsabilità del progetto.

18. API pubblica opzionale

Questa è una funzione avanzata disponibile nel JSON. Se aggiungi public_api, il Builder genera registrazione Tcl, documentazione API e, per le operazioni opt-in, un provider-owned Script Bridge binding.

"public_api": {
  "id": "RESEARCH_SCALE_SIGNAL_API_v1",
  "version": 1,
  "name": "Scale Signal API",
  "capabilities": ["structured_analysis_run"],
  "operations": [
    {
      "id": "run",
      "summary": "Run the scale analysis.",
      "result_contract": "execution receipt struct",
      "read_only": false,
      "script_bridge": true,
      "arguments": [
        {
          "name": "dataset_id",
          "kind": "Dataset ID",
          "required": true,
          "target": "source.primary"
        },
        {
          "name": "scale",
          "kind": "number",
          "required": true,
          "target": "config.scale"
        }
      ]
    }
  ]
}

Regole importanti:

19. Validate

Validate salva il progetto e controlla che la descrizione sia coerente prima di costruire lo ZIP. Fra i controlli implementati:

Identity

ID valido, versione semantica a tre componenti, metadata obbligatori, Profile e Language validi.

Source

File esistente, estensione coerente con il linguaggio, niente symlink del main source.

Analysis Sources

ID univoci, primary presente e required, contratti validi e conflitto declaration/manual risolto.

Fields e bindings

ID univoci, tipi supportati, choice con values, table con colonne valide e min/max rows coerenti.

APIs

Formato delle requirement e struttura della public API opzionale.

Profile B

Presenza della documentazione scientific_method.

In caso di successo la status line mostra linguaggio e SHA-256 del sorgente autorevole.

20. Build ZIP

Build ZIP ripete la validazione e crea il package nella directory scelta. Il nome è:

<module-id>_<version>.zip

Accanto allo ZIP viene scritto un file .zip.sha256. Se lo ZIP o il relativo checksum esistono già, il Builder rifiuta la sovrascrittura.

Il package è costruito in ordine deterministico, con timestamp ZIP stabilizzato, e contiene checksum sia dei file del bundle sia del payload complessivo.

21. Contenuto del pacchetto generato

research.scale_signal_1.0.0.zip ├── module.ini ├── plugin-package.ini ├── MANUAL.md ├── CHANGELOG.md ├── LICENSE ├── builder-project.json ├── SHA256SUMS.txt ├── bundle/ │ ├── main.py # oppure main.m │ ├── helper.py # se dichiarato │ ├── reference/ │ │ └── coefficients.csv │ └── SHA256SUMS └── api/ # solo se public_api è presente ├── public_api.tcl ├── PUBLIC_API.md └── script_bridge_binding.py # se almeno una operation usa script_bridge

Il builder-project.json interno è reso portabile: i percorsi del source e dei bundle puntano alle copie presenti nel package e viene aggiunto source_sha256.

Rebuild riproducibile
Conservando il progetto e il sorgente puoi ricostruire il modulo senza dipendere dalla directory originaria. Il package stesso conserva anche un progetto portabile.

22. Installazione e Run

Build ZIP→Plugins → Install plugin→Modules → Enable→Analysis → Configure→Run

Il modulo generato usa runner=script_module. La GUI Analysis viene prodotta dai descriptor standard, non da Tcl/Tk personalizzato.

Ogni esecuzione registra in provenance almeno snapshot del sorgente, stato, module version, language, required APIs e SHA-256 del source.

23. Tutorial completo: creare un modulo Python

1
Scrivi scale_signal.py. Inserisci, se utile, la riga GX-TXT-ANALYSIS-SOURCES-V1.
2
Apri Modules → Script Module Builder… e premi New from script….
3
In Details… assegna ID stabile, nome, descrizione e versione. Mantieni Language=Python e Profile=A per il primo package.
4
Controlla la tabella Analysis Sources. Se la dichiarazione nello script è corretta, usala come autorità.
5
Premi Add variable… e crea il binding signal.
6
Premi Add field… e crea scale di tipo number, default 2.
7
Aggiungi con Require API… tutte le API realmente usate.
8
In Outputs & notes… dichiara gli output attesi e documenta brevemente il metodo.
9
Salva il progetto JSON e premi Validate.
10
Se la validazione è pulita, scegli Package output e premi Build ZIP.
11
Installa lo ZIP, abilita il modulo, seleziona Dataset e variabile in Analysis, imposta scale ed esegui.

24. Tutorial completo: creare un modulo GNU Octave

Il flusso GUI è identico. Cambiano il main source e il codice scientifico:

Gli helper .m del bundle vengono aggiunti solo al path temporaneo dell'esecuzione.

25. Uso da riga di comando

GUI e CLI usano la stessa implementazione.

python3 tools/gxtxt_module_builder.py validate research_module.json
python3 tools/gxtxt_module_builder.py build research_module.json /new/package/output

La CLI è particolarmente utile per rebuild ripetibili, CI locale e controllo rapido dei progetti JSON senza aprire la GUI.

26. Errori comuni

Messaggio / sintomoCausa tipicaCorrezione
module ID must start with a letter...ID non validoUsa lettere/cifre/punto/underscore/trattino e inizia con una lettera.
version must be major.minor.patchVersione incompletaUsa ad esempio 1.0.0.
authoritative source must be an existing .py/.m filePath o language erratoCorreggi source oppure Language.
sources must include primaryManca source principaleAggiungi primary required.
Builder sources conflict...Script declaration diversa dal JSONUsa i pulsanti di review e scegli esplicitamente script o manual.
choice field ... needs valuesChoice senza listaImposta valori separati da ;.
table field ... needs a nonempty columns listTable senza colonneAggiungi almeno una colonna.
Profile B requires scientific_methodProfile B incompletoDocumenta il metodo scientifico nel JSON.
refusing to overwrite ...zipVersione già costruitaIncrementa versione o usa una nuova directory di output.
Run fallisce prima del calcoloRequired API non disponibileControlla ID/versione/provider/capability dichiarati.

27. Checklist finale

  1. Il main source è la copia scientificamente autorevole e non è un symlink.
  2. Module ID e versione sono stabili e corretti.
  3. primary è presente e required.
  4. Ogni Dataset necessario è una Analysis Source, non un path privato.
  5. Ogni variabile scelta dall'utente è un binding standard.
  6. I parametri modificabili sono fields standard.
  7. Le table hanno colonne tipizzate coerenti nel JSON.
  8. Tutte le API pubbliche usate sono dichiarate in required_apis.
  9. I file ausiliari necessari sono nel bundle.
  10. Gli output sono dichiarati e vengono pubblicati tramite API appropriate.
  11. Un eventuale conflitto Analysis Sources è stato risolto esplicitamente.
  12. Profile B contiene scientific_method.
  13. Validate passa prima del Build.
  14. La versione viene incrementata quando cambia source o contratto.
  15. Dopo l'installazione viene eseguito almeno un Run reale in una Sessione di prova.

28. Provenienza tecnica della guida

La guida è stata preparata sulla copia GX-TXT 0.9.8.10-dev-031 e sul modulo tool.script_module_builder 1.0.2, verificando module.ini, MANUAL.md, README.md, CHANGELOG.md, la guida framework docs/help/script_module_builder.md, la dichiarazione SCRIPT_ANALYSIS_SOURCES_API_v1 e l'implementazione runtime/builder.py.

Le immagini della GUI sono ricostruzioni eseguite direttamente sulla struttura e sulle etichette definite dall'implementazione dev-031. Nel sito statico sono distribuite come asset immagine separati.