toga-ai 1.0.364 → 1.0.366

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.
@@ -6,7 +6,7 @@ project: Webhook
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-06-15
9
+ updated: 2026-07-17
10
10
  owners: ["dfranks"]
11
11
  files:
12
12
  - webhook/_/webhook/netsuite.php
@@ -74,6 +74,23 @@ the assignment fires 2493 in `edit` (full-record) context → proper name (see G
74
74
  None — single internal Agilant/True integration.
75
75
 
76
76
  ## Gotchas / known issues
77
+ - **Create-only, NO dedup of any kind (confirmed 2026-07-17).** `Webhook_NetSuite::post()`
78
+ json-decodes the payload and calls `createTask()`, which POSTs a **new** task to ClickUp
79
+ list `901111987449` **unconditionally on every delivery** (writing link `db_client`). There
80
+ is no idempotency check whatsoever — so it double-creates a task on **any** repeat or
81
+ concurrent delivery, not only concurrent ones.
82
+ - **Live payload carries no immutable opportunity identifier (confirmed 2026-07-17).** The
83
+ inbound body has **only**: `name`, `description`, `presalesLead`, `salesRepText`, `token`.
84
+ It has **no NetSuite opportunity internal id and no opportunity/customer number**, so there
85
+ is no stable key available in this handler to dedup on today. Any dedup fix must first get
86
+ NetSuite (script 2493) to include an immutable id in the payload, or derive one another way.
87
+ - **Where the swapped Opp#/Cust# mapping actually lives.** The
88
+ `OPPORTUNITY_NUMBER ← customerNumber` / `CUSTOMER_NUMBER ← opportunityNumber` swap is in the
89
+ **dormant 2.0 port** `worker2/Worker/Netsuite.php` (class `_Worker_NetSuite`, ~lines 116–121),
90
+ which is **NOT live**. The live `webhook/_/webhook/netsuite.php` payload doesn't even carry
91
+ those number fields (see above). There is **no** `worker2/Worker/Netsuite/Opportunity.php` and
92
+ **no** `maybeCreateClickupTask()` method anywhere — earlier plans referencing those paths were
93
+ citing files that do not exist.
77
94
  - **`OPP <internalId>` degenerate tasks (root-caused & confirmed 2026-06-15).** A task named just
78
95
  `OPP 7147699` with no description/fields. The name is built by NetSuite and relayed verbatim;
79
96
  the opps are **fully populated** in NetSuite (so it's not missing data, not a TOGA bug). Cause:
@@ -131,6 +148,13 @@ Done 2026-06-15 for opps 7147699/7147698/7147472/6382879 → 4 proper tasks crea
131
148
  (task ids `868k0tr41`, `868k0tr16`, `868k0rwtp`, `868k0h44m`) were archived in ClickUp afterward.
132
149
 
133
150
  ## Change history
151
+ - 2026-07-17 — Confirmed against live code: `createTask()` POSTs to list `901111987449`
152
+ **unconditionally with no dedup** (double-creates on any repeat/concurrent delivery); the
153
+ live payload carries only `name`/`description`/`presalesLead`/`salesRepText`/`token` — **no
154
+ opportunity internal id or number**, so no stable dedup key exists in the handler today. The
155
+ swapped Opp#/Cust# mapping lives in the **dormant** `worker2/Worker/Netsuite.php`
156
+ (`_Worker_NetSuite`, ~lines 116–121), not the live file; corrected fictional references to
157
+ `worker2/Worker/Netsuite/Opportunity.php` / `maybeCreateClickupTask()` (neither exists). (dfranks)
134
158
  - 2026-06-15 — **Fix deployed in NetSuite prod:** scheduled script 2412's presales-lead assignment
135
159
  switched from `submitFields` to full `load`/`setValue`/`save` → fires 2493 in `edit` (full-record)
136
160
  context → proper names. Residual: 2493 still latently `xedit`-vulnerable to other triggers; watch
@@ -3,5 +3,5 @@
3
3
  | Doc | Summary | Files |
4
4
  |-----|---------|-------|
5
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/view/components/SelectedShipmentItemsTable.tsx, toga2-supply/src/pages/EditShipment/view/helpers/ShipmentDetailsForm/renderEditShipmentFormInput.tsx, toga2-supply/src/pages/EditShipment/viewModel/FIELDS/DUMMYUPDATESHIPMENTFIELDS.json, toga2-supply/src/pages/EditShipment/helpers/ShipmentDetailsForm/renderEditShipmentFormInput.tsx, toga2-supply/tailwind.config.cjs, toga2-supply/src/pages/EditShipment/view/modals/ReturnShippingModal.tsx, toga2-supply/src/styles/index.scss, toga2-supply/src/components/ui/BaseInput/BaseInput.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, toga2-supply/src/pages/EditShipment/viewModel/signatureTypes.ts, toga2-supply/src/pages/EditShipment/view/modals/SelectReturnAddressModal.tsx, toga2-supply/src/pages/EditShipment/helpers/ShipmentDetailsForm/formatShipmentData.ts, toga2-supply/src/pages/EditShipment/types.ts, toga2-supply/src/pages/Shipments/view/ShipmentsPage.tsx, toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx, toga2-supply/src/pages/Shipments/api/ShipmentsApi.ts, toga2-supply/src/pages/Shipments/types.ts, toga2-supply/src/pages/FulfilledShipments/view/FulfilledShipmentsPage.tsx, toga2-supply/src/components/ui/CardTable/CardTable.tsx, toga2-supply/src/components/ui/CardTable/types.ts, toga2-supply/src/assets/pen-line.svg, _underscore/Model/Client/ItemFulfillment.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Component/Library/Carriers/Ups/Ups.php |
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/components/ui/BaseInput/UnitSelect.tsx, toga2-supply/src/pages/EditShipment/view/modals/SerialNumbersModal.tsx, 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/view/components/SelectedShipmentItemsTable.tsx, toga2-supply/src/pages/EditShipment/view/helpers/ShipmentDetailsForm/renderEditShipmentFormInput.tsx, toga2-supply/src/pages/EditShipment/viewModel/FIELDS/DUMMYUPDATESHIPMENTFIELDS.json, toga2-supply/src/pages/EditShipment/helpers/ShipmentDetailsForm/renderEditShipmentFormInput.tsx, toga2-supply/tailwind.config.cjs, toga2-supply/src/pages/EditShipment/view/modals/ReturnShippingModal.tsx, toga2-supply/src/styles/index.scss, toga2-supply/src/components/ui/BaseInput/BaseInput.tsx, toga2-supply/src/pages/EditShipment/api/UpdateShipmentApi.ts, toga2-supply/src/pages/EditShipment/viewModel/signatureTypes.ts, toga2-supply/src/pages/EditShipment/view/modals/SelectReturnAddressModal.tsx, toga2-supply/src/pages/EditShipment/helpers/ShipmentDetailsForm/formatShipmentData.ts, toga2-supply/src/pages/EditShipment/types.ts, toga2-supply/src/pages/Shipments/view/ShipmentsPage.tsx, toga2-supply/src/pages/Shipments/view/components/ShipmentsCardTableForm/ShipmentsCardTableForm.tsx, toga2-supply/src/pages/Shipments/api/ShipmentsApi.ts, toga2-supply/src/pages/Shipments/types.ts, toga2-supply/src/pages/FulfilledShipments/view/FulfilledShipmentsPage.tsx, toga2-supply/src/components/ui/CardTable/CardTable.tsx, toga2-supply/src/components/ui/CardTable/types.ts, toga2-supply/src/assets/pen-line.svg, _underscore/Model/Client/ItemFulfillment.php, _underscore/Trait/Netsuite/ItemFulfillment.php, _underscore/Component/Library/Carriers/Ups/Ups.php |
7
7
  | [AWS Amplify Build & Deploy (non-prod environments)](workflows/amplify-build-and-deploy.md) | How `toga2-supply` (React + Vite) builds and deploys on **AWS Amplify**. | toga2-supply/amplify.yml, toga2-supply/.gitattributes, toga2-supply/.github/workflows/sync-stage-environments.yml, toga2-supply/.env.qc-security |
@@ -6,9 +6,11 @@ project: TOGa Supply
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-07-15
9
+ updated: 2026-07-17
10
10
  owners: [mhammontree]
11
11
  files:
12
+ - toga2-supply/src/components/ui/BaseInput/UnitSelect.tsx
13
+ - toga2-supply/src/pages/EditShipment/view/modals/SerialNumbersModal.tsx
12
14
  - toga2-supply/src/pages/ShipmentItems/view/ShipmentItemsPage.tsx
13
15
  - toga2-supply/src/pages/EditShipment/view/EditShipmentPage.tsx
14
16
  - toga2-supply/src/pages/EditShipment/view/components/forms/EditShipmentForm.tsx
@@ -135,8 +137,11 @@ bare string** — see the gotcha below before wiring a new select field.
135
137
 
136
138
  - **Renderer extension points (how to add a non-BaseInput control).** `renderEditShipmentFormInput.tsx`
137
139
  special-cases fields by boolean flags on the JSON field object (existing: `isClearAll`, `isReadOnly`;
138
- added `isUnitSelector` = a native in./cm `<select>`, mirroring the Return Shipping modal — visual-only,
139
- not persisted). **Reuse pattern for any custom control: add a flag to the JSON field + a branch in the
140
+ added `isUnitSelector` = the in./cm unit selector, mirroring the Return Shipping modal — visual-only,
141
+ not persisted). The `isUnitSelector` branch now renders the shared **`UnitSelect`** component
142
+ (`src/components/ui/BaseInput/UnitSelect.tsx`) — a react-select styled to match the compact
143
+ `BaseInput` dropdowns (white menu, checkmark, FA chevron) — instead of a native `<select>`, so its
144
+ menu matches the other dropdowns; `ReturnShippingModal` uses the same component. **Reuse pattern for any custom control: add a flag to the JSON field + a branch in the
140
145
  renderer** rather than forcing it through `BaseInput`. A per-section `sectionTitleContainerClasses` is
141
146
  also read by `EditShipmentForm.tsx`'s shared section-title wrapper (default unchanged) so a section can
142
147
  e.g. right-align its title (used to right-align the Item Count column's title + value to a shared edge).
@@ -281,6 +286,38 @@ the call 403s and returns no label.
281
286
 
282
287
  ## Gotchas / known issues
283
288
 
289
+ - **⚠ A portaled react-select menu loses the control's inherited font size.** `BaseInput`'s
290
+ react-select menus now portal to `<body>` (`menuPortalTarget={document.body}` +
291
+ `styles.menuPortal` `zIndex 9999`, on both single- and multi-select) so the menu can't be
292
+ painted over by a sibling scroll box / stacking context (the symptom was the device-list
293
+ table clipping the dropdown). **Side effect:** once portaled, the menu is a child of `<body>`,
294
+ not the control, so it no longer inherits the control's font size and jumps to the browser
295
+ default (~16px). Fix: pin it back with `text-sm` on the react-select `menu` `classNames`.
296
+ Whenever you portal a react-select menu, re-assert font size on the menu.
297
+ (`src/components/ui/BaseInput/BaseInput.tsx`.)
298
+ - **⚠ Sticky table headers need a z-index ABOVE `BaseToolTip`'s `z-[9999]`.** `BasicTable` gained
299
+ a `stickyHeaderZ` prop (default `z-10`). `BaseToolTip` wraps its children in a `z-[9999]`
300
+ layer, so a tooltip-wrapped cell (e.g. a trash/delete column) shows THROUGH a sticky header
301
+ while scrolling unless the header's z beats it. **But you can't just crank it globally:** an
302
+ in-page table's header must stay `z-10` so it can never paint above a modal; a table that lives
303
+ *inside* a modal can safely use a very high z (`z-[10000]`) because it's already inside the
304
+ modal's stacking context. Pick the z per table location, not one global value.
305
+ - **⚠ Config-driven fixed-width form labels silently misalign when a label exceeds its width.**
306
+ Right-aligned label columns sized `w-[Npx] shrink-0` rely on every label fitting in `N`px —
307
+ flexbox `min-width:auto` will grow just the labels whose text is longer than `N` and shove
308
+ *their* inputs to the right, so only some rows misalign. Two rules: (1) size the label column to
309
+ the LONGEST label; (2) keep the label→input spacing identical on EVERY row — a stray double
310
+ space (`"items-center pb-3"`) made one row miss a bulk `gap-2` sweep and sit 8px off. Concrete
311
+ fix: the Update Info address block was matched to the Edit Return Label block (labels `w-[70px]`,
312
+ ZIP `w-[36px]`, `flex items-center gap-2`), address column widened `col5 w-80`→`w-96`, and a
313
+ ZIP-favoring grid split `grid-cols-[1fr_1fr_1fr_1.25fr_1.25fr]` so a full ZIP+4 fits.
314
+ - **Fixed-height modals overflow short viewports — size to the viewport, not to px.** The Add
315
+ Serial Numbers modal was `h-[822px]` and overflowed short screens. Reusable pattern that fixed
316
+ it: modal `max-h-[90vh] overflow-y-auto`, the inner scrolling list sized to the viewport
317
+ (`max-h-[40vh]`) rather than fixed px, drop the fixed `h-[90%]`/`h-[822px]` wrapper, and give the
318
+ in-modal sticky header a z above tooltips (see the `stickyHeaderZ` gotcha — modal tables can use
319
+ `z-[10000]`). Files: `src/pages/EditShipment/view/modals/SerialNumbersModal.tsx`,
320
+ `SelectedShipmentItemsTable.tsx`.
284
321
  - **⚠ Native `<datalist>` renders its OWN dropdown arrow, un-hideable by Tailwind.** An
285
322
  `<input list>` combobox (the Edit Return Label Addressee) shows a **second dark arrow** (the
286
323
  webkit calendar-picker indicator) that a Tailwind arbitrary variant can't reliably hide. Kill it
@@ -497,6 +534,23 @@ not the base `_Model_Client_ItemFulfillment`. Tested with GroWrk; UPS support wa
497
534
  for Compass and is not yet in prod.
498
535
 
499
536
  ## Change history
537
+ - 2026-07-17 — TRUE-79191 (David design-review pass, toga2-supply UI): documented four durable,
538
+ app-wide component gotchas — (1) **`BaseInput` react-select menus now portal to `<body>`**
539
+ (`menuPortalTarget` + `menuPortal zIndex 9999`) so a sibling scroll box can't clip them, and the
540
+ side effect that a portaled menu loses the control's font size (re-pin with `text-sm` on the `menu`
541
+ classNames); (2) **`BasicTable` gained `stickyHeaderZ`** (default `z-10`) because sticky headers
542
+ must beat `BaseToolTip`'s `z-[9999]` to stop tooltip-wrapped cells showing through — but in-page
543
+ tables must stay `z-10` (never above a modal) while in-modal tables can use `z-[10000]`; (3) the
544
+ **fixed-width form-label misalignment** footgun (size the column to the longest label + keep
545
+ identical label→input spacing on every row); and (4) the **fixed-height-modal overflow** pattern
546
+ (modal `max-h-[90vh] overflow-y-auto` + inner list `max-h-[40vh]`, drop fixed px) via the Add Serial
547
+ Numbers modal. Also: new shared **`UnitSelect`** component (react-select styled to match the compact
548
+ dropdowns) replaced the native in./cm `<select>` in the renderer's `isUnitSelector` branch and in
549
+ `ReturnShippingModal`; `SupplyFormGuardrail` now renders a dimmed click-to-cancel backdrop
550
+ (`fixed inset-0 z-[9920] bg-black/40`) so it reads as a lightbox; and the Update Info address block
551
+ was aligned to the Edit Return Label block (labels `w-[70px]`/ZIP `w-[36px]`, address col `w-96`,
552
+ ZIP-favoring 5-col grid). The return-validation spinner (left of the modal's Cancel while validating)
553
+ and the Select Return Address Figma tuning were cosmetic — no separate doc change. (mhammontree)
500
554
  - 2026-07-17 — TRUE-79191: replaced the boolean `requiresSignature` with a **4-level `signatureType`
501
555
  enum** (None Specified / Indirect / Direct / Adult) — `viewModel/signatureTypes.ts` is the single
502
556
  source of truth (options, `signatureCardLabel`, `requiresSignatureFromLevel` back-compat,
@@ -6,7 +6,7 @@ project: Worker
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-06-26
9
+ updated: 2026-07-17
10
10
  owners: [dfranks]
11
11
  files:
12
12
  - .claude/skills/plan-ticket/scripts/talos.js
@@ -79,6 +79,26 @@ The browser obtains the initial token pair via the `talos.togaiq.com` login. A d
79
79
  copy `accessToken` + `refreshToken` out of the browser session to seed a local tool, after
80
80
  which the tool refreshes on its own.
81
81
 
82
+ ## Gotcha — intermittent tool-selection failure (empty `{}` ≠ "no notes")
83
+
84
+ DevCore is **nondeterministic** in which tool it picks for a meeting-notes query. On some
85
+ runs it emits a tool call to **`search_knowledge_base`**, which is **no longer a registered
86
+ tool** on the server. The runtime rejects it —
87
+ `Error: search_knowledge_base is not a valid tool, try one of [toga_health,
88
+ toga_list_environments, toga_list_clusters, toga_list_schemas, ...]` (the registry now
89
+ exposes the TOGa Database Integration tools instead). On those runs the run produces **no
90
+ final `ai` answer** and `talos.js` prints an empty `{}`. Other runs pick a valid KB-search
91
+ tool and return real cited meeting notes.
92
+
93
+ - **Do not read an empty `{}` as "no meeting notes found."** It is a transient
94
+ tool-selection failure — treating it as an answer leads to fabricated "no notes"
95
+ conclusions.
96
+ - **Workaround:** retry the query until non-empty (a simple retry loop, ~4 attempts, clears
97
+ it in practice).
98
+ - **Root fix is server-side:** whoever owns the DevCore assistant config should re-register
99
+ the meeting-notes KB-search tool (or update the assistant's system prompt to the current
100
+ tool name).
101
+
82
102
  ## Credential storage (location only)
83
103
 
84
104
  The consumer tool stores its token pair at **`~/.talos/credentials.json`** (user home,
@@ -94,4 +114,5 @@ mirrored into the knowledge base.
94
114
 
95
115
  ## Change history
96
116
 
117
+ - 2026-07-17 — Added the intermittent tool-selection gotcha: DevCore nondeterministically calls the now-unregistered `search_knowledge_base` tool → run yields no `ai` answer and `talos.js` prints empty `{}`; treat empty as a transient failure (retry ~4x), not "no notes found"; root fix is re-registering the KB-search tool server-side (dfranks)
97
118
  - 2026-06-26 — Initial doc: consumer-side Talos meeting-notes access via DevCore assistant + the `/v2/auth/refresh` token-rotation flow; stateless `[talos]` config vs. assistant distinction; EV-2/EV-5 gotchas; credential location `~/.talos/credentials.json` (dfranks)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.364",
3
+ "version": "1.0.366",
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",