Skip to content

Releases: bgarcevic/tomix

v0.13.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 08:20
1e8b18e

Added

  • tx deploy checks the deployed model after it lands: it re-reads the target and reports every
    object the server holds in an error, incomplete, or unprocessed state, in the text output and
    as validation in the JSON result. Objects in an error state (a measure whose DAX does not
    resolve, a broken RLS filter) fail the deploy with exit code 1 and
    TOMIX_DEPLOY_VALIDATION_FAILED, even though the model is deployed; incomplete objects warn
    (TOMIX_DEPLOY_VALIDATION_WARNINGS); unprocessed ones point at tx refresh. A check that
    cannot run warns with TOMIX_DEPLOY_VALIDATION_UNAVAILABLE. --ci vsts|github now prints
    annotations for post-deploy errors and warnings.
  • tx deploy --rollback-on-error checks the deployed model before the deploy is kept. On an
    existing model the deploy runs inside a server transaction and rolls back when an object is in
    an error state, leaving the target's definition and data unchanged. A new model is deleted
    again. A rolled-back deploy fails with TOMIX_DEPLOY_ROLLED_BACK and "status": "rolled-back".
    See ADR 0005.
  • tx format style options (#229): --separators us|eu shows DAX with ; list and ,
    decimal separators (display only; models always store the US form, and an explicit
    --separators eu with --save, --save-to, --stage or --revert fails with the new
    TOMIX_FORMAT_SEPARATORS_DISPLAY_ONLY), --function-spacing space|none drops the space
    before a DAX call's parenthesis, and --short undoes --long. Each has a config key
    (format.separators, format.functionSpacing, format.lines) that the flag overrides.
    Golden files pin the printed output for each style.
  • tx bpa run --vpax <file.vpax> reads VertiPaq statistics from a file exported with
    tx vertipaq --export, so statistics rules run on a model file, a read-only connection, or in
    CI without annotating the model. The statistics apply in memory only. A file that matches no
    table fails the run (TOMIX_BPA_VPAX_MISMATCH); tables missing from the model warn
    (TOMIX_BPA_VPAX_PARTIAL) (#234).
  • New default-off vertipaq ruleset preset with every bundled rule that reads statistics,
    including two new rules: LARGE_SHARE_OF_MODEL_SIZE and
    UNUSED_HIDDEN_HIGH_CARDINALITY_COLUMNS. Rules can read model-level annotations through
    Model.GetAnnotation(...) (#234).

Changed

  • FIX_REFERENTIAL_INTEGRITY_VIOLATIONS, AVOID_BI-DIRECTIONAL_RELATIONSHIPS_AGAINST_HIGH-CARDINALITY_COLUMNS
    and LARGE_TABLES_SHOULD_BE_PARTITIONED move to the vertipaq preset (category VertiPaq),
    out of standard and full. bpa run without --ruleset and the deploy BPA gate add the
    vertipaq preset when the model has statistics (Vertipaq_* annotations or --vpax), so an
    unannotated model no longer lists them as "Not checked". A named --ruleset is used as given:
    --ruleset standard now skips them (#234).

Fixed

  • tx test --tolerance (and tx: tolerance=) now applies to measures whose data type is Variant.
    Their results read back as object columns, which compared exactly, so floating-point noise
    failed the test whatever the tolerance. Cells compare within the tolerance when both sides are
    numbers; text, dates and booleans still compare exactly. --ignore-row-order sorts these
    columns by value after the dimension columns, in a fixed BLANK, number, text order.

What's Changed

  • feat(bpa): read VertiPaq statistics from .vpax and add a vertipaq preset by @bgarcevic in #464
  • feat(format): style options for separators, function spacing, and line length by @bgarcevic in #465
  • feat(deploy): post-deploy validation reporting in result and JSON by @bgarcevic in #467
  • build: Bump the nuget-minor-patch group with 7 updates by @dependabot[bot] in #468
  • feat(deploy): --rollback-on-error validates inside a transaction and rolls back by @bgarcevic in #469
  • fix(test): apply tolerance to Variant (object) measure columns by @bgarcevic in #471
  • chore(release): prepare 0.13.0 by @github-actions[bot] in #466

Full Changelog: v0.12.1...v0.13.0

v0.12.1

Choose a tag to compare

@github-actions github-actions released this 18 Oct 19:55
84e2181

Fixed

  • Sign-in and tx's own HTTP requests no longer hang on networks that advertise IPv6 they cannot
    route: connections race IPv6 and IPv4 the way browsers do (Happy Eyeballs), so tx auth login
    falls back to IPv4 within a quarter of a second instead of timing out. A spinner waiting on a
    remote host (auth login, connect, deploy, query) now says which host after 10 seconds and that
    Ctrl+C cancels.

What's Changed

  • chore: rename repository to tomix by @bgarcevic in #461
  • fix(net): race IPv6 and IPv4 so broken-IPv6 networks don't hang sign-in by @bgarcevic in #462
  • chore(release): prepare 0.12.1 by @github-actions[bot] in #463

Full Changelog: v0.12.0...v0.12.1

v0.12.0

Choose a tag to compare

@github-actions github-actions released this 15 Oct 18:40
0149587

Added

  • tx rm removes several objects as one change: pass several paths, or --from <file|-> with
    JSON Lines ({"type", "table"?, "name"} or {"path"}) or plain paths. Every kind rm
    supports can be mixed. All targets resolve before anything changes, the dependency guard
    judges the whole set regardless of order, targets inside another target are folded into it,
    and cascades onto surviving objects need --cascade. One validation, one save, one undo step.
    New error codes TOMIX_RM_NEEDS_CASCADE and TOMIX_RM_INPUT_INVALID.
  • tx rm refuses to remove a shared expression that surviving Power Query (M) still reads (M
    partitions, other shared expressions, refresh policy queries), using the bundled M parser.
    JSON adds brokenMReferences; --force overrides.
  • tx validate checks Power Query (M) partition sources and shared expressions offline with
    the bundled M parser, and reports each one that does not parse as an M0001 error with its
    line and column. --no-m (MCP: "m": false) skips the check (#453).
  • tx test --tolerance <value> accepts numeric cells within an absolute difference (0.001) or a
    percentage of the larger value (0.1%), so floating-point noise in averages and ratios no
    longer fails a test. --ignore-row-order sorts both rowsets before comparing, so test queries
    need no ORDER BY. A test overrides either option in a // tx: comment line before its query
    (// tx: tolerance=0.01% ignore-row-order); an unknown directive fails the test.
  • tx test --update-missing records snapshots only for tests that have none yet and compares the
    rest, so adding a test no longer means re-accepting the whole suite. tx test --update now lists
    what it accepted: each rewritten snapshot shows a Before/After table of the cells that changed
    (differences in JSON). Snapshots left behind by a deleted or renamed test are reported as
    orphans (orphans in JSON) without failing the run (#451).
  • A BPA fix expression can assign a quoted string literal as written, with \" and \\
    escapes, so a model-provided rule can set DAX (Expression = "DIVIDE([A], [B])"). An
    unquoted value with ( or [ is still an unsupported fix expression (#208).

Changed

  • tx test snapshots (.expected.json) are written with one column and one row per line, so a
    changed value diffs as its whole row instead of a bare value. Existing snapshots still load;
    the next --update rewrites them in the new layout without changing their content.
  • tx get <object> --output-format tmdl|bim|tmsl prints the object through the model's own
    serializer instead of a hand-built skeleton, so fragments keep descriptions, format strings,
    display folders, lineage tags, annotations and child objects. A TMDL table child is wrapped in
    ref table <name> and pastes into its table's .tmdl file as is. Relationships, roles,
    hierarchies, functions and the other kinds print as fragments instead of the property view,
    and tx get . prints the whole model. A model source without a serializer fails with
    TOMIX_SCRIPT_UNSUPPORTED (#243).
  • The tx bpa run --fix preview groups pending fixes by rule and shows a property change once
    over every object that gets it (IsHidden: false → true over a list of columns, capped at 10
    unless --full), quoting only text values. An expression fix shows full Before/After blocks,
    DAX syntax-highlighted in a terminal and plain when piped, capped at 12 lines each, instead of
    one line cut at 60 characters (#208).
  • A BPA finding is marked fixable (canFix in JSON) only when tx can run its rule's fix
    expression. Under --fix, a rule whose fix tx cannot run (such as
    Partitions[0].Name = it.Name) is listed once with its finding count (unsupportedFixes in
    JSON) instead of adding one "Unsupported fix expression" fix error and one skip per object.
  • tx connect -w checks whether the workspace target already exists by listing the workspace's
    models instead of downloading the target's whole model, so the step after the model picker is
    fast on large models. A dataset that the list hides but that exists (read-only access) is still
    reported instead of being treated as a new mirror (#142).

Fixed

  • A lone [Col] in DAX resolves to the tables DAX can bind it to, instead of the first table
    with a column of that name: the innermost table iterated around it that has the column
    (SUMX('Fact A', [Revenue]) reads 'Fact A'[Revenue], even in a measure of a table with its
    own [Revenue]), and the expression's own table (SUM([Revenue]), a calculated column's row).
    tx rm no longer refuses to remove Sales[Date] because DateTableTemplate's YEAR([Date])
    reads its own Date, and tx deps and rename fixups follow the right columns. Where the
    binding is unknown (a table expression without a rule, EARLIER), every table's column of that
    name still counts, so a removal blocks rather than breaking a reference.
  • BPA follows the same rule: ReferencedBy counts a lone [Col] only for the tables it may bind
    to, so a dead Sales[Date] is no longer kept alive by DateTableTemplate's YEAR([Date]), and
    the DAX_COLUMNS_FULLY_QUALIFIED fix qualifies such a reference with the one table DAX binds it
    to instead of refusing because other tables share the name. It still refuses when two tables
    remain possible.
  • tx validate judges a lone [Col] by the tables DAX can bind it to; it used to pass if any
    table had the column. Outside every iterator, in a measure, calculated column or role filter, a
    column only another table has is a new DAX0010 error (DISTINCTCOUNT([Region]) in a Sales
    measure when only Geo has Region), which DAX rejects too. Inside an iterator that does not
    provide it, it is a DAX0003 warning. Window functions' ORDERBY/PARTITIONBY columns count
    as rows of their relation. Both messages name the qualified columns to use instead.
  • Help for subcommands such as tx stage commit, tx auth login, tx config set and
    tx skills install now shows an Examples: block. The tx auth login service-principal example
    uses -u for the app id instead of --client-id. The reference docs list every shipped option,
    including format --type, save --no-sync and the bpa run staging flags, and no longer show
    -p/-t aliases that tx auth login does not have (#148).

What's Changed

  • feat(get): emit TMDL, BIM and TMSL through the TOM serializer by @bgarcevic in #449
  • feat(validate): report Power Query (M) syntax errors offline by @bgarcevic in #455
  • feat(test): numeric tolerance and order-insensitive comparison by @bgarcevic in #454
  • feat(test): safer snapshot recording with --update-missing, accepted diffs and orphans by @bgarcevic in #456
  • perf(connect): classify the mirror target from the database list by @bgarcevic in #457
  • docs: guard option-level drift and add subcommand help examples by @bgarcevic in #459
  • feat(bpa): grouped --fix preview with highlighted DAX before/after by @bgarcevic in #458
  • feat(rm): batch removal with whole-set guard and Power Query references by @bgarcevic in #460
  • chore(release): prepare 0.12.0 by @github-actions[bot] in #450

Full Changelog: v0.11.0...v0.12.0

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 10:50
cefb99b

Added

  • tx query checks the tables, columns and measures a DAX query names before sending it. A
    typo fails at once with TOMIX_QUERY_UNKNOWN_REFERENCE and the closest name
    (Did you mean 'Amount'?), or the table's columns or the model's tables when nothing is
    close, instead of a server error. Names the query defines itself are understood;
    --no-validate skips the check (#240).
  • tx query --cold reports TOMIX_QUERY_COLD_UNAVAILABLE when it cannot clear the cache, and
    --trace reports TOMIX_QUERY_TRACE_UNAVAILABLE when it cannot capture server timings, so
    the JSON output says so too, not only a stderr line.

Changed

  • Edits and undo in a live session (tx shell, tx serve, tx mcp, tx ui) are faster on
    large models: the session copies the model for the next undo step in the background after
    each edit instead of during it. On a model with 1,000 measures an edit drops from about
    100 ms to about 50 ms and undo from about 55 ms to about 30 ms (#423).
  • The undo history of a live session is capped by model size as well as by count, so a large
    model keeps fewer than 50 steps and the session's memory stays near 250 MB (#423).
  • Text output uses color more sparingly. Labels in key-value blocks (auth status, doctor,
    diff, connect, validate, vertipaq, …) are plain instead of bold, with the values lined
    up in one column. Progress lines and notices such as "Authenticating..." and where
    credentials were saved are dim. Placeholders in --help (<path>, [options]) are dim too
    (#440).
  • With stdin piped ($secret | tx auth login --password -), a command's progress label prints
    once, dim, on stderr instead of as plain text on stdout (#440).

Fixed

  • tx query and tx test work with read access only (the Viewer role with Build permission).
    They used to fail with Database not found, because the server lists only the models a
    caller can write to. Commands that read the model's metadata now fail with TOMIX_METADATA_ACCESS_DENIED
    instead, naming the write access they need. The docs no longer say --trace and --cold
    need admin rights: write access (workspace Admin, Member or Contributor) is enough.

  • A wrong model name on a Power BI workspace fails with TOMIX_DATABASE_NOT_FOUND instead of
    TOMIX_CONNECT_FAILED and a raw (404) Not Found.

  • tx validate checks each row-level security filter on its own table permission
    (Roles/<role>/<table>). It used to parse a role's filters joined as Table: <filter> lines,
    so a role with more than one filter could fail with Unexpected ':' after the end of the expression (DAX0007). Renaming a column or table now rewrites the RLS filters that use
    it instead of only warning, and BPA rules see filters that span several lines whole.

  • tx validate, tx deps and rename fixup also cover calculation group no-selection and
    multiple-or-empty-selection expressions and calculation item format string expressions.

  • tx bpa run checks rules scoped to TablePermission, which it used to skip: the dynamic RLS
    rule (full ruleset) now reports roles that filter on USERPRINCIPALNAME() or USERNAME(),
    and DAX_COLUMNS_FULLY_QUALIFIED checks RLS filters, with --fix qualifying their column
    references. A permission is reported as <role>/<table>.

  • Reference tracking (deps, validate, rename and remove guards, BPA) now reads DAX with the
    same lexer as tx format and dax check, so a date literal (dt"2024-01-01") or a query
    parameter (@Risk) is no longer taken for a table named dt or Risk (#204).

  • The tx deploy preview no longer reports a calculated column as modified when its source
    has no dataType (as Power BI Desktop writes it) and the deployed model holds the type the
    engine inferred, for example datetime, calculated to unknown, calculated.

  • A modified object in tx diff and the tx deploy preview now prints as
    ~ CalculatedColumn Calculations/Date: DataType, so the changed property no longer reads as
    part of the object's name (Calculations/Date Detail). A column's type change is labelled
    DataType in text output; JSON keeps Detail.

  • -s/--server and tx connect now reach an on-premises Analysis Services server as typed
    (ssas01.contoso.com, 10.0.0.5, ssas01:2383, ssas01.contoso.com\TABULAR, or a full
    MSOLAP connection string) with your Windows identity, instead of prefixing it with
    powerbi://api.powerbi.com/v1.0/myorg/ and sending the deploy to Power BI. deploy warns
    (TOMIX_DEPLOY_AMBIGUOUS_SERVER) when a dotted two-part name such as Sales.Prod could also
    be a workspace name.

What's Changed

  • fix(validate): check each RLS filter on its table permission by @bgarcevic in #448
  • chore(release): prepare 0.11.0 by @github-actions[bot] in #447

Full Changelog: v0.10.0...v0.11.0

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 05:34

Added

  • tx mcp serves a model session to AI agents (Claude Code, Codex, Cursor and others) as Model
    Context Protocol tools on stdio: claude mcp add tomix -- tx mcp. Each tool calls the session
    protocol method of the same name, so an agent's edit is one undo step, and
    transaction_begin/transaction_commit group several under a label. When tx ui holds the
    model, tx mcp joins that session, so you watch, undo and save the agent's work in the page.
    Every tool says whether it writes (readOnlyHint, destructiveHint), and --read-only lists
    only the ones that change nothing (#354). The server tells the agent to save a TMDL folder or
    .bim file once its checks pass, and to ask before saving to a server or Power BI Desktop.

  • tx skills install, status, and uninstall install the tomix agent skill for Claude Code
    (.claude/skills/tomix) and Codex and other Agent Skills harnesses (.agents/skills/tomix),
    in the repository or with --user in your home folder. The skill ships inside the binary, so it
    matches the installed tx. status reports copies from another version as outdated, and copies
    that were edited or not written by tx are left alone unless you pass --force
    (TOMIX_SKILL_CONFLICT). The skill covers live sessions too: edit through the tx mcp tools
    rather than the files while a session is open. A new guide, "Using tomix from your agent",
    covers setup, including watching an agent's edits in tx ui (#404).

  • A client of a live session (tx serve, tx ui) can ask in initialize for
    capabilities.diagnostics. The host then recomputes dependencies, DAX diagnostics and,
    with { "bpa": true }, BPA findings 250 ms after the last change and sends
    diagnostics.updated; dax.check and bpa.run answer from those results. deps.get,
    dax.check and bpa.run now read the last committed version instead of waiting for
    another client's transaction (#350).

  • A live session (tx interactive, tx serve, tx ui) on a TMDL folder or .bim file now
    notices when the files change outside it, for example by a git checkout or another editor.
    The session turns stale, and saving fails with TOMIX_SESSION_STALE instead of overwriting
    that change. reload (protocol: session.reload) takes the files' version, and
    save --force (session.save with force) keeps the session's. The tx ui page offers
    both (#351).

  • A live session on a server or Power BI Desktop now notices when the model changes there
    outside it (checked every 10 seconds for Desktop, 30 for a remote server): it turns stale, and save fails with
    TOMIX_SESSION_STALE until save --force. session.status reports canReload (#351).

  • A live session whose Power BI Desktop has closed fails with
    TOMIX_SESSION_SOURCE_UNAVAILABLE instead of a raw connection error; save -o <folder>
    still writes its changes to files. The shell, status (protocol: sourceUnavailable) and
    the tx ui page say so as soon as a check finds it gone (#351).

  • tx refresh on a PBIP's files (the .pbip, its .SemanticModel folder, or anything in it)
    now refreshes the model in the Power BI Desktop that has that PBIP open, as Tabular Editor
    does, instead of failing with TOMIX_REFRESH_NO_REMOTE_TARGET. It says so with
    TOMIX_REFRESH_IN_DESKTOP.

Changed

  • tx now colors its output with your terminal theme's own ANSI colors instead of a fixed
    RGB palette, so it matches Campbell, Dark+, Solarized, high-contrast and color-blind-friendly
    themes. Color is kept for status (red, yellow, green) and DAX and M highlighting; names,
    paths and values print plain, options bold, and secondary text dimmed. DAX keywords are
    magenta, functions bright blue, measure references cyan, and literals green; tables,
    columns and variables are no longer colored. Help section headings are bold and
    uppercase (USAGE, DISCOVER), and the command and option names under them regular weight. The tx ui page moves to warm neutrals with a single persimmon accent.

Fixed

  • save in a live session on a server or Power BI Desktop sends the changes to the server
    instead of failing with TOMIX_SAVE_OUTPUT_REQUIRED, and save -o naming the session's own
    files saves in place, so it no longer skips the check for changes made outside the session
    (#351).
  • A command on a Power BI Desktop that has closed fails at once with TOMIX_DESKTOP_NOT_RUNNING
    and a hint to reopen it, instead of waiting about 4 seconds for a raw socket error.
    Opening a session (tx interactive, tx serve, tx ui) there, or on a server it cannot
    reach, reports the connection error instead of "Unexpected error" (#351).
  • Tables written to a pipe or a file no longer wrap at 80 columns, and use ASCII borders
    (+, -, |) instead of box-drawing characters, as do tx deps --deep trees. A DAX
    expression or format string in tx ls output stays on one row, so it can be grepped or read
    by an agent, and borders no longer turn into mojibake in Windows PowerShell 5.1 or more.
    tx bpa run and tx bpa rules switch their symbols to ASCII there too (* for ●, x
    for ×, - for · and —, OK/FAIL for ✓/✗).

What's Changed

  • feat(session): notice files changed outside a live session; reload or keep (#351) by @bgarcevic in #403
  • feat(refresh): refresh a PBIP in the Power BI Desktop that has it open by @bgarcevic in #407
  • feat(session): notice server-side changes in a live session; clear error when Desktop is gone (#351) by @bgarcevic in #406
  • feat(session): recompute deps, DAX diagnostics and BPA after changes (#350) by @bgarcevic in #415
  • feat: agent skill, plain redirected output, and the ANSI terminal palette by @bgarcevic in #416
  • feat(mcp): tx mcp, an MCP server over the live session (#354) by @bgarcevic in #417
  • feat(output): terminal ANSI palette, ASCII BPA symbols when redirected, uppercase help headings by @bgarcevic in #418
  • feat(skill): cover live sessions, and let agents save file models by @bgarcevic in #419
  • chore(release): prepare 0.10.0 by @github-actions[bot] in #405

Full Changelog: v0.9.0...v0.10.0

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 06 Oct 06:47

The live session (tx interactive, tx serve, tx ui) is a preview: its protocol and options
may still change. A live session does not yet notice when other tools change its model's files
(for example a git checkout or an edit in Power BI Desktop), and saving from it overwrites
those changes; save or close the session before changing the files another way (#351).

Added

  • tx interactive (alias tx shell) opens a model once and keeps it in memory: commands such
    as get, set, add, rm and bpa run work on the open model, undo and redo step
    through every change, begin … commit groups edits into one undo step, history lists
    them, and save writes the model. It asks before discarding unsaved changes (#347).
  • tx serve holds a live session for editors and agents and speaks the tomix session protocol
    (JSON-RPC over stdio, specified in docs/protocol.md): open, read, edit, undo, transactions,
    save, and change events for every client (#348, #349).
  • tx ui [model] shares a live session on 127.0.0.1 with a browser page and agents at the
    same time: the page shows who is connected and every client's changes as they happen, with
    Undo, Redo and Save. --open opens the page; --port, --grace and --log tune it. Every
    request needs the session's token. tx serve on a model tx ui holds joins that session
    instead of opening a second one (#369).
  • While tx ui holds a model, add, bpa run, deps, find, format, get, ls, mv,
    replace, rm, save, set, summary and validate on it run in its session instead of
    on the files: edits become undo steps there and show up on the page, reads see unsaved
    edits, and edits stay unsaved until tx save (#400).
  • New error codes TOMIX_SESSION_IN_USE, TOMIX_UI_UNAUTHORIZED, TOMIX_UI_FORBIDDEN,
    TOMIX_UI_PORT_IN_USE and TOMIX_UI_UNREACHABLE (#369).

What's Changed

  • feat(core): live session contracts and ADR 0002 lease gate (#343) by @bgarcevic in #380
  • feat(provider-tom): change journal and TomWriter for every TOM write (#379) by @bgarcevic in #381
  • feat(provider-tom): TomLiveModelSession with a FIFO lease gate (#344) by @bgarcevic in #382
  • refactor(app): run handlers against an open session (#345) by @bgarcevic in #384
  • feat(provider-tom): undo, redo and explicit transactions in the live session (#346) by @bgarcevic in #385
  • feat(cli): tx interactive (alias tx shell), the live session REPL (#347) by @bgarcevic in #386
  • docs(protocol): tomix session protocol v0 spec (#348) by @bgarcevic in #387
  • feat(serve): tx serve over stdio (#349) by @bgarcevic in #389
  • ci(dependabot): use conventional dependency update titles by @bgarcevic in #388
  • feat(serve): one live session shared by several clients over localhost (#369) by @bgarcevic in #390
  • build: Bump Microsoft.CodeAnalysis.BannedApiAnalyzers from 4.14.0 to 5.6.0 by @dependabot[bot] in #383
  • feat(ui): tx ui shares a live session with a browser page and agents (#369) by @bgarcevic in #399
  • feat(live): one-shot commands on a model tx ui holds run in its session (#400) by @bgarcevic in #401
  • chore(release): prepare 0.9.0 by @github-actions[bot] in #402

Full Changelog: v0.8.0...v0.9.0

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 01 Oct 06:08

Added

  • tx get is now the single read command. A path naming one object shows its properties; a
    wildcard ("Sa*"), a container (Sales/Measures), or no path lists every match. New options
    select and analyze over the same path resolution: --ls, --where Prop=Value
    (case-insensitive, * wildcard, repeat to AND), --deps [upstream|downstream] with --deep
    and --max-depth, --unused with --hidden, --paths-only, and --no-multiline. tx ls
    and tx deps keep their flags and are now shortcuts for get --ls and get --deps /
    get --unused, with identical output (#335).
  • BPA rule sources beyond --rules: the bpa.rules config key and the TOMIX_BPA_RULES
    environment variable add team rule files to bpa run, bpa rules list/show/ignore, and
    the deploy BPA gate. bpa run prints a "Rules loaded" line saying where every rule came
    from and how many a later source overrode (JSON: ruleSources) (#233).
  • --ruleset presets for default-off rule categories (for example localization), which
    neither standard nor full includes. Repeat --ruleset or comma-separate it to combine
    presets (#233).
  • tx bpa rules ignore --user and unignore --user turn a rule off (or back on) just for you,
    on this machine, for every model; without --user they still write the model's ignore
    annotation. bpa rules list --ignored shows rules ignored at either level, and bpa run
    says which level ignored a rule (JSON: userIgnoredRules). unignore warns when the other
    level still ignores the rule (TOMIX_BPA_RULE_STILL_IGNORED_BY_MODEL,
    TOMIX_BPA_RULE_STILL_IGNORED_BY_USER) or when the rule isn't in the ruleset that runs
    (TOMIX_BPA_RULE_NOT_IN_RULESET) (#233).

Changed

  • Breaking: tx session is removed; tx connect covers it. tx connect now names the
    session holding the connection (JSON: a session object with id, kind, scope, path),
    tx connect --clear replaces session clear, and tx connect --clear --all forgets the
    connection in every session. session prune and session list have no replacement: each
    tx connect <target> now removes session files whose folder no longer exists (and legacy
    pid-* sessions of exited shells), and tx doctor reports any stale ones left.
  • Breaking: tx deploy and the partition-risky tx refresh variants (--refresh-type clearvalues, --skip-refresh-policy, --effective-date, --policy-only) preview by
    default. Each shows its preview (the deploy diff, or the refresh TMSL or policy-only
    summary), then asks before applying. The preview and the apply share one connection, so
    the model opens and the deploy BPA gate runs once.
    Where it cannot prompt (--non-interactive, --quiet, JSON or CSV output, redirected input)
    it stops after the preview and exits with the new exit code 3, instead of failing with
    TOMIX_CONFIRMATION_REQUIRED. Pass --yes to apply without the preview. Routine refreshes
    still run without asking. deploy --xmla only writes a script, so it no longer asks.
  • Breaking: tx bpa run --fix without --save, --save-to, or --stage is a preview: it
    lists each pending fix with before and after values, reports fixesApplied: 0, and judges the
    exit code on the model as it is.
  • tx rm, tx replace, and tx bpa run --fix --allow-delete ask for confirmation only when
    they write (--save, --save-to, --stage, or --revert). A preview no longer asks. A
    preview of rm on an object that DAX still references reports the dependents and hints
    --force instead of failing.
  • Breaking: JSON output says preview where it said dryRun: mutation results drop the
    dryRun field and the dryRun status (status is preview), bpa run reports preview
    instead of dryRun, and deploy reports status: "preview" instead of "dry-run". The refresh --policy-only preview's
    CSV column dry_run is now preview.
  • tx get Measures and other bare container paths now list the container instead of failing
    with TOMIX_OBJECT_NOT_FOUND, and tx get ./model lists the model's tables. --query or
    --deps on a path that selects a set fails with TOMIX_SINGLE_OBJECT_REQUIRED (#335).
  • tx bpa rules list shows each rule ID once, from the source that wins as in bpa run, and
    says what a team or model rule overrides (JSON: overrides); bpa rules show still prints
    every source's copy. Without a model, list and show use the active local connection (#233).
  • tx bpa rules disable and enable are hidden; they still work and do the same as
    ignore --user and unignore --user (#233).
  • Internal: validate and bpa rules now share one rule shape and one severity scale, and every
    validate issue code comes from a documented rule catalog. Output is unchanged (#230).

Fixed

  • A quoted folder path with a trailing backslash, such as tx connect '.\My Model.SemanticModel\'
    in Windows PowerShell 5.1 or ".\My Model.SemanticModel\" in cmd.exe, no longer fails with a
    stray " at the end of the path. Windows reads \" as a literal quote; tx now restores the
    path when the text before the quote is an existing folder.
  • tx format and tx add no longer wait on stdin when it is redirected but nothing is piped,
    as in a CI step, an ssh session, or a script whose parent holds stdin open. format reads a
    piped expression only when no model, --path, --save, --save-to, --stage, or
    --revert is given, so tx format ./model --save no longer blocks or formats stray stdin
    instead of the model. add reads stdin only for -e -, as documented; a bare pipe into
    add is no longer read. tx query still reads a piped query when none is given.
  • tx deploy without -d now previews the database it would actually write (named after the
    model) instead of skipping the diff and showing the model path as the target. A model with no
    name of its own, such as a bare TMDL folder, fails with TOMIX_DEPLOY_NO_TARGET asking for
    -d instead of a serializer error.

Removed

  • Breaking: --dry-run is removed from every command (add, set, mv, rm, replace,
    format, bpa run, deploy, refresh, session prune). Model edits already preview unless
    you pass --save or --stage, and the commands that change a target now preview by default.
    The TOMIX_BPA_DRY_RUN_REQUIRES_FIX code is gone with it.
  • Breaking: tx init, tx config init, tx bpa rules init, and tx connect -w take
    --overwrite instead of --force to replace an existing target, matching --overwrite on the
    save commands. --force now only ever bypasses a check. Recover a corrupt config with tx config init --overwrite.
  • Breaking: tx deploy --force is removed. It never had an effect: no deploy check read it.
    Use --skip-bpa to bypass the BPA gate.

What's Changed

  • feat(get): make get the single read pipeline; ls and deps become shortcuts by @bgarcevic in #335
  • chore(agents): remove template dotnet skills that contradict repo conventions by @bgarcevic in #337
  • feat(connect)!: fold tx session into tx connect by @bgarcevic in #339
  • feat!: preview by default instead of --dry-run by @bgarcevic in #338
  • docs(design): ADR 0001 for the live model session by @bgarcevic in #373
  • feat(bpa): rule-source chain, attribution, default-off presets, and ignore --user (#233) by @bgarcevic in #340
  • fix(cli): don't block on a redirected stdin that nothing was piped into by @bgarcevic in #375
  • refactor(rules): share one rule shape across validate and bpa by @bgarcevic in #376
  • fix(cli): repair quoted Windows paths with a trailing backslash by @bgarcevic in #377
  • chore(release): prepare 0.8.0 by @github-actions[bot] in #336

Full Changelog: v0.7.0...v0.8.0

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 29 Sep 21:51

Added

  • tx bpa rules add, set, remove, and init author custom BPA rules from the CLI. They edit
    your config-dir bpa-rules.json (which bpa run loads) or the file --rules-file names, and
    keep fields tx does not model. Scope and severity are validated (#232).
  • tx bpa rules add, set, and remove take a model to edit the rules that ship with it, in
    its BestPracticeAnalyzer annotation. The edit runs like other model mutations (--save,
    --stage, --save-to, ...), uses the same field checks as rules files, and keeps fields tx
    does not model (#330).
  • tx bpa run --fix now fixes DAX_COLUMNS_FULLY_QUALIFIED and DAX_MEASURES_UNQUALIFIED
    by rewriting the object's DAX, through two new fix expressions:
    QualifyColumnReferences() and UnqualifyMeasureReferences(). References that cannot be
    resolved for certain (a column name in several tables, a name that is also a string literal,
    a measure qualified with the wrong table) are reported as fix errors and left unchanged (#267).
  • tx doctor reports the current session's connection (current-session) and, on Windows,
    warns when you are signed in but the token cache file is missing.
  • tx doctor --show-details includes account, server, database, model, profile, and session
    names and full paths. Without it, the report is safe to paste into a bug report: the home
    directory is shown as ~ and names are replaced by what kind of thing they are.
  • tx doctor suggests tx session prune when session files of exited shells are left over.

Changed

  • tx doctor output is shorter and only warns when something needs doing. Optional states
    (no profiles, not signed in, no update check yet) are reported with the new Info status
    (INFO) instead of WARN. The runtime, operating-system, terminal, and
    model-providers checks are removed because they could never fail; the runtime, OS, and
    terminal details are still in the header and in the JSON fields. The update-cache message
    now shows a short UTC time and says to run tx update. A source build (./tx) or an install
    tx update cannot update reports a newer release as INFO without that hint, matching the
    update notice. The header and JSON (installKind) show how tx was installed.
  • tx doctor no longer prints the end-of-command "a new version is available" notice (its
    update-cache check already says so) and no longer refreshes the update cache over the
    network, keeping its promise to stay local.
  • tx doctor no longer creates ~/.tomix on a machine where tx has not run yet; it reports
    that the directory will be created on first use.
  • tx get text output shows only the properties that are set, aligned under the object's path
    and kind, with annotations and translations in their own sections and multi-line expressions
    as indented blocks. Unset settable properties fold into one Not set: line, followed by a
    tx set hint. The new --all option lists every property, with a "N of M set" count, a dim
    — for empty values, and a read-only tag. JSON and CSV output are unchanged.
  • tx get --query with an unknown property now fails with TOMIX_PROPERTY_NOT_FOUND and
    suggests the closest property name, or lists the valid ones when nothing is close. An unset
    annotation: or translation: token reads back as null.

Changed

  • tx bpa rules list shows each rule's scope, and lists the rules in your config-dir
    bpa-rules.json (source user), matching what bpa run loads (#232).
  • Config, profiles, recent connections, session, staging, update-check, auth, BPA, and
    test-snapshot files are now read and written with source-generated JSON instead of runtime
    reflection, as groundwork for a faster-starting Native AOT build. The files' format is
    unchanged, so existing ones keep working.
  • Release binaries and the dotnet tool package no longer include msalruntime and
    msasxpress, two native libraries tx never uses for sign-in (the release binary is about
    3 MB smaller). The dotnet tool package now talks to XMLA endpoints uncompressed, as the
    release binaries already did.

Removed

  • Breaking: tx script is removed. Despite its description it never ran C#: it evaluated a
    handful of fixed read-only expressions (Model.Tables.Count, Model.Tables[0].Name, ...) and
    could not change a model. Use tx ls, tx get, and tx find (with --output-format json)
    to read the same information. The TOMIX_SCRIPT_FILE_NOT_FOUND and TOMIX_SCRIPT_REQUIRED
    codes are gone with it.
  • Breaking: tx load is replaced by tx summary, which is listed under Discover and reports
    more: the source (path or workspace endpoint), on-disk format, culture, default storage mode,
    and partition, calculation group, perspective, and culture counts alongside the old ones.
  • Breaking: the compatibility -q <property>/-i <value> options on tx add and tx set
    are removed. Use --set <property>=<value> (repeatable; <property>=- reads stdin) and, on
    add, --expression/-e for the new object's value. -q now means --quiet on every command.
    The TOMIX_SET_INPUT_CONFLICT, TOMIX_ADD_INPUT_CONFLICT, and TOMIX_ADD_VALUE_REQUIRED codes
    are gone with them.

What's Changed

  • feat(bpa): DAX-rewrite fixes for column and measure qualification by @bgarcevic in #326
  • feat(bpa): author custom rules with bpa rules add/set/remove/init by @bgarcevic in #328
  • feat(doctor): shareable report, current session, and honest update advice by @bgarcevic in #331
  • refactor: source-generated JSON and a single-binary Native AOT preview by @bgarcevic in #329
  • feat(bpa): author rules in the model's BestPracticeAnalyzer annotation by @bgarcevic in #332
  • feat(get): compact property view with --all and property suggestions by @bgarcevic in #334
  • feat!: remove tx script, replace tx load with tx summary, retire add/set -q/-i by @bgarcevic in #333
  • chore(release): prepare 0.7.0 by @github-actions[bot] in #327

Full Changelog: v0.6.0...v0.7.0

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 29 Sep 10:06

Fixed

  • tx validate no longer reports every column reference into a calculated table as missing
    (DAX0002) when its TMDL declares no columns because the table was never evaluated. Columns
    are inferred from DATATABLE(...) and ROW(...) expressions, so typos are still caught;
    references into calculated tables whose columns cannot be inferred offline are not judged (#320).
  • tx validate in CI logs: with --ci (or under Azure Pipelines), findings are no longer
    hard-wrapped at 80 columns, so each one stays on its own line. In Azure Pipelines, a column
    named like a log command ([Group], [Section], [Error], ...) no longer turns its line
    into a collapsible section header that drops the ##[error] styling and leaves stray 8m
    fragments in the table.
  • tx validate no longer warns (DAX0003) about columns an expression defines for itself:
    [@Name] when "@Name" is a new column's name in ADDCOLUMNS, SELECTCOLUMNS,
    SUMMARIZE, SUMMARIZECOLUMNS, GROUPBY, ROW, or DATATABLE, and [Value] from
    GENERATESERIES or a { ... } table constructor (not an IN { ... } list).
  • tx validate now checks where those columns are used: a column an expression builds is
    accepted only where a row of its table is in context (inside FILTER, SUMX, and other
    iterators over it, also through a VAR), and a use outside it warns with DAX0003 "is built
    by this expression but used outside the table that has it".

What's Changed

  • fix(validate): infer columns of undeclared calculated tables by @bgarcevic in #320
  • docs(changelog): move #320 entry to [Unreleased] and document the rule by @bgarcevic in #321
  • fix(validate): readable CI logs and no warnings for query-scoped columns by @bgarcevic in #323
  • fix(validate): scope-check columns an expression builds itself by @bgarcevic in #324
  • chore(release): prepare 0.6.0 by @github-actions[bot] in #322

Full Changelog: v0.5.0...v0.6.0

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 29 Sep 08:22

Added

  • tx bpa run --fix --dry-run previews fixes without changing the model. Each pending fix is
    listed as Would fix: (or Would delete: with --allow-delete) with the property's value
    before and after, followed by how many findings would remain. Nothing is applied, saved, or
    staged, and the exit code still follows --fail-on for the model as it is. JSON adds
    dryRun, fixesPending, wouldRemain, and a fixes array with each fix's before and after
    values; outside a dry run, fixes lists the fixes that were applied (#268).
  • tx connect <workspace> --list lists the semantic models on a workspace or XMLA
    endpoint without connecting (name, compatibility level, last update). It works
    non-interactively and with --output-format json, so scripts and agents can
    discover models on a workspace that hosts more than one.
  • tx refresh reports refresh progress in detail: a live panel shows overall progress and each
    in-progress table's step (querying, reading, compressing, hierarchies, calculated columns),
    partition, rows, and running time, then the model-level steps (relationships, calculation
    script, commit). It replaces the single status line, which on large models was cut off at the
    terminal width and kept showing the same few tables. The summary adds a Process
    column, a row per partition for multi-partition tables, and a phase table; JSON gains
    tables[].processMs, tables[].partitions, and phases.

Changed

  • Opening a workspace that hosts several models without naming one now fails with
    TOMIX_DATABASE_REQUIRED (exit 2) and a hint to run tx connect <workspace> --list,
    instead of TOMIX_CONNECT_FAILED / TOMIX_QUERY_FAILED (exit 1).

Removed

  • Breaking: tx query --plan and the plans field of tx query --output-format json. Power BI /
    Fabric XMLA endpoints never deliver query-plan trace events, so the option could not return a plan.

Fixed

  • tx refresh reported only the last partition's rows and timings for tables with several
    partitions, and on Power BI / Fabric could summarize before the trace arrived, reporting zeros
    (typically with --output-format json).
  • tx query --trace returns server timings on Power BI / Fabric XMLA endpoints. The trace was
    rejected for an unsupported column, and events that arrived were then silently discarded; timings
    (and benchmark storage-engine stats) came back null. A missing timing now always comes with a
    warning on stderr.

What's Changed

  • ci: automate releases with verified previews and a release PR by @bgarcevic in #315
  • feat(connect): list models on a remote workspace with --list by @bgarcevic in #316
  • fix(query)!: restore Fabric trace timings, detail refresh progress, remove --plan by @bgarcevic in #318
  • feat(bpa): --dry-run for --fix previews fixes without applying them by @bgarcevic in #319
  • chore(release): prepare 0.5.0 by @github-actions[bot] in #317

New Contributors

  • @github-actions[bot] made their first contribution in #317

Full Changelog: v0.4.3...v0.5.0