fix: keep extension 0.5.167 after updater rollback
This commit is contained in:
@@ -10,9 +10,9 @@ Reverted
|
||||
|
||||
## Reversal
|
||||
|
||||
On 2026-09-03 the user explicitly directed that this iteration be backed up and removed from the main branch. The exact integrated state at commit `b2e33e2e5d29138891eabc93969cf24907492dfe` is preserved on remote branch `codex/backup-extension-update-20260903-b2e33e2`; active `main` restores the pre-iteration extension `0.5.165` and migration 018 baseline through a normal revert of merge `3224758`.
|
||||
On 2026-09-03 the user explicitly directed that this iteration be backed up and its server-side automatic-update architecture removed from the main branch, then clarified that the Chrome plugin itself must remain at `0.5.167`. The exact full-stack state at commit `b2e33e2e5d29138891eabc93969cf24907492dfe` is preserved on remote branch `codex/backup-extension-update-20260903-b2e33e2`; active `main` keeps the exact `0.5.167` plugin source/package but restores the control plane to migration 018 with no private-OSS/ECS update orchestration.
|
||||
|
||||
This ADR is retained only as historical design context and no longer governs the active architecture. The reverted code was never deployed, migration 019 was not applied, no OSS extension release was published, and no Cloud Assistant or Chrome reload action was performed by these repository tasks.
|
||||
This ADR is retained only as historical server-architecture context and no longer governs the active control plane. Plugin-side idle proof and guarded reload handlers remain as dormant `0.5.167` capabilities with no current server/platform trigger. The reverted server code was never deployed, migration 019 was not applied, no OSS extension release was published, and no Cloud Assistant or Chrome reload action was performed by these repository tasks.
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|---|---|---|---|
|
||||
| DOC-LEGACY-001 | Root `task_plan.md`, `findings.md`, and `progress.md` were the active project-memory system. | DOC-001 | 2026-08-28 |
|
||||
| AUTH-001 (partial) | Organization-wide ERP FIFO and archive-only operator removal. | AUTH-002 | 2026-09-03 |
|
||||
| EXT-001 | Central-service private-OSS and ECS Cloud Assistant orchestration for shared unpacked-extension updates. | Reverted by explicit user decision; exact implementation preserved on `codex/backup-extension-update-20260903-b2e33e2`. | 2026-09-03 |
|
||||
| EXT-001 | Central-service private-OSS and ECS Cloud Assistant orchestration for shared unpacked-extension updates. | Server architecture reverted by explicit user decision; exact full implementation is preserved on `codex/backup-extension-update-20260903-b2e33e2`, while plugin `0.5.167` remains current. | 2026-09-03 |
|
||||
|
||||
## Decision Criteria
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Authenticated manual or account-bound AgentBus input is routed through task-scop
|
||||
| `schemas/` and `mappings/` | Parse-state, execution-state, ERP form, field, and lifecycle contracts | Current contracts only |
|
||||
| `control-plane/` | Task/session persistence, parser orchestration, confirmation, audit, AgentBus channel ownership, task assignment, browser workers, attachments, receipts, and structured diagnostics | TypeScript source; build output goes to `.build/` |
|
||||
| `LianSyn-platform/` | Operator workbench and external parser adapter | Source and UI, not local task output |
|
||||
| `chrome-extension/ltjt-order-assistant/` | Logged-in ERP resolution, preflight, native execution, response handling, and requery | Any code change requires synchronized versioned release updates |
|
||||
| `chrome-extension/ltjt-order-assistant/` | Logged-in ERP resolution, preflight, native execution, response handling, requery, and dormant idle/reload safety handlers | Current server/platform does not trigger automatic updates; any code change requires synchronized versioned release updates |
|
||||
| `dist/` | Versioned current deliverables and machine-readable release manifest | Not a compilation directory |
|
||||
| `.project-docs/` | Task-isolated project memory and integrated canonical context | No runtime dependency |
|
||||
| `archive/` | Date-scoped immutable history and evidence | Never defines current behavior |
|
||||
@@ -28,6 +28,7 @@ Authenticated manual or account-bound AgentBus input is routed through task-scop
|
||||
- Each enabled AgentBus channel owns one active non-admin employee account. Inbound work uses that account and route allowlist, persists the same account as immutable task assignee, and is returned only to that account's executable feed.
|
||||
- Each employee account has one expected ERP identity and at most one fresh browser execution worker. Mismatched ERP identity, concurrent fresh workers, unbound channels, or unassigned tasks fail closed. Browser claims, active-execution checks, and confirmed FIFO are serialized per immutable task assignee, so one account cannot block or occupy another account's queue.
|
||||
- Administrator-wide task visibility is a read model, not an executable feed. Task SSE history/live events, browser claims, plugin-result ingestion, and browser cleanup commands are always scoped to the authenticated account matching `assigned_user_id`, including for administrators.
|
||||
- Extension `0.5.167` is the current manually published/loaded plugin baseline. It retains an idle-proof and guarded-reload message protocol, but the active control plane has no extension-release tables, ECS host mapping, OSS publication endpoint, Cloud Assistant dispatcher, or platform trigger; required migration remains 018.
|
||||
- Creator and manual input-turn attribution remain durable while business input stays encrypted at rest. Routine removal is reversible archive/restore. Separately confirmed force delete physically removes an authorized task regardless of lifecycle state, retains only a minimal non-content deletion audit marker, and cannot undo an ERP write that already occurred.
|
||||
- Unknown, ambiguous, unverified, or post-write-uncertain states fail closed; automatic retries must not create duplicate writes.
|
||||
- PostgreSQL is the sole required durable database/state middleware, and the production artifact provider is OSS. Redis, message queues, MongoDB, and search services are not runtime dependencies.
|
||||
|
||||
@@ -4,8 +4,8 @@ This file is the integrated default-branch snapshot. Feature tasks record progre
|
||||
|
||||
## Integrated Through
|
||||
|
||||
- Rollback commit `81a0cda` from integration task `20260903-backup-revert-extension-update-c71a4e92` for preserving the complete former `0.5.167`/migration-019 iteration at remote branch `codex/backup-extension-update-20260903-b2e33e2`, reverting merge `3224758` without rewriting history, and restoring the active product/release baseline to `f52d9d7` (`0.5.165`, migration 018).
|
||||
- Merge commit `3224758` and integration task `20260903-finalize-extension-update-a6c4e192` remain historical records of the briefly integrated extension-update design; that design is no longer active and is preserved on the backup branch only.
|
||||
- Rollback/correction task `20260903-backup-revert-extension-update-c71a4e92` preserved the complete former `0.5.167`/migration-019 stack at remote branch `codex/backup-extension-update-20260903-b2e33e2`, removed the central private-OSS/ECS automatic-update service architecture without rewriting history, and retained the exact Chrome extension `0.5.167` source/package on the active main line with migration 018.
|
||||
- Merge commit `3224758` and integration task `20260903-finalize-extension-update-a6c4e192` remain historical records of the full-stack extension-update design. Only the plugin `0.5.167` release, adaptive entry readiness, and dormant plugin-side idle/reload safeguards remain active; the server orchestration is preserved on the backup branch only.
|
||||
- Commit `c4c469f4441d744627af2d34abe693b6783e833c` for the independently advanced remote deployment/extension line.
|
||||
- Commit `cd45ce17d0fcd25f7fa89ab9f8a391d3e904ecdf` for WeChat attachment correlation and privacy-safe server diagnostics.
|
||||
- Commit `161f90d09d6ad1368973b1a85d51059059495223` for trusted-intranet attachment compatibility and canonical reconciliation.
|
||||
@@ -33,7 +33,7 @@ This file is the integrated default-branch snapshot. Feature tasks record progre
|
||||
|
||||
## Current Focus
|
||||
|
||||
Operate the repository's current `0.5.165` extension baseline and fixed-scope account model safely, bind each enabled AgentBus channel to one employee/ERP identity, provision narrow route grants, use explicit leadership-dashboard filters, and preserve Program/AI plus per-assigned-account ERP execution boundaries. Same-account tasks remain FIFO and single-active; distinct accounts are independent, and administrator visibility never enters another account's executable event/result path. Migration 018, extension reload, guarded product-search retry, and service rollout remain separately authorized runtime work.
|
||||
Operate the repository's current `0.5.167` extension baseline and fixed-scope account model safely, bind each enabled AgentBus channel to one employee/ERP identity, provision narrow route grants, use explicit leadership-dashboard filters, and preserve Program/AI plus per-assigned-account ERP execution boundaries. Same-account tasks remain FIFO and single-active; distinct accounts are independent, and administrator visibility never enters another account's executable event/result path. Migration 018, manual extension reload, guarded product-search retry, and service rollout remain separately authorized runtime work; server-side automatic extension updating is not part of the active main line.
|
||||
|
||||
## Recently Completed
|
||||
|
||||
@@ -57,16 +57,16 @@ Operate the repository's current `0.5.165` extension baseline and fixed-scope ac
|
||||
- 2026-09-02: Integrated extension `0.5.165`: scatter-plan creation and independent batch-order creation now try loaded product candidates, then the form's native non-empty `S_chanpinming` search, and finally one bounded empty-query compatibility reload. A user-authorized search-only ERP check returned exactly one target row in both forms without selecting or saving it; zero or multiple local matches continue to fail closed.
|
||||
- 2026-09-03: Accepted AUTH-002 and integrated account-scoped ERP queues. Each immutable assignee now owns one FIFO/single-active claim partition, different accounts no longer block one another, and executable SSE/results/cleanup commands are owner-only even when an administrator is signed in.
|
||||
- 2026-09-03: Restored explicit permanent force deletion as a separate operation from reversible archive/restore. It bypasses lifecycle-state gates, physically removes task-owned platform records, retains a minimal deletion audit marker, performs post-commit cleanup best effort, and warns that prior ERP effects are not rolled back.
|
||||
- 2026-09-03: Backed up the complete adaptive-readiness and central extension-update iteration at remote branch `codex/backup-extension-update-20260903-b2e33e2`, then reverted it from `main` with a normal history-preserving commit. The active repository again uses extension `0.5.165` and migration 018; the reverted iteration was never deployed by these tasks.
|
||||
- 2026-09-03: Backed up the complete adaptive-readiness and central extension-update stack at remote branch `codex/backup-extension-update-20260903-b2e33e2`, then removed the central OSS/ECS update service and migration 019 from `main` with normal history-preserving commits. After correcting an initially over-broad rollback, the active repository retains the exact extension `0.5.167` source/package and uses migration 018; the removed server architecture was never deployed by these tasks.
|
||||
|
||||
## In Progress
|
||||
|
||||
- The standard database currently contains one administrator account and no non-administrator task grants. Multi-account operational smoke testing remains for an administrator-led staging window.
|
||||
- Migration `018_agentbus_account_workers`, employee ERP identities/channel bindings, extension `0.5.165`, account-scoped queue/routing changes, force-delete behavior, and the merged dashboard/runtime changes have not been applied to or restarted on the standard service in this integration task.
|
||||
- Migration `018_agentbus_account_workers`, employee ERP identities/channel bindings, extension `0.5.167`, account-scoped queue/routing changes, force-delete behavior, and the merged dashboard/runtime changes have not been applied to or restarted on the standard service in this integration task.
|
||||
|
||||
## Next Recommended Steps
|
||||
|
||||
1. In an explicitly authorized staging/rollout window, back up PostgreSQL, apply migration 018, restart the control plane, load extension `0.5.165`, verify its runtime handshake, configure employee ERP identities and channel bindings, and run the multi-cloud-PC/identity/failover plus account-queue matrix before production assurance.
|
||||
1. In an explicitly authorized staging/rollout window, back up PostgreSQL, apply migration 018, restart the control plane, manually load extension `0.5.167`, verify its runtime handshake, configure employee ERP identities and channel bindings, and run the multi-cloud-PC/identity/failover plus account-queue matrix before production assurance.
|
||||
2. Through the administrator UI, create representative team-lead and ordinary accounts, assign narrow task grants, and verify owner isolation, leadership dashboard reads, grant/revoke behavior, and denial prompts without ERP writes.
|
||||
3. In the same authorized staging window, verify that an administrator receives no employee executable events/results, then force-delete disposable waiting and active employee tasks and confirm database absence plus cleanup only in the owning employee plugin.
|
||||
4. With explicit authorization, run a live read-only ERP verification of the shared-mother-plan `tid-only` whole-visitor export path.
|
||||
|
||||
@@ -9,5 +9,5 @@ This is integrated history. Feature tasks write only their task-scoped records;
|
||||
| 2026-08-28 | Shared mother-plan whole-visitor export | Released strict `shared_plan + visitor-list + tid-only` routing and execution boundaries in extension `0.5.157`. | [Release gate](../../agent设计规范/test-fixtures/lwlt-lifecycle/release-gate.md) |
|
||||
| 2026-09-02 | AgentBus account workers | Integrated one-to-one employee channel ownership, immutable task assignment, expected ERP identity, single-fresh-worker enforcement, migration 018, and extension `0.5.164`. | [Integration task](tasks/20260902-integrate-all-push-c93a7f21.md) |
|
||||
| 2026-09-02 | Leadership dashboard query and filter contract | Integrated bounded single-connection reads, 20-row paging, cancellation/timeout feedback, display-only metrics, and explicit result filtering. | [Integration task](tasks/20260902-integrate-all-push-c93a7f21.md) |
|
||||
| 2026-09-03 | Adaptive ERP readiness and extension host updates | Integrated immediate-first scatter-plan readiness plus private OSS/ECS host updating as extension `0.5.167`; this iteration was later reverted from `main` before deployment. | [Original integration task](tasks/20260903-finalize-extension-update-a6c4e192.md) |
|
||||
| 2026-09-03 | Extension-update iteration backup and rollback | Preserved exact commit `b2e33e2` on remote branch `codex/backup-extension-update-20260903-b2e33e2` and restored active extension `0.5.165` plus migration 018 through a non-force revert. | [Rollback task](tasks/20260903-backup-revert-extension-update-c71a4e92.md) |
|
||||
| 2026-09-03 | Adaptive ERP readiness and extension host updates | Integrated immediate-first scatter-plan readiness plus private OSS/ECS host updating as extension `0.5.167`; the server-update architecture was later reverted before deployment while the plugin release was retained. | [Original integration task](tasks/20260903-finalize-extension-update-a6c4e192.md) |
|
||||
| 2026-09-03 | Extension-update iteration backup and scoped rollback | Preserved exact commit `b2e33e2` on remote branch `codex/backup-extension-update-20260903-b2e33e2`, removed migration 019 and server-side automatic updating, and retained extension `0.5.167` plus migration 018 through non-force commits. | [Rollback task](tasks/20260903-backup-revert-extension-update-c71a4e92.md) |
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
- Worktree: /Users/inmanx/Documents/lwltAPI-finalize-extension-update-a6c4e192
|
||||
- Base commit: b2e33e2e5d29138891eabc93969cf24907492dfe
|
||||
- Owner: codex
|
||||
- Status: Integrated and pushed
|
||||
- Status: Correction verified; push pending
|
||||
|
||||
## Scope
|
||||
|
||||
- Preserve the complete extension-update iteration currently at remote `main` commit `b2e33e2` on a dedicated remote backup branch before changing `main`.
|
||||
- Revert merge commit `3224758` through a normal history-preserving commit, restoring the active product source, migration boundary, extension release, and governed artifacts to the pre-iteration `f52d9d7` baseline.
|
||||
- Revert the central-service automatic-update orchestration carried by merge `3224758` through normal history-preserving commits, while retaining the released Chrome extension `0.5.167`, its adaptive ERP readiness behavior, dormant idle/reload safety protocol, synchronized mappings, tests, ZIP, archive, and release manifest.
|
||||
- Preserve the source and integration task records as historical evidence, mark accepted decision `EXT-001` as reverted, and reconcile canonical project memory to the restored active architecture.
|
||||
- Run the complete repository, release, document, test, and build gates, then advance remote `main` with a normal non-force push.
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
|
||||
- The user explicitly requested a branch backup followed by rollback of this plugin-update iteration. This supplies the required human decision to reverse accepted architecture and product behavior.
|
||||
- The exact backup ref is `codex/backup-extension-update-20260903-b2e33e2`; it must resolve remotely to `b2e33e2e5d29138891eabc93969cf24907492dfe` before the rollback continues.
|
||||
- Roll back both commits carried by merge `3224758`: adaptive ERP entry readiness (`500034b`, extension `0.5.166`) and central OSS/ECS Cloud Assistant updates (`f08aac0`, migration 019 and extension `0.5.167`). The restored current release is extension `0.5.165` with required migration 018.
|
||||
- The user's correction establishes the intended boundary: extension `0.5.167` remains current. Remove the central OSS/ECS Cloud Assistant service implementation, account/host UI, dependencies, configuration and migration 019, but keep the exact published `0.5.167` plugin bytes and the `0.5.166` adaptive ERP entry readiness they contain. Required database migration remains 018.
|
||||
- Do not create a second payload under version `0.5.167`. Restore the exact source and ZIP from merge `3224758`, SHA-256 `6822ec660097a8889da8ea4fa22d4091467aa022067bff3bee2ac5406864b679`; the plugin-side update messages remain dormant because the current platform/server does not trigger them.
|
||||
- Use `git revert`, not a force push or history rewrite. Keep prior task records and the reverted ADR so the decision trail remains auditable and recoverable from the backup branch.
|
||||
- The local `main` checkout is owned by task `20260902-migrate-restart-confirmed-4f8c2a71` and contains its untracked task record. Do not alter, adopt, stash, reset, or clean that worktree.
|
||||
- Do not deploy, restart, migrate a database, access ERP, publish to OSS, invoke Cloud Assistant, reload Chrome, mutate live tasks, or inspect secrets.
|
||||
@@ -29,10 +30,12 @@
|
||||
## Outcome
|
||||
|
||||
- Remote backup branch `codex/backup-extension-update-20260903-b2e33e2` was created first and independently verified at exact commit `b2e33e2e5d29138891eabc93969cf24907492dfe`.
|
||||
- Reverted merge `3224758` in the isolated Integration worktree while retaining both source task records and the former integration record. Product source, dependencies, migration readiness, extension source, release package, mappings, tests, and operational documentation now match the pre-iteration `f52d9d7` tree exactly.
|
||||
- Restored extension `0.5.165`, release ZIP SHA-256 `14f3150ab26d99131e32321ddc805a85550438bc2810a1e20921f7922b25aaac`, and required schema migration `018_agentbus_account_workers`; removed active migration 019 and the central OSS/ECS update implementation from the main-line result.
|
||||
- The first rollback commit `81a0cda` was too broad: it restored extension `0.5.165` together with the service baseline. After the user clarified that the plugin must remain `0.5.167`, this task resumed to correct that scope without rewriting either commit or remote history.
|
||||
- Restored the exact extension `0.5.167` source/package from merge `3224758`, including adaptive list-entry readiness and its dormant idle/reload safety handlers; synchronized the platform minimum version, mappings, business/release documentation, focused tests, archived prior releases, and `dist/release-manifest.json`.
|
||||
- Kept required schema migration `018_agentbus_account_workers`; migration 019, central OSS/ECS update orchestration, update endpoints/poller, account-to-ECS fields/UI, Alibaba SDK dependencies and production update configuration remain removed from the main-line result.
|
||||
- Marked `EXT-001` as Reverted and reconciled the decision index, system overview, data flow, current state, task history, evidence index, and rollout commitment.
|
||||
- Created rollback commit `81a0cdac8ea4be867ab43d0a84ffa547d159223d`. After a fresh fetch proved `origin/main` was still exactly `b2e33e2` and an ancestor of the rollback commit, a normal non-force push advanced remote `main` to `81a0cda`.
|
||||
- Prepared a forward correction that retains the exact `0.5.167` plugin release while leaving the central updater rollback intact; commit and non-force push are pending.
|
||||
- No production deployment, service restart, database migration, OSS publication, ECS command, Chrome reload, ERP access, live task mutation, history rewrite, or secret access occurred.
|
||||
|
||||
## Verification
|
||||
@@ -42,18 +45,19 @@
|
||||
- `node --run check:repo`: 10/10 passed, including exact release-set hashes and extension ZIP/source equality.
|
||||
- `node --run check`: passed.
|
||||
- `node --run test:control-plane`: 162/162 passed.
|
||||
- `node --run test:legacy`: 268/268 passed.
|
||||
- `node --run test:legacy`: 270/270 passed, including adaptive entry readiness and dormant `0.5.167` plugin idle/reload safety coverage.
|
||||
- `node --run build`: passed.
|
||||
- `node --check` passed for extension `background.js`, `business-bridge.js`, and `inpage.js`.
|
||||
- `unzip -t dist/ltjt-order-assistant-0.5.165.zip`: passed; SHA-256 equals the restored release manifest.
|
||||
- Explicit version check returned source/release/artifact `0.5.165` and required migration `018_agentbus_account_workers`.
|
||||
- `git diff --exit-code f52d9d7 -- . ':(exclude).project-docs'`: passed, proving the active product tree exactly matches the pre-iteration baseline.
|
||||
- `unzip -t dist/ltjt-order-assistant-0.5.167.zip`: passed; SHA-256 is `6822ec660097a8889da8ea4fa22d4091467aa022067bff3bee2ac5406864b679` and equals both the release manifest and the package at merge `3224758`.
|
||||
- Exact path comparisons against `3224758` passed for the extension source, current/archived release packages, release manifest, lifecycle/plan mappings, and shared-plan business contract.
|
||||
- Exact path comparisons against pre-updater baseline `f52d9d7` passed for the control plane, dependency manifests, production environment example, and platform HTML/styles. Platform JavaScript differs only by the required extension version `0.5.167`.
|
||||
- Explicit architecture checks returned required migration `018_agentbus_account_workers` and confirmed migration 019, `extension-updates.ts`, update endpoints/poller, account-to-ECS fields/UI, Alibaba SDK dependencies, and production updater configuration are absent.
|
||||
- `check_project_docs.py`, `check_doc_drift.py --task-id 20260903-backup-revert-extension-update-c71a4e92`, and `git diff --check`: passed before commit.
|
||||
- Post-push fetch and `git ls-remote` returned remote `main` at `81a0cdac8ea4be867ab43d0a84ffa547d159223d` and the backup branch at `b2e33e2e5d29138891eabc93969cf24907492dfe`.
|
||||
- The initial rollback push was verified with remote `main` at `81a0cdac8ea4be867ab43d0a84ffa547d159223d`; final correction push verification remains pending. The remote backup branch remains at exact commit `b2e33e2e5d29138891eabc93969cf24907492dfe`.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- None planned. The reverted implementation remains available only on the named backup branch unless a future explicit decision revives it.
|
||||
- The full server-side automatic-update implementation remains available on the named backup branch. The active `0.5.167` plugin continues to use the existing manual publication/loading workflow unless a future explicit decision revives server orchestration.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ Use this index for searchable, traceable evidence records.
|
||||
| 2026-09-02 | Leadership-dashboard filtering and summary interaction | Repository and focused regression verified; merged runtime not restarted | [Integration record](../30-worklog/tasks/20260902-integrate-all-push-c93a7f21.md) | Single-connection bounded reads, SQL prefiltering, selective hydration, 20-row paging, cancellation/timeout feedback, and display-only metric cards with explicit filters passed combined regression. |
|
||||
| 2026-09-02 | Native ERP product search for ordering forms | Root cause and live search-only behavior verified; repository/release verified; extension not reloaded | [Integration task](../30-worklog/tasks/20260902-integrate-product-search-3b7f6a20.md) | Both `plan_add.asp` and `orders_adds.asp` returned exactly one target product for the full keyword with radios left unchecked and no save; extension `0.5.165` now uses native non-empty search before its bounded empty-query fallback while retaining deterministic unique matching. |
|
||||
| 2026-09-03 | Account-scoped ERP queues, assignee-only executable routing, and force delete | Repository and full regression verified; runtime not deployed or mutated | [Integration task](../30-worklog/tasks/20260903-finalize-account-routing-7c4e2a91.md) | Source task `20260902-per-account-queue-hard-delete-a6d9f2c1` replaced global head-of-line blocking with per-assignee FIFO/advisory locks, isolated SSE/plugin-result/browser-command routing from administrator read visibility, and separated reversible archive from lifecycle-independent physical deletion. |
|
||||
| 2026-09-03 | Adaptive ERP readiness and central extension host updates | Historical repository evidence; reverted from `main` before production rollout | [Original integration task](../30-worklog/tasks/20260903-finalize-extension-update-a6c4e192.md) | Source commits `500034b` and `f08aac0`, release `0.5.167`, and their verification remain recoverable at exact commit `b2e33e2` on remote branch `codex/backup-extension-update-20260903-b2e33e2`; they no longer define active source or release behavior. |
|
||||
| 2026-09-03 | Extension-update iteration rollback | Backup ref verified; active code/release restored and regression rechecked | [Rollback task](../30-worklog/tasks/20260903-backup-revert-extension-update-c71a4e92.md) | The complete iteration was backed up before a normal revert of merge `3224758`; active main returns to extension `0.5.165` and migration 018 without rewriting Git history. |
|
||||
| 2026-09-03 | Adaptive ERP readiness and central extension host updates | Mixed disposition: plugin/release retained; server architecture reverted before production rollout | [Original integration task](../30-worklog/tasks/20260903-finalize-extension-update-a6c4e192.md) | Exact extension `0.5.167` source/package and adaptive readiness remain active. Migration 019 and central private-OSS/ECS orchestration are recoverable only at exact commit `b2e33e2` on remote branch `codex/backup-extension-update-20260903-b2e33e2`. |
|
||||
| 2026-09-03 | Extension-update iteration scoped rollback | Backup ref verified; `0.5.167` retained; server/migration rollback and regression rechecked | [Rollback task](../30-worklog/tasks/20260903-backup-revert-extension-update-c71a4e92.md) | The full stack was backed up before normal non-force commits removed server-side automatic updating and migration 019; active main keeps extension `0.5.167` and migration 018 without rewriting Git history. |
|
||||
|
||||
## When To Add Evidence
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Track future-facing memory: promised follow-ups, unfinished loops, timed checks,
|
||||
| 2026-08-28 | Resolve AgentBus OSS attachment rejection caused by private/reserved local DNS answers. | User scheduled integration and confirmed the environment is trusted internal networking | Integration task `20260831-integrate-server-diagnostics-8b42c6d1` | Completed in repository | Deploy/restart and run one live internal attachment verification only under separate authorization. |
|
||||
| 2026-09-02 | Roll out and stage-test AgentBus account workers, account-scoped queues, and force deletion. | Explicit authorization for database backup/migration, service restart, extension reload, account/channel configuration, staging traffic, and disposable task mutation | Future authorized rollout task | Pending authorization | Apply migration 018 and extension `0.5.165`; verify two employee accounts/cloud PCs, ERP identity mismatch, same-account worker conflict/FIFO, cross-account independence, 90-second failover, administrator executable-feed isolation, manual/AgentBus routing, and waiting/active force-delete cleanup. |
|
||||
| 2026-09-02 | Verify the integrated native product-search execution path. | Explicit authorization for extension reload and a guarded ERP preflight/retry | Future authorized rollout task | Pending authorization | Load extension `0.5.165`, confirm the runtime handshake, then verify deterministic product selection and normal write gates without automatically retrying the earlier failed task. |
|
||||
| 2026-09-03 | Bootstrap and canary the central extension-update channel. | Former rollout plan for reverted `EXT-001` | None while reverted | Cancelled by user rollback | Do not deploy migration 019 or extension `0.5.167` from `main`; consult backup branch `codex/backup-extension-update-20260903-b2e33e2` only if a future explicit decision revives the design. |
|
||||
| 2026-09-03 | Bootstrap and canary the central extension-update channel. | Former rollout plan for reverted server-side `EXT-001` architecture | None while reverted | Cancelled by user rollback | Extension `0.5.167` remains the current manual plugin release. Do not deploy migration 019 or the removed server updater from `main`; consult `codex/backup-extension-update-20260903-b2e33e2` only if a future explicit decision revives that architecture. |
|
||||
|
||||
## Use
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ const persistedExtensionResultVersions = new Map();
|
||||
let taskCreateInProgress = false;
|
||||
const AUTO_HANDOFF_RETRY_MS = 30_000;
|
||||
|
||||
const REQUIRED_EXTENSION_VERSION = '0.5.165';
|
||||
const REQUIRED_EXTENSION_VERSION = '0.5.167';
|
||||
const MANUAL_HANDOFF_LABEL = '确认并提交到 ERP 插件';
|
||||
const RETRY_HANDOFF_LABEL = '继续提交到 ERP 插件';
|
||||
const RECONCILE_LABEL = '只读回查 ERP 现有结果';
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
|
||||
当前页面为已登录的 `https://lwlt.hisy.cc/System/Mainlt.asp`。插件按以下顺序操作:
|
||||
|
||||
1. 进入“散拼团计划表”,点击“新增计划”,打开 `/System/Business/plan_add.asp`。
|
||||
1. 进入“散拼团计划表”后立即检查“新增计划”按钮;若 ERP 主 iframe 已进入 `/System/Business/plan.asp` 但按钮仍在渲染,则持续重新取得当前 iframe document 并按条件短轮询,按钮一旦存在且可用便立即点击,不使用固定等待。只有在 15 秒总超时后仍不可用才在写前阻断,然后打开 `/System/Business/plan_add.asp`。
|
||||
2. 填写 `Riqi1=2026-09-01`、`Riqi2=2026-09-30`。
|
||||
3. 先在散拼团产品列表的产品名称/天数单元格中按 `广东衡阳6D` 做连续或有序唯一匹配并点选 `cp_id`。若当前候选无法解析,调用 `S_chanpinming` 的原生非空检索:完整产品名原样搜索,`10D`/`8天` 等尾部数字时长先剥离后只搜索产品名;再对返回候选本地唯一匹配,必要时以空条件做一次兼容重载。点选后的 `set_th` 必须自动带入团号前缀/后缀。
|
||||
4. 填写 `jihuashu=40`。
|
||||
@@ -109,6 +109,7 @@
|
||||
- 日期枚举无法完整覆盖周期日期,或同一日期会提交多个勾选值;
|
||||
- 计划容量或房型总数为 0,或已提供的可选字段未能正确落到 ERP 控件;
|
||||
- ERP 默认跟团人/销售人为空;
|
||||
- 散拼团计划表在 15 秒条件等待后仍未出现可用的“新增计划”按钮;
|
||||
- 页面自身校验弹窗、登录失效、权限错误、响应不明确或任一返回团号回查未命中。
|
||||
|
||||
## 3. Skill 适配
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
|
||||
## 当前基线
|
||||
|
||||
- Chrome 插件:`0.5.165`
|
||||
- Chrome 插件:`0.5.167`
|
||||
- Agent Prompt:`ltjt-agent-prompt-v1.8-independent-headcount-categories`
|
||||
- 生命周期契约:`ltjt-lifecycle-v2.9-roster-leader-contact-2026-08`
|
||||
- 五个 Skill:`0.5.125`;运营 DOCX:`0.5.125`
|
||||
- 发布状态:核心窄能力已有真实证据;一笔名单附件 Program-only 任务已把 25 行及唯一领队联系人正确保存到 ERP,后续只读逐字段核验全等。两种写后逐行读取方式都曾在真实成功写入后产生假阴性;名单在全部写前门禁通过后,以父表单 ERP 明确成功响应作为终结证据,不再执行写后逐行回查或自动名单对账。`0.5.155` 规定确认覆盖的指定序号同值也写;`0.5.156` 把原生游客位不足统一映射为包含名单人数和 ERP 实际上限的业务提示,原技术 blocker 仅留技术详情。`0.5.157` 新增散拼母团“整团游客信息”的 `shared_plan + visitor-list + tid-only` 窄分支,静态契约与回归已通过,仍待授权后的新版运行态只读复测。`0.5.158` 把正式控制面 `https://lwlt.nianxx.cn` 同步加入 Popup、后台、Manifest 权限和 content script 精确白名单;其他 HTTPS origin 仍保持阻断。`0.5.159` 修复 MV3 后台恢复被中断后持久化 `running` 永久阻断插件派发的问题:仅在内存恢复 Promise 已不存在时收敛为 `interrupted`,真实活动恢复仍保持阻断,下一次成功只读保活把状态归零为 `idle`。`0.5.160` 为独立团单个下单写前漂移增加仅字段名诊断,并把数字后缀动态应收字段纳入保护。`0.5.161` 等待客户、跟单人和销售人原生 lookup 数据就绪后才开始单团预检;生产反馈证明仅检查 lookup 数据仍不足。`0.5.162` 进一步要求页面 jQuery Ajax 在预检前归零,并在 `GetProduct` 后等待原生 `ajaxStop` 再应用最终业务字段。`0.5.163` 按生产操作方明确要求恢复 `0.5.156` 的实际校验范围:核心订单字段继续写前阻断,带编号的动态 `ys_*` 应收行不再纳入保护哈希,允许 ERP 原生回调在预检后调整这些字段。`0.5.164` 新增平台账号、AgentBus 渠道、唯一云电脑 worker 与 ERP 登录身份四方一致门禁;旧未绑定渠道和历史未归属 AgentBus 任务默认不执行。`0.5.165` 让散拼新增计划和独立团批量下单在本地候选未命中时先使用表单原生非空产品检索,实测两类表单均能由完整关键词唯一返回目标产品;本轮未勾选或保存,自动选择与写入仍由原门禁保护。新增独立团房型/人数映射仍待实写;未验证宽能力继续失败关闭。
|
||||
|
||||
- `0.5.166` 在散拼母团列表入口加入立即检查、100ms 条件轮询和 15 秒总超时;每次探测都重新取得当前主 iframe document,按钮一旦可用便立即继续。该等待只发生在点击前,不固定拖慢快速页面,也不触发业务写入重试。
|
||||
- `0.5.167` 保留插件侧的空闲证明和受控重载安全协议,并继续包含 `0.5.166` 的散拼入口自适应等待。中央服务私有 OSS/ECS 云助手编排及迁移 019 已按用户决定从主线撤回,因此这些插件更新消息在当前主线没有服务端触发方,属于休眠能力;插件仍按现有人工发布/加载流程使用。
|
||||
|
||||
运行中的浏览器版本必须实时握手确认。当前制品文件名和 SHA-256 只看 [`../../../dist/release-manifest.json`](../../../dist/release-manifest.json),不从历史日志推断。
|
||||
|
||||
## 已证明的核心能力
|
||||
|
||||
8
archive/releases/2026-09-03/README.md
Normal file
8
archive/releases/2026-09-03/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# 2026-09-03 发布归档
|
||||
|
||||
本目录只保存被新版本替代的历史发布物,不定义当前运行规则。当前制品文件名和 SHA-256 只以根目录 [`../../../dist/release-manifest.json`](../../../dist/release-manifest.json) 为准。
|
||||
|
||||
- `release-manifest-0.5.165.json`:加入散拼母团列表入口自适应就绪等待前的历史清单快照。
|
||||
- `ltjt-order-assistant-0.5.165.zip`:被 `0.5.166` 的散拼母团“新增计划”按钮自适应条件等待替代;保留用于恢复和追溯。
|
||||
- `release-manifest-0.5.166.json`:加入服务端 OSS 发布、ECS 云助手部署和浏览器空闲重载协议前的历史清单快照。
|
||||
- `ltjt-order-assistant-0.5.166.zip`:被 `0.5.167` 的中央服务编排更新能力替代;仍保留自适应就绪等待修复,可用于恢复和追溯。
|
||||
BIN
archive/releases/2026-09-03/ltjt-order-assistant-0.5.166.zip
Normal file
BIN
archive/releases/2026-09-03/ltjt-order-assistant-0.5.166.zip
Normal file
Binary file not shown.
69
archive/releases/2026-09-03/release-manifest-0.5.165.json
Normal file
69
archive/releases/2026-09-03/release-manifest-0.5.165.json
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"generated_on": "2026-09-02",
|
||||
"baselines": {
|
||||
"chrome_extension": "0.5.165",
|
||||
"skills": "0.5.125",
|
||||
"business_instruction_docx": "0.5.125",
|
||||
"agent_prompt": "ltjt-agent-prompt-v1.8-independent-headcount-categories"
|
||||
},
|
||||
"artifacts": [
|
||||
{
|
||||
"kind": "chrome_extension",
|
||||
"version": "0.5.165",
|
||||
"path": "dist/ltjt-order-assistant-0.5.165.zip",
|
||||
"source": "chrome-extension/ltjt-order-assistant",
|
||||
"sha256": "14f3150ab26d99131e32321ddc805a85550438bc2810a1e20921f7922b25aaac"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
"name": "lwlt-arrangement",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/lwlt-arrangement-0.5.125.skill",
|
||||
"source": "agent设计规范/skills/lwlt-arrangement",
|
||||
"sha256": "c729bebec84695b8642a6d31cb4dc0d963135b6c6620c2173be095826cd3976d"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
"name": "lwlt-confirmation",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/lwlt-confirmation-0.5.125.skill",
|
||||
"source": "agent设计规范/skills/lwlt-confirmation",
|
||||
"sha256": "659f6aca7918a03a29fc78f0b4b938dfa9084ccdbb44ebd71f6399556cfa4609"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
"name": "lwlt-lifecycle",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/lwlt-lifecycle-0.5.125.skill",
|
||||
"source": "agent设计规范/skills/lwlt-lifecycle",
|
||||
"sha256": "d964c0a9e482f82757fea25d4713f0c81feb2704486583dfa84f2336ecd930c0"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
"name": "lwlt-newbooking",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/lwlt-newbooking-0.5.125.skill",
|
||||
"source": "agent设计规范/skills/lwlt-newbooking",
|
||||
"sha256": "bb610c50dd659fc172aabfa469b3028de98704c249cfd4890463deea0c88cd0c"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
"name": "lwlt-updating",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/lwlt-updating-0.5.125.skill",
|
||||
"source": "agent设计规范/skills/lwlt-updating",
|
||||
"sha256": "c6f5bc9008e2f63d170f3f140140003d99411ce5232632c48b38891da1ceee33"
|
||||
},
|
||||
{
|
||||
"kind": "business_instruction_docx",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/老挝联泰AI指令表-0.5.125.docx",
|
||||
"source": "agent设计规范/templates/business-input-templates.md",
|
||||
"builder": "tools/build_business_instruction_docx.py",
|
||||
"sha256": "a0c2fd5f808e3d3f2ac211a652a59f2e435d3824df49c51f763ca4beb7d9b97d",
|
||||
"source_sha256": "27600fe9bcb0de3898a99550428a9890dd350c701ba704fb3940ca966088dcd9",
|
||||
"builder_sha256": "c162884210da22e3b78368749b66f1f177df5e9fc6155f4fd9954bd516d187f1"
|
||||
}
|
||||
]
|
||||
}
|
||||
69
archive/releases/2026-09-03/release-manifest-0.5.166.json
Normal file
69
archive/releases/2026-09-03/release-manifest-0.5.166.json
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"generated_on": "2026-09-02",
|
||||
"baselines": {
|
||||
"chrome_extension": "0.5.166",
|
||||
"skills": "0.5.125",
|
||||
"business_instruction_docx": "0.5.125",
|
||||
"agent_prompt": "ltjt-agent-prompt-v1.8-independent-headcount-categories"
|
||||
},
|
||||
"artifacts": [
|
||||
{
|
||||
"kind": "chrome_extension",
|
||||
"version": "0.5.166",
|
||||
"path": "dist/ltjt-order-assistant-0.5.166.zip",
|
||||
"source": "chrome-extension/ltjt-order-assistant",
|
||||
"sha256": "68aeda857f0bf596eed3c5012fb37c6292977935ff215ce1d133983a8dffe259"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
"name": "lwlt-arrangement",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/lwlt-arrangement-0.5.125.skill",
|
||||
"source": "agent设计规范/skills/lwlt-arrangement",
|
||||
"sha256": "c729bebec84695b8642a6d31cb4dc0d963135b6c6620c2173be095826cd3976d"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
"name": "lwlt-confirmation",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/lwlt-confirmation-0.5.125.skill",
|
||||
"source": "agent设计规范/skills/lwlt-confirmation",
|
||||
"sha256": "659f6aca7918a03a29fc78f0b4b938dfa9084ccdbb44ebd71f6399556cfa4609"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
"name": "lwlt-lifecycle",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/lwlt-lifecycle-0.5.125.skill",
|
||||
"source": "agent设计规范/skills/lwlt-lifecycle",
|
||||
"sha256": "d964c0a9e482f82757fea25d4713f0c81feb2704486583dfa84f2336ecd930c0"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
"name": "lwlt-newbooking",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/lwlt-newbooking-0.5.125.skill",
|
||||
"source": "agent设计规范/skills/lwlt-newbooking",
|
||||
"sha256": "bb610c50dd659fc172aabfa469b3028de98704c249cfd4890463deea0c88cd0c"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
"name": "lwlt-updating",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/lwlt-updating-0.5.125.skill",
|
||||
"source": "agent设计规范/skills/lwlt-updating",
|
||||
"sha256": "c6f5bc9008e2f63d170f3f140140003d99411ce5232632c48b38891da1ceee33"
|
||||
},
|
||||
{
|
||||
"kind": "business_instruction_docx",
|
||||
"version": "0.5.125",
|
||||
"path": "dist/老挝联泰AI指令表-0.5.125.docx",
|
||||
"source": "agent设计规范/templates/business-input-templates.md",
|
||||
"builder": "tools/build_business_instruction_docx.py",
|
||||
"sha256": "a0c2fd5f808e3d3f2ac211a652a59f2e435d3824df49c51f763ca4beb7d9b97d",
|
||||
"source_sha256": "27600fe9bcb0de3898a99550428a9890dd350c701ba704fb3940ca966088dcd9",
|
||||
"builder_sha256": "c162884210da22e3b78368749b66f1f177df5e9fc6155f4fd9954bd516d187f1"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -11,9 +11,17 @@ Chrome Manifest V3 扩展,在用户已登录的 LTJT ERP 页面内执行经过
|
||||
|
||||
## 当前版本
|
||||
|
||||
当前源码版本为 `0.5.165`。版本化 ZIP、文件哈希和 Skill/DOCX 基线见 [`../../dist/release-manifest.json`](../../dist/release-manifest.json)。旧版本实现流水已冻结在 [`../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md`](../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md)。
|
||||
当前源码版本为 `0.5.167`。版本化 ZIP、文件哈希和 Skill/DOCX 基线见 [`../../dist/release-manifest.json`](../../dist/release-manifest.json)。旧版本实现流水已冻结在 [`../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md`](../../archive/project-history/2026-08-16/chrome-extension-README.pre-governance.md)。
|
||||
|
||||
0.5.165 当前重点:
|
||||
0.5.167 当前重点:
|
||||
|
||||
- 插件 PING 会返回当前运行任务、持久化写入边界和待回查结果汇总后的 `extension_update.safe`。只有内存与持久化状态都完全空闲,服务端才允许同一 ECS 实例进入文件部署。
|
||||
- 中央服务完成共享目录替换后,平台通过受控消息请求后台 `chrome.runtime.reload()`,并刷新平台页以重新注入 content script;执行中、已跨写边界或待回查状态会拒绝重载。
|
||||
- 这是自动更新协议的引导版本。每个 Windows Server/Chrome profile 仍需最后一次人工把插件加载到统一的 `C:\ProgramData\LTJT\chrome-extension\ltjt-order-assistant`;后续版本才由现有服务配合阿里云 ECS 云助手更新,不新增 LTJT 常驻更新器。
|
||||
|
||||
继续保留 0.5.166 的自适应等待:
|
||||
|
||||
- 散拼新增计划进入计划表后立即检查“新增计划”按钮;若同路径 iframe 尚在渲染,则每 100ms 重新取得当前 document 并检查按钮是否已连接且可用,出现后立即继续,最长 15 秒后才在写前阻断。快速页面没有固定等待,也不会自动重试任何 ERP 写入。
|
||||
|
||||
- 散拼新增计划和独立团批量下单在已加载候选无法唯一匹配时,会真正触发 `S_chanpinming` 的原生非空检索并等待 Ajax 返回,再对产品名/时长做本地唯一匹配。完整产品名原样查询;只有尾部 `10D`、`8天` 等数字时长会先剥离。最后仍保留一次空条件兼容重载,零候选或多候选继续在写前阻断。
|
||||
|
||||
|
||||
@@ -917,6 +917,64 @@ async function hasActiveErpExecution() {
|
||||
));
|
||||
}
|
||||
|
||||
async function extensionUpdateSafetyStatus() {
|
||||
if (runningTasks.size > 0) {
|
||||
return {
|
||||
ok: true,
|
||||
safe: false,
|
||||
reason: 'running_task',
|
||||
active_task_count: runningTasks.size
|
||||
};
|
||||
}
|
||||
const saved = await chrome.storage.local.get(['businessTaskExecutions', 'businessTaskResults']);
|
||||
const executions = Object.values(saved.businessTaskExecutions || {});
|
||||
if (executions.some((execution) => ['running', 'write_started', 'submitted', 'uncertain'].includes(String(execution?.state || '')))) {
|
||||
return { ok: true, safe: false, reason: 'persisted_execution_active', active_task_count: 0 };
|
||||
}
|
||||
const results = Object.values(saved.businessTaskResults || {});
|
||||
if (results.some((result) => /^(?:saved_unverified|execution_uncertain|reconciliation_pending)$/.test(String(result?.status || '')))) {
|
||||
return { ok: true, safe: false, reason: 'reconciliation_pending', active_task_count: 0 };
|
||||
}
|
||||
return { ok: true, safe: true, reason: 'idle', active_task_count: 0 };
|
||||
}
|
||||
|
||||
async function applyPreparedExtensionUpdate(targetVersion) {
|
||||
const safety = await extensionUpdateSafetyStatus();
|
||||
if (!safety.safe) {
|
||||
return {
|
||||
ok: false,
|
||||
accepted: false,
|
||||
status: 'update_reload_blocked',
|
||||
message: '插件仍有执行中或待回查任务,暂不重载。',
|
||||
update_safety: safety
|
||||
};
|
||||
}
|
||||
const currentVersion = String(chrome.runtime.getManifest().version || '');
|
||||
if (!/^\d+\.\d+\.\d+(?:\.\d+)?$/.test(String(targetVersion || ''))) {
|
||||
return { ok: false, accepted: false, status: 'update_version_invalid', message: '目标插件版本无效。' };
|
||||
}
|
||||
const currentParts = currentVersion.split('.').map(Number);
|
||||
const targetParts = String(targetVersion).split('.').map(Number);
|
||||
let comparison = 0;
|
||||
for (let index = 0; index < Math.max(currentParts.length, targetParts.length); index += 1) {
|
||||
const difference = (currentParts[index] || 0) - (targetParts[index] || 0);
|
||||
if (!difference) continue;
|
||||
comparison = difference > 0 ? 1 : -1;
|
||||
break;
|
||||
}
|
||||
if (comparison >= 0) {
|
||||
return { ok: true, accepted: false, status: 'already_current', version: currentVersion };
|
||||
}
|
||||
setTimeout(() => chrome.runtime.reload(), 250);
|
||||
return {
|
||||
ok: true,
|
||||
accepted: true,
|
||||
status: 'update_reload_scheduled',
|
||||
current_version: currentVersion,
|
||||
target_version: String(targetVersion)
|
||||
};
|
||||
}
|
||||
|
||||
async function findExistingErpTabForKeepalive({ allowLoading = false } = {}) {
|
||||
await requireErpHostPermission();
|
||||
const tabs = await chrome.tabs.query({ url: `${ERP_ORIGIN}/*` });
|
||||
@@ -3757,6 +3815,28 @@ chrome.runtime.onConnect.addListener((port) => {
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message?.type === 'LTJT_EXTENSION_UPDATE_STATUS') {
|
||||
extensionUpdateSafetyStatus()
|
||||
.then((result) => sendResponse(result))
|
||||
.catch((error) => sendResponse({
|
||||
ok: false,
|
||||
safe: false,
|
||||
reason: 'status_failed',
|
||||
message: error.message || String(error)
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
if (message?.type === 'LTJT_APPLY_EXTENSION_UPDATE') {
|
||||
applyPreparedExtensionUpdate(message.target_version || '')
|
||||
.then((result) => sendResponse(result))
|
||||
.catch((error) => sendResponse({
|
||||
ok: false,
|
||||
accepted: false,
|
||||
status: 'update_reload_failed',
|
||||
message: error.message || String(error)
|
||||
}));
|
||||
return true;
|
||||
}
|
||||
if (message?.type === 'LTJT_ERP_SESSION_STATUS') {
|
||||
readErpSessionStatus(message.expected_erp_account || '')
|
||||
.then((result) => sendResponse(result))
|
||||
|
||||
@@ -60,12 +60,21 @@ async function bridgePayload(extra = {}, expectedErpAccount = '') {
|
||||
} catch (error) {
|
||||
erpSession = { ...erpSession, message: error.message || String(error) };
|
||||
}
|
||||
let extensionUpdate = { ok: false, safe: false, reason: 'status_unavailable' };
|
||||
try {
|
||||
extensionUpdate = await chrome.runtime.sendMessage({
|
||||
type: 'LTJT_EXTENSION_UPDATE_STATUS'
|
||||
}) || extensionUpdate;
|
||||
} catch (error) {
|
||||
extensionUpdate = { ...extensionUpdate, message: error.message || String(error) };
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
extension: 'ltjt-order-assistant',
|
||||
version: chrome.runtime.getManifest().version,
|
||||
bridge_installed_at: window.__LTJT_ORDER_ASSISTANT_BRIDGE_INSTALLED_AT__ || '',
|
||||
erp_session: erpSession,
|
||||
extension_update: extensionUpdate,
|
||||
...(await getAutomationState()),
|
||||
...extra
|
||||
};
|
||||
@@ -273,6 +282,19 @@ const bridgeHandler = async (event) => {
|
||||
postReply(requestId, 'PONG', await bridgePayload({}, message.payload?.expected_erp_account));
|
||||
return;
|
||||
}
|
||||
if (message.type === 'APPLY_EXTENSION_UPDATE') {
|
||||
const result = await chrome.runtime.sendMessage({
|
||||
type: 'LTJT_APPLY_EXTENSION_UPDATE',
|
||||
target_version: String(message.payload?.target_version || '')
|
||||
});
|
||||
postReply(requestId, 'EXTENSION_UPDATE_APPLYING', result || {
|
||||
ok: false,
|
||||
accepted: false,
|
||||
status: 'update_reload_failed',
|
||||
message: '插件后台未返回重载结果。'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (message.type === 'CREATE_TASK') {
|
||||
const task = await createTask(message.payload || {});
|
||||
postReply(requestId, 'TASK_CREATED', {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
'use strict';
|
||||
|
||||
const SPLIT_PARENT_RESPONSE_REQUERY_DELAYS_MS = Object.freeze([0, 750, 2000]);
|
||||
const SPLIT_PARENT_ENTRY_READY_TIMEOUT_MS = 15000;
|
||||
const SPLIT_PARENT_ENTRY_READY_INTERVAL_MS = 100;
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
@@ -1351,6 +1353,24 @@
|
||||
return current;
|
||||
}
|
||||
|
||||
async function waitForSplitParentAddButton(initialListDocument) {
|
||||
return waitForCondition(() => {
|
||||
// The ERP can expose the destination path before replacing or finishing
|
||||
// the iframe document. Reacquire it on every probe so a stale same-path
|
||||
// document cannot make the first execution fail while the button renders.
|
||||
const candidate = mainIframe() ? mainIframeDocument() : initialListDocument;
|
||||
if (!candidate) return null;
|
||||
try {
|
||||
if (!/\/system\/business\/plan\.asp$/i.test(candidate.location.pathname)) return null;
|
||||
const addButton = candidate.querySelector('#NewBuildB, [name="NewBuildB"]');
|
||||
if (!addButton || addButton.isConnected === false || addButton.disabled === true) return null;
|
||||
return { document: candidate, addButton };
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}, SPLIT_PARENT_ENTRY_READY_TIMEOUT_MS, SPLIT_PARENT_ENTRY_READY_INTERVAL_MS);
|
||||
}
|
||||
|
||||
function nativeListRequestMatches(settings = {}, scopeDocument) {
|
||||
let requestUrl;
|
||||
try {
|
||||
@@ -3879,9 +3899,16 @@
|
||||
S_chufariqi: dateStart,
|
||||
S_chufarizhi: dateEnd
|
||||
});
|
||||
const addButton = listDocument.querySelector('#NewBuildB, [name="NewBuildB"]');
|
||||
if (!addButton) return { status: 'split_parent_live_blocked', blockers: ['split parent add button not found'], no_erp_write: true };
|
||||
addButton.click();
|
||||
const listReady = await waitForSplitParentAddButton(listDocument);
|
||||
if (!listReady) {
|
||||
return {
|
||||
status: 'split_parent_live_blocked',
|
||||
blockers: ['split parent add button not found after readiness timeout'],
|
||||
no_erp_write: true
|
||||
};
|
||||
}
|
||||
listDocument = listReady.document;
|
||||
listReady.addButton.click();
|
||||
const formDocument = await waitForDocumentPath(/\/system\/business\/plan_add\.asp$/i, 30000);
|
||||
if (!formDocument) return { status: 'split_parent_live_blocked', blockers: ['split parent form did not load'], no_erp_write: true };
|
||||
const ready = await waitForCondition(() => {
|
||||
@@ -6091,7 +6118,7 @@
|
||||
}
|
||||
|
||||
window.LTJTOrderAssistant = {
|
||||
version: '0.5.165',
|
||||
version: '0.5.167',
|
||||
resolveNativeListSearchValues,
|
||||
lookupKeywordMatchesText,
|
||||
inspectLifecycleSearchCriteria: lifecycleSearchCriteria,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "联泰下单助手",
|
||||
"version": "0.5.165",
|
||||
"version": "0.5.167",
|
||||
"description": "在已登录 LTJT ERP 页面内规划并受控执行联泰 ERP 业务操作。",
|
||||
"permissions": [
|
||||
"activeTab",
|
||||
|
||||
@@ -944,7 +944,7 @@
|
||||
|
||||
window.LTJTOrderAssistant = {
|
||||
...(window.LTJTOrderAssistant || {}),
|
||||
version: '0.5.165',
|
||||
version: '0.5.167',
|
||||
openTeamBatchForm,
|
||||
pingTeamBatchFrame,
|
||||
preflightTeamBatchNative,
|
||||
|
||||
BIN
dist/ltjt-order-assistant-0.5.167.zip
vendored
Normal file
BIN
dist/ltjt-order-assistant-0.5.167.zip
vendored
Normal file
Binary file not shown.
10
dist/release-manifest.json
vendored
10
dist/release-manifest.json
vendored
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"manifest_version": 1,
|
||||
"generated_on": "2026-09-02",
|
||||
"generated_on": "2026-09-03",
|
||||
"baselines": {
|
||||
"chrome_extension": "0.5.165",
|
||||
"chrome_extension": "0.5.167",
|
||||
"skills": "0.5.125",
|
||||
"business_instruction_docx": "0.5.125",
|
||||
"agent_prompt": "ltjt-agent-prompt-v1.8-independent-headcount-categories"
|
||||
@@ -10,10 +10,10 @@
|
||||
"artifacts": [
|
||||
{
|
||||
"kind": "chrome_extension",
|
||||
"version": "0.5.165",
|
||||
"path": "dist/ltjt-order-assistant-0.5.165.zip",
|
||||
"version": "0.5.167",
|
||||
"path": "dist/ltjt-order-assistant-0.5.167.zip",
|
||||
"source": "chrome-extension/ltjt-order-assistant",
|
||||
"sha256": "14f3150ab26d99131e32321ddc805a85550438bc2810a1e20921f7922b25aaac"
|
||||
"sha256": "6822ec660097a8889da8ea4fa22d4091467aa022067bff3bee2ac5406864b679"
|
||||
},
|
||||
{
|
||||
"kind": "skill",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"contract_version": "ltjt-lifecycle-v2.9-roster-leader-contact-2026-08",
|
||||
"current_agent_parse_prompt_version": "ltjt-agent-prompt-v1.8-independent-headcount-categories",
|
||||
"current_extension_version": "0.5.165",
|
||||
"current_extension_version": "0.5.167",
|
||||
"historical_test_marker": "TEST-202609",
|
||||
"scope": "/System/Business/",
|
||||
"erp_session_keepalive": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://local.lwltapi/schemas/ltjt_form_mapping.schema.json",
|
||||
"mapping_version": "2026-09-02.shared_plan_create.plan_add.v0.9",
|
||||
"status": "native_nonempty_product_search_live_verified_release_gated_0.5.165",
|
||||
"mapping_version": "2026-09-03.shared_plan_create.plan_add.v0.10",
|
||||
"status": "adaptive_list_entry_readiness_release_gated_0.5.167",
|
||||
"source": {
|
||||
"schema": "schemas/standard_system_operation.schema.json",
|
||||
"action": "shared_plan_create"
|
||||
@@ -16,6 +16,14 @@
|
||||
"payload_prefix": "Act=DoInfoSPs&",
|
||||
"response_type": "script"
|
||||
},
|
||||
"entry_readiness": {
|
||||
"page": "/System/Business/plan.asp",
|
||||
"target": "#NewBuildB, [name=\"NewBuildB\"]",
|
||||
"policy": "check immediately; while absent reacquire the current main-iframe document and poll every 100ms; click as soon as the button is connected and enabled",
|
||||
"timeout_ms": 15000,
|
||||
"fixed_delay": false,
|
||||
"failure_policy": "block before click and before ERP write"
|
||||
},
|
||||
"ordered_steps": [
|
||||
{ "step": 1, "operation": "set_date_range", "source": "data.recurrence.start_date/end_date", "targets": ["Riqi1", "Riqi2"] },
|
||||
{ "step": 2, "operation": "resolve_and_select_product", "source": "data.product.keyword || data.product.name", "search_target": "S_chanpinming", "radio_target": "cp_id", "side_effect": "set_th fills tuanxuhao1/tuanxuhao2", "unique_required": true, "fallback": "match loaded candidates first; if unresolved, issue the native non-empty product-name query and match the returned name/duration fields locally; strip only a trailing numeric duration before the native query; retain one empty-query compatibility reload; never choose the first row" },
|
||||
|
||||
@@ -307,6 +307,28 @@ test('team-order live gate allows numbered receivable drift like 0.5.156', async
|
||||
clearTimeout(jq.ajax.__ltjt_restore_timer);
|
||||
});
|
||||
|
||||
test('split-parent entry waits adaptively for the current iframe add button before clicking', async () => {
|
||||
const inpage = await readFile(new URL('../chrome-extension/ltjt-order-assistant/inpage.js', import.meta.url), 'utf8');
|
||||
const readinessBody = inpage.slice(
|
||||
inpage.indexOf('async function waitForSplitParentAddButton'),
|
||||
inpage.indexOf('function nativeListRequestMatches')
|
||||
);
|
||||
const createBody = inpage.slice(
|
||||
inpage.indexOf('async function createSplitParentLive'),
|
||||
inpage.indexOf('async function createSplitChildLive')
|
||||
);
|
||||
assert.match(inpage, /SPLIT_PARENT_ENTRY_READY_TIMEOUT_MS = 15000/);
|
||||
assert.match(inpage, /SPLIT_PARENT_ENTRY_READY_INTERVAL_MS = 100/);
|
||||
assert.match(readinessBody, /return waitForCondition/);
|
||||
assert.match(readinessBody, /const candidate = mainIframe\(\) \? mainIframeDocument\(\) : initialListDocument/);
|
||||
assert.match(readinessBody, /addButton\.isConnected === false/);
|
||||
assert.match(readinessBody, /addButton\.disabled === true/);
|
||||
assert.match(createBody, /const listReady = await waitForSplitParentAddButton\(listDocument\)/);
|
||||
assert.match(createBody, /listDocument = listReady\.document/);
|
||||
assert.match(createBody, /listReady\.addButton\.click\(\)/);
|
||||
assert.doesNotMatch(createBody, /const addButton = listDocument\.querySelector/);
|
||||
});
|
||||
|
||||
test('split-parent post-write verification retries read-only and falls back after any missed response group', async () => {
|
||||
const inpage = await readFile(new URL('../chrome-extension/ltjt-order-assistant/inpage.js', import.meta.url), 'utf8');
|
||||
const createBody = inpage.slice(
|
||||
@@ -1296,7 +1318,7 @@ test('passenger explicit server success is terminal without a post-save row requ
|
||||
assert.doesNotMatch(passengerBranch, /passengerRequery|verifyLifecycleOperation/);
|
||||
assert.doesNotMatch(background, /attemptAutomaticPassengerReconciliation/);
|
||||
assert.match(background, /名单已取得 ERP 明确成功响应,按业务规则确认录入成功/);
|
||||
assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.165'/);
|
||||
assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.167'/);
|
||||
});
|
||||
|
||||
test('uncertain lifecycle writes can only converge through a read-only plugin requery', async () => {
|
||||
@@ -1503,6 +1525,22 @@ test('lifecycle execution keeps the MV3 worker alive until the durable task sett
|
||||
assert.match(background, /arrangement_resource_candidate_data_missing/);
|
||||
});
|
||||
|
||||
test('extension 0.5.167 keeps reload dormant unless its durable execution state is fully idle', async () => {
|
||||
const [background, bridge] = await Promise.all([
|
||||
readFile(new URL('../chrome-extension/ltjt-order-assistant/background.js', import.meta.url), 'utf8'),
|
||||
readFile(new URL('../chrome-extension/ltjt-order-assistant/business-bridge.js', import.meta.url), 'utf8')
|
||||
]);
|
||||
assert.match(background, /async function extensionUpdateSafetyStatus\(\)/);
|
||||
assert.match(background, /\['running', 'write_started', 'submitted', 'uncertain'\]/);
|
||||
assert.match(background, /saved_unverified\|execution_uncertain\|reconciliation_pending/);
|
||||
assert.match(background, /message\?\.type === 'LTJT_EXTENSION_UPDATE_STATUS'/);
|
||||
assert.match(background, /message\?\.type === 'LTJT_APPLY_EXTENSION_UPDATE'/);
|
||||
assert.match(background, /if \(comparison >= 0\)/);
|
||||
assert.match(background, /chrome\.runtime\.reload\(\)/);
|
||||
assert.match(bridge, /message\.type === 'APPLY_EXTENSION_UPDATE'/);
|
||||
assert.match(bridge, /type: 'LTJT_APPLY_EXTENSION_UPDATE'/);
|
||||
});
|
||||
|
||||
test('ERP browser injection is host-permission gated and fail-closed with diagnostics', async () => {
|
||||
const [manifestText, background, platform] = await Promise.all([
|
||||
readFile(new URL('../chrome-extension/ltjt-order-assistant/manifest.json', import.meta.url), 'utf8'),
|
||||
@@ -1926,7 +1964,7 @@ test('delete guard distinguishes independent, shared child, and shared parent ro
|
||||
for (const operation of operations) assert.equal(plans.validateOperation(operation).ok, true, plans.validateOperation(operation).blockers.join('; '));
|
||||
|
||||
const mapping = JSON.parse(await readFile(new URL('../mappings/lifecycle.mapping.json', import.meta.url), 'utf8'));
|
||||
assert.equal(mapping.current_extension_version, '0.5.165');
|
||||
assert.equal(mapping.current_extension_version, '0.5.167');
|
||||
assert.equal(
|
||||
mapping.updates.order_update_independent.field_mapped_pending_live_validation['pax.child_no_bed'],
|
||||
'ertrenshu'
|
||||
@@ -2309,10 +2347,10 @@ test('schema and browser adapters contain the v2 safety fields and no confirm ov
|
||||
assert.match(inpage, /`ys_danweiid\$\{index\}`, resolvedCustomerId/);
|
||||
assert.doesNotMatch(inpage, /product_customer_source_region|sourceRegionCheck|source_reference/);
|
||||
assert.doesNotMatch(teamBatchInpage, /product_customer_source_region|sourceRegionCheck/);
|
||||
assert.equal(extensionManifest.version, '0.5.165');
|
||||
assert.match(inpage, /version: '0\.5\.165'/);
|
||||
assert.match(teamBatchInpage, /version: '0\.5\.165'/);
|
||||
assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.165'/);
|
||||
assert.equal(extensionManifest.version, '0.5.167');
|
||||
assert.match(inpage, /version: '0\.5\.167'/);
|
||||
assert.match(teamBatchInpage, /version: '0\.5\.167'/);
|
||||
assert.match(platformApp, /REQUIRED_EXTENSION_VERSION = '0\.5\.167'/);
|
||||
assert.match(inpage, /function strictIsoDate\(value\)/);
|
||||
assert.match(inpage, /const startDate = strictIsoDate\(controlCanonicalValue\(form, 'riqi0'\)\)/);
|
||||
assert.match(inpage, /const endDate = strictIsoDate\(controlCanonicalValue\(form, 'riqis0'\)\)/);
|
||||
|
||||
Reference in New Issue
Block a user