toga-ai 1.0.31 → 1.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,4 +3,5 @@
3
3
  | Doc | Summary | Files |
4
4
  |-----|---------|-------|
5
5
  | [_underscore Framework Architecture](architecture.md) | `_underscore` is the shared PHP backend framework for **all 2.0 applications**. | _underscore/_underscore.php, _underscore/Loader.php, _underscore/Framework.php, _underscore/Model.php, _underscore/Database.php, _underscore/Query.php, _underscore/Route.php, _underscore/Component.php |
6
+ | [Carrier Shipping Labels (UPS/FedEx) & NetSuite Item Fulfillment](features/carrier-shipping-labels.md) | Backend mechanics behind TOGa Supply's Fulfill & Ship: buying a carrier label (UPS/FedEx), persisting it, and creating the NetSuite Item Fulfillment with tracki | _underscore/Model/Client/ItemFulfillment.php, _underscore/Component/Library/Carriers/Ups/Ups.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Trait/Netsuite/SalesOrder.php, _underscore/Component/Library/NetSuite/NetSuite.php, _underscore/Model/Client/TrackingNumber.php, _underscore/Model/Client/ShippingMethod.php, _underscore/Model.php, _underscore/Cloud.php |
6
7
  | [Recursive Item Fulfillments (upstream mirroring)](features/recursive-item-fulfillments.md) | In a multi-tier supply chain a sales order (SO) spawns a purchase order (PO) that becomes another SO downstream, and so on. | _underscore/Model/Client/ItemFulfillment.php, _underscore/Model/Client/ItemFulfillmentItem.php, _underscore/Model/Client/ItemFulfillmentItemUnit.php, _underscore/Model/Client/ItemFulfillmentPackage.php, _underscore/Model/Compass/AdvanceShippingNotice.php, dbchanges2/Core/2026-02-13 - 75601 - RecursiveItemFulfillmentCreation.sql, dbchanges2/Core/2026-06-04 - RecursiveItemFulfillmentPut.sql |
@@ -0,0 +1,113 @@
1
+ ---
2
+ title: Carrier Shipping Labels (UPS/FedEx) & NetSuite Item Fulfillment
3
+ framework: "2.0"
4
+ repo: _underscore
5
+ project: _Underscore
6
+ client: shared
7
+ type: feature
8
+ status: active
9
+ updated: 2026-06-10
10
+ owners: [mhammontree]
11
+ files:
12
+ - _underscore/Model/Client/ItemFulfillment.php
13
+ - _underscore/Component/Library/Carriers/Ups/Ups.php
14
+ - _underscore/Trait/Netsuite/ItemFulfillment.php
15
+ - _underscore/Trait/Netsuite/SalesOrder.php
16
+ - _underscore/Component/Library/NetSuite/NetSuite.php
17
+ - _underscore/Model/Client/TrackingNumber.php
18
+ - _underscore/Model/Client/ShippingMethod.php
19
+ - _underscore/Model.php
20
+ - _underscore/Cloud.php
21
+ related:
22
+ - ../architecture.md
23
+ - recursive-item-fulfillments.md
24
+ - ../../toga2-supply/features/fulfill-and-ship.md
25
+ ---
26
+
27
+ ## Summary
28
+
29
+ Backend mechanics behind TOGa Supply's Fulfill & Ship: buying a carrier label
30
+ (UPS/FedEx), persisting it, and creating the NetSuite Item Fulfillment with tracking
31
+ number and label attached. Includes the **authoritative label-storage architecture
32
+ decision** (dev lead Jeff, June 2026) that supersedes what the code currently does.
33
+
34
+ ## Key files / entry points
35
+
36
+ - `upsShipmentApi` / `fedexShipmentApi` (scripted APIs on
37
+ `Model/Client/ItemFulfillment.php`): build the carrier request, call the carrier,
38
+ (currently) convert ZPL→PDF via Labelary, save the PDF to NetSuite File Cabinet +
39
+ the DB storage field, return `{ trackingNumber, pdfLabel, fileInternalId }` or
40
+ `{ error, trackingNumber }`. UPS path now checks `$shipmentResponse->success` and
41
+ fast-fails on an empty service code (it previously swallowed UPS errors and surfaced
42
+ a misleading "Failed to save PDF to NetSuite").
43
+ - `_Component_Library_Carriers_Ups::submitShipmentRequest`
44
+ (`Component/Library/Carriers/Ups/Ups.php`): returns `{ success, errorMessage,
45
+ trackingNumber, encodedLabel }`.
46
+ - `createNetsuiteItemFulfillment` (`Trait/Netsuite/ItemFulfillment.php`): builds the NS
47
+ IF from the SO, assigns serialized inventory, sets packages/tracking numbers.
48
+ **Returns the numeric NS internalId on success, an error string on failure**
49
+ (ambiguous return — callers must check `/^\d+$/`). Takes
50
+ `$labelFileInternalId = null` and attaches the label to the IF after creation
51
+ (`attachFileToRecord` was widened `private` → `protected` so the trait can call it
52
+ from client subclasses).
53
+ - The trait is composed into **client-specific** subclasses
54
+ (`_Model_Growrk_ItemFulfillment extends _Model_Client_ItemFulfillment`), not the base
55
+ model.
56
+
57
+ ## Label-storage architecture (AUTHORITATIVE — dev lead Jeff, 2026-06)
58
+
59
+ Supersedes the Labelary-PDF + manual-S3 approach:
60
+
61
+ 1. **Do NOT touch S3 by hand.** The model's `FIELD_STORAGE` abstraction, accessed via
62
+ the 2.0 API, already handles label fetch + storage.
63
+ 2. **Store the raw carrier response as a GIF**, not a Labelary-converted PDF.
64
+ 3. **Generate the printable PDF on demand**, combining the shipping label AND the
65
+ return label into one PDF (the browser print dialog handles one file at a time).
66
+ Leaning **backend** generation — `pdf-lib` (client-side) cannot embed GIF.
67
+
68
+ Not yet implemented. Open questions before building: backend vs frontend for the
69
+ GIF→PDF step; which existing 2.0 label-fetch/storage calls to build on. Combining
70
+ shipping + return also depends on the return-label flow existing — outbound-only can
71
+ come first.
72
+
73
+ ## `FIELD_STORAGE` mechanics (reference)
74
+
75
+ `Model.php` handles storage fields separately from regular columns (write loop ~line
76
+ 393; read ~line 730). Config keys in `[_underscore]`: `model_storage_folder` → local
77
+ folder mode (if set, S3 is never used); `model_storage_s3_bucket` +
78
+ `model_storage_s3_folder` → S3 mode. Storage key/path (both modes):
79
+
80
+ ```
81
+ <folder-or-s3-prefix>/<env (_Environment::$name)>/<database>/<TABLE>/<field>/<primaryKeyId>
82
+ ```
83
+
84
+ e.g. `<prefix>/beta/Client_Growrk/TrackingNumbers/labelPdfFile/<id>` — named by numeric
85
+ PK, **no extension**. Reads return the raw bytes verbatim (no base64/data-uri); writes
86
+ store whatever value was assigned. `_Cloud::copyFileToS3` **re-throws** on AWS errors —
87
+ if no exception reached the caller and execution continued, the write was never
88
+ attempted.
89
+
90
+ ## Gotchas / known issues
91
+
92
+ - UPS **test** endpoint (`wwwcie.ups.com`, debug mode) returns a constant tracking
93
+ number `1ZXXXXXXXXXXXXXXXX` + SAMPLE labels → `TrackingNumbers.number` UNIQUE
94
+ collision and File Cabinet duplicate-filename failures on repeat tests (see the
95
+ fulfill-and-ship doc for the cleanup SQL). Never in prod.
96
+ - `upsShipmentApi` reads ship-to from the **Sales Order** (`shipToAddressId`), not the
97
+ Item Fulfillment — form-edited addresses never reach UPS.
98
+ - UPS `AddressLine` max 35 chars/line; send an array of trimmed lines (FedEx already
99
+ does), not `line1 . ' ' . line2`.
100
+ - `ShippingMethods.code` is carrier-scoped: UPS numeric (`03` Ground, `01` Next Day
101
+ Air), FedEx strings (`FEDEX_GROUND`). Empty code → UPS error 120500.
102
+ - Serialized-inventory assignment fails ("Invalid issueinventorynumber reference key")
103
+ when the lookup isn't location-scoped and the SO has no Warehouse Location —
104
+ recommended: always scope `getInventoryNumberFromSerialNumber` by location.
105
+ - `createNetsuiteItemFulfillment` doesn't set carrier/method on the NS IF — it defaults
106
+ (can show FedEx for a UPS shipment). Open item.
107
+
108
+ ## Related docs
109
+
110
+ - [Fulfill & Ship (toga2-supply)](../../toga2-supply/features/fulfill-and-ship.md) —
111
+ frontend flow and success gating.
112
+ - [Recursive Item Fulfillments](recursive-item-fulfillments.md) — interceptor-driven
113
+ upstream mirroring on the same models.
@@ -0,0 +1,6 @@
1
+ # toga2-supply (TOGa Supply) — 2.0 knowledge
2
+
3
+ | Doc | Summary | Files |
4
+ |-----|---------|-------|
5
+ | [TOGa Supply (toga2-supply) Architecture](architecture.md) | `toga2-supply` is the **React + Vite frontend** for TOGa Supply — warehouse fulfillment tooling (shipment selection, fulfill & ship against carrier APIs, NetSui | toga2-supply/src/api/toga.ts, toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx, toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx |
6
+ | [Fulfill & Ship](features/fulfill-and-ship.md) | Fulfill & Ship lets a warehouse user select sales-order line items, enter serials, pick a carrier/method, and in one action: create the Item Fulfillment records | toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx, toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx, toga2-supply/src/pages/EditShipment/view/components/forms/EditShipmentForm.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx, toga2-supply/src/pages/Shipments/api/ShipmentsApi.ts, _underscore/Model/Client/ItemFulfillment.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Component/Library/Carriers/Ups/Ups.php |
@@ -0,0 +1,73 @@
1
+ ---
2
+ title: TOGa Supply (toga2-supply) Architecture
3
+ framework: "2.0"
4
+ repo: toga2-supply
5
+ project: TOGa Supply
6
+ client: shared
7
+ type: architecture
8
+ status: active
9
+ updated: 2026-06-10
10
+ owners: [mhammontree]
11
+ files:
12
+ - toga2-supply/src/api/toga.ts
13
+ - toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx
14
+ - toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx
15
+ - toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts
16
+ - toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx
17
+ related:
18
+ - ../_underscore/architecture.md
19
+ - ../api2/architecture.md
20
+ - features/fulfill-and-ship.md
21
+ ---
22
+
23
+ ## Summary
24
+
25
+ `toga2-supply` is the **React + Vite frontend** for TOGa Supply — warehouse fulfillment
26
+ tooling (shipment selection, fulfill & ship against carrier APIs, NetSuite Item
27
+ Fulfillment creation, label printing/reprinting). It is a pure frontend: all business
28
+ logic lives in the 2.0 API (`api2` engine over `_underscore` models). It has **no
29
+ backend code of its own** — `dependsOn: [api2]`.
30
+
31
+ ## Topology (dev/test setup)
32
+
33
+ - The frontend runs **locally** on the developer machine (e.g.
34
+ `http://growrk.togasupply:5173`); it is not deployed to beta in this setup. Local
35
+ code edits take effect on reload.
36
+ - It calls the **beta** API at `https://api.beta.togahub.com`. Backend (`_underscore`)
37
+ changes therefore require a **deploy to beta** before they are observable — a symptom
38
+ can look "unfixed" simply because the backend fix isn't deployed yet.
39
+ - Client subdomain selects the tenant (e.g. `growrk.togasupply` → client GroWrk,
40
+ DB `Client_Growrk`).
41
+
42
+ ## Shared API client — `src/api/toga.ts`
43
+
44
+ `togaApiRequest` resolves the API base from the hostname, auto-bootstraps auth
45
+ (`/auth/public` / `/auth/refresh`), and **retries once on 401**. The recurring 401s
46
+ seen at page load are this retry/refresh pattern (usually transient) — the real failure
47
+ mode is a non-401 status (400/business error) carrying a message.
48
+
49
+ Response envelope (2.0 API): `{ isSuccess, status, error, messages, data: { <route>:
50
+ { <method>: ... } } }`. Scripted-API results nest as `data.<routeCamel>.<methodName>`.
51
+
52
+ ## Route map
53
+
54
+ | Route | Page | Purpose |
55
+ |---|---|---|
56
+ | `/shipment-items?internalId=<NS SO id>` | `ShipmentItemsPage` | select SO line items; the **only** place the SO syncs from NetSuite into Toga; stores selection in `localStorage("selectedItems")` |
57
+ | `/edit-shipment?internalId=<id>` | `EditShipmentPage` → `EditShipmentForm` | serials, carrier, method → **Fulfill & Ship** |
58
+ | `/shipments`, `/fulfilled-shipments` | `ShipmentsCardTableForm` | pending vs fulfilled views; reprint lives here |
59
+
60
+ ## Key decisions
61
+
62
+ - Carrier dropdown filters to FEDEX/UPS carriers that have ≥1 account number.
63
+ - Success/failure gating: a fulfillment is only "green" when the carrier returned a real
64
+ tracking number AND NetSuite returned a numeric internalId (`/^\d+$/`) — see the
65
+ fulfill-and-ship feature doc.
66
+ - Browser print: the print dialog handles one file at a time and `window.print()` fires
67
+ once per session — hence the combined-PDF reprint design. Popups must be allowed
68
+ (label window is `window.open`).
69
+
70
+ ## Related docs
71
+
72
+ - [Fulfill & Ship feature](features/fulfill-and-ship.md) — the end-to-end flow, bugs, gotchas.
73
+ - [Carrier shipping labels (_underscore)](../_underscore/features/carrier-shipping-labels.md) — backend label + NetSuite mechanics.
@@ -0,0 +1,112 @@
1
+ ---
2
+ title: Fulfill & Ship
3
+ framework: "2.0"
4
+ repo: toga2-supply
5
+ project: TOGa Supply
6
+ client: shared
7
+ type: feature
8
+ status: active
9
+ updated: 2026-06-10
10
+ owners: [mhammontree]
11
+ files:
12
+ - toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx
13
+ - toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx
14
+ - toga2-supply/src/pages/EditShipment/view/components/forms/EditShipmentForm.tsx
15
+ - toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts
16
+ - toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx
17
+ - toga2-supply/src/pages/Shipments/api/ShipmentsApi.ts
18
+ - _underscore/Model/Client/ItemFulfillment.php
19
+ - _underscore/Trait/Netsuite/ItemFulfillment.php
20
+ - _underscore/Component/Library/Carriers/Ups/Ups.php
21
+ related:
22
+ - ../architecture.md
23
+ - ../../_underscore/features/carrier-shipping-labels.md
24
+ - ../../_underscore/features/recursive-item-fulfillments.md
25
+ ---
26
+
27
+ ## Summary
28
+
29
+ Fulfill & Ship lets a warehouse user select sales-order line items, enter serials,
30
+ pick a carrier/method, and in one action: create the Item Fulfillment records in Toga,
31
+ buy a carrier label (UPS/FedEx), and create the NetSuite Item Fulfillment with the
32
+ tracking number and label attached. Driven green end-to-end on beta (UPS, client
33
+ GroWrk, June 2026); FedEx + UPS both need verification before prod.
34
+
35
+ ## How it works
36
+
37
+ 1. `/shipment-items` load: `checkIfSalesOrderExists(internalId)` (GET `/sales-orders`
38
+ by `c_netsuiteInternalSalesOrderId`); if missing →
39
+ `GET /sales-orders/syncNetsuiteSalesOrder` then `syncNetsuiteItemFulfillmentWithToga`.
40
+ **This is the only place the SO syncs from NetSuite into Toga.**
41
+ 2. `/edit-shipment` submit (`onFormSubmit("fulfillAndShip")` in `EditShipmentForm.tsx`):
42
+ - `saveShipment` → POST `/item-fulfillments`, `/tracking-numbers`,
43
+ `/item-fulfillment-packages`.
44
+ - `fulfillShipment` → GET `/item-fulfillments/upsShipmentApi` (or `fedexShipmentApi`)
45
+ for the label, then `saveShipmentToNetsuite` →
46
+ GET `/item-fulfillments/createNetsuiteItemFulfillment`.
47
+ - `handleShipmentDownload` opens the label PDF and triggers print.
48
+ 3. **Success gating**: `fulfillShipment` returns `{ success, error, data }` and requires
49
+ BOTH a real tracking number (no `error`) AND a numeric NetSuite internalId
50
+ (`/^\d+$/` — `createNetsuiteItemFulfillment` returns the numeric internalId on
51
+ success but an **error string** on failure). Both callers gate the success toaster
52
+ on `success`.
53
+ 4. The label `fileInternalId` is passed through `fulfillShipment` →
54
+ `saveShipmentToNetsuite` → `createNetsuiteItemFulfillment`, which attaches the label
55
+ to the IF **after** creating it (the IF doesn't exist yet when the label is bought).
56
+
57
+ ## Reprint (first pass — being reworked)
58
+
59
+ Fulfilled-shipments view: multi-select shipments, merge each stored label into one
60
+ multi-page PDF with `pdf-lib`, print once. **Superseded by the label-storage decision**
61
+ (see the carrier-shipping-labels doc): labels will be stored as raw carrier GIFs and
62
+ the combined PDF generated on demand — note `pdf-lib` cannot embed GIF, so generation
63
+ likely moves to the backend.
64
+
65
+ ## Gotchas / known issues
66
+
67
+ - **UPS test endpoint** (`wwwcie.ups.com`, debug mode) returns a constant tracking
68
+ number `1ZXXXXXXXXXXXXXXXX` + SAMPLE labels. On 2nd+ test runs this collides with the
69
+ `TrackingNumbers.number` UNIQUE index (surfaces mislabeled as "Labelary API error")
70
+ AND NetSuite File Cabinet's unique filename (`ShippingLabel_<tracking>.pdf`). Free
71
+ both between runs:
72
+ `UPDATE TrackingNumbers SET number = CONCAT(number,'-',id) WHERE number='1ZXXXXXXXXXXXXXXXX'`
73
+ and delete/rename the prior File Cabinet file. Never happens in prod.
74
+ - **Address source mismatch**: `upsShipmentApi` reads ship-to from the **Sales Order**
75
+ (`SalesOrder.shipToAddressId`), NOT the address edited in the form (the IF's) — form
76
+ address edits never reach the carrier. Open decision: read the IF address instead.
77
+ - **UPS address limits**: `AddressLine` max 35 chars/line; code currently sends
78
+ `line1 + ' ' + line2` as one line — should send a trimmed array (FedEx path already
79
+ does).
80
+ - **Service codes are carrier-scoped**: UPS numeric (`03`=Ground, `01`=Next Day Air),
81
+ FedEx strings (`FEDEX_GROUND`), in `ShippingMethods.code`. Empty code → UPS 120500;
82
+ there is now a fast-fail guard.
83
+ - **Serialized inventory needs a location**: a SO with no Warehouse Location makes
84
+ NetSuite reject the serial issue ("Invalid issueinventorynumber reference key").
85
+ Recommended hardening: always scope `getInventoryNumberFromSerialNumber` by location.
86
+ - **EV-12 on POST /item-fulfillments** means the SO isn't synced into Toga yet — fire
87
+ `GET /sales-orders/syncNetsuiteSalesOrder?netsuiteInternalSalesOrderId=<id>`.
88
+ - **Carrier on the NS IF defaults wrong**: `createNetsuiteItemFulfillment` doesn't set
89
+ carrier/method, so the IF can show FedEx while the tracking number is UPS. Open item.
90
+ - Real carrier errors live in the client-logs `Api` table (DIRECTION `OUT`,
91
+ `hostname LIKE '%ups.com%'`, `responsePayload`).
92
+ - React warning: `setState`-in-render in `ShipmentItemsTable.tsx` (~line 149,
93
+ `clearErrors` inside a `setRowsClicked` updater) — move out of the updater.
94
+
95
+ ## Remaining work
96
+
97
+ - Label storage + reprint rework per the carrier-shipping-labels doc (raw GIF +
98
+ on-demand combined PDF).
99
+ - Return-label flow: `returnTrackingNumberId` (nullable) on `ItemFulfillmentItemUnits`;
100
+ "needs return label" checkbox; return-address editable combo ("Rolodex pattern" of
101
+ client locations, overridable, validated); "return label" text on return pages of the
102
+ combined PDF.
103
+ - Address-source decision, UPS 35-char hardening, location-scoped inventory lookup,
104
+ carrier/method on the NS IF, responsiveness per Figma, FedEx + UPS end-to-end
105
+ verification before prod.
106
+
107
+ ## Client variations
108
+
109
+ None in the flow itself — but the NetSuite trait is composed into **client-specific**
110
+ model subclasses (e.g. `_Model_Growrk_ItemFulfillment uses _Trait_Netsuite_ItemFulfillment`),
111
+ not the base `_Model_Client_ItemFulfillment`. Tested with GroWrk; UPS support was built
112
+ for Compass and is not yet in prod.
@@ -9,10 +9,11 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
9
9
 
10
10
  ## 2.0 framework
11
11
 
12
- - **_underscore** (_Underscore) _(framework core)_ — 2 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
12
+ - **_underscore** (_Underscore) _(framework core)_ — 3 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
13
13
  - **worker2** (Worker) — 3 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
14
14
  - **api2** (API) — 1 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
15
15
  - **dbchanges2** (Database Changes) _(framework core)_ — 1 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
16
+ - **toga2-supply** (TOGa Supply) — 2 doc(s) → [2.0/apps/toga2-supply/INDEX.md](2.0/apps/toga2-supply/INDEX.md)
16
17
 
17
18
  ## Clients
18
19
 
@@ -4,5 +4,6 @@
4
4
  { "repo": "api2", "project": "API", "framework": "2.0", "role": "app", "dependsOn": [] },
5
5
  { "repo": "dbchanges2", "project": "Database Changes", "framework": "2.0", "role": "core", "dependsOn": [] },
6
6
  { "repo": "library", "project": "Library", "framework": "1.0", "role": "core", "dependsOn": [] },
7
- { "repo": "worker", "project": "Worker", "framework": "1.0", "role": "app", "dependsOn": [] }
7
+ { "repo": "worker", "project": "Worker", "framework": "1.0", "role": "app", "dependsOn": [] },
8
+ { "repo": "toga2-supply", "project": "TOGa Supply", "framework": "2.0", "role": "app", "dependsOn": ["api2"] }
8
9
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.31",
3
+ "version": "1.0.32",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",