@4pm/cli 1.30.0 → 1.31.0
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.
- package/dist/index.js +368 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28569,6 +28569,344 @@ async function fetchCliVersion(serverUrl, version) {
|
|
|
28569
28569
|
}
|
|
28570
28570
|
}
|
|
28571
28571
|
|
|
28572
|
+
// vendor/@4pm/constants/error-codes.ts
|
|
28573
|
+
var ErrorCode = {
|
|
28574
|
+
// Common
|
|
28575
|
+
VALIDATION_FAILED: "VALIDATION_FAILED",
|
|
28576
|
+
UNAUTHORIZED: "UNAUTHORIZED",
|
|
28577
|
+
FORBIDDEN: "FORBIDDEN",
|
|
28578
|
+
IP_NOT_ALLOWED: "IP_NOT_ALLOWED",
|
|
28579
|
+
// A user's IP allowlist entry falls outside the org allowlist (ADR-0044).
|
|
28580
|
+
IP_OUTSIDE_ORG_ALLOWLIST: "IP_OUTSIDE_ORG_ALLOWLIST",
|
|
28581
|
+
// An allowlist entry falls outside its parent tier: a team/project outside the
|
|
28582
|
+
// org, or a user outside the union of their teams'/projects' allowlists (ADR-0050).
|
|
28583
|
+
IP_OUTSIDE_PARENT_ALLOWLIST: "IP_OUTSIDE_PARENT_ALLOWLIST",
|
|
28584
|
+
NOT_FOUND: "NOT_FOUND",
|
|
28585
|
+
CONFLICT: "CONFLICT",
|
|
28586
|
+
RATE_LIMITED: "RATE_LIMITED",
|
|
28587
|
+
FEATURE_NOT_AVAILABLE: "FEATURE_NOT_AVAILABLE",
|
|
28588
|
+
// Request body exceeded the HTTP gateway's JSON size limit (see HTTP_JSON_BODY_LIMIT_BYTES).
|
|
28589
|
+
PAYLOAD_TOO_LARGE: "PAYLOAD_TOO_LARGE",
|
|
28590
|
+
INTERNAL_ERROR: "INTERNAL_ERROR",
|
|
28591
|
+
// auth
|
|
28592
|
+
INVALID_CREDENTIALS: "INVALID_CREDENTIALS",
|
|
28593
|
+
EMAIL_NOT_VERIFIED: "EMAIL_NOT_VERIFIED",
|
|
28594
|
+
ACCOUNT_LOCKED: "ACCOUNT_LOCKED",
|
|
28595
|
+
TOKEN_INVALID: "TOKEN_INVALID",
|
|
28596
|
+
TOKEN_EXPIRED: "TOKEN_EXPIRED",
|
|
28597
|
+
TOKEN_USED: "TOKEN_USED",
|
|
28598
|
+
TOKEN_REVOKED: "TOKEN_REVOKED",
|
|
28599
|
+
/** The session is idle-locked (ADR-0204) — re-authenticate to continue (HTTP 423). */
|
|
28600
|
+
SESSION_LOCKED: "SESSION_LOCKED",
|
|
28601
|
+
PASSWORD_POLICY_VIOLATION: "PASSWORD_POLICY_VIOLATION",
|
|
28602
|
+
PASSWORD_CONFIRM_MISMATCH: "PASSWORD_CONFIRM_MISMATCH",
|
|
28603
|
+
PASSWORD_CURRENT_INVALID: "PASSWORD_CURRENT_INVALID",
|
|
28604
|
+
IDENTITY_REQUIRED: "IDENTITY_REQUIRED",
|
|
28605
|
+
MFA_CODE_INVALID: "MFA_CODE_INVALID",
|
|
28606
|
+
MFA_CODE_EXPIRED: "MFA_CODE_EXPIRED",
|
|
28607
|
+
// org · user · team · project
|
|
28608
|
+
USER_NOT_FOUND: "USER_NOT_FOUND",
|
|
28609
|
+
TEAM_NOT_FOUND: "TEAM_NOT_FOUND",
|
|
28610
|
+
PROJECT_NOT_FOUND: "PROJECT_NOT_FOUND",
|
|
28611
|
+
ORG_NOT_FOUND: "ORG_NOT_FOUND",
|
|
28612
|
+
// org login alias (ADR-0111): alias already used by another org, or a reserved word
|
|
28613
|
+
ORG_ALIAS_TAKEN: "ORG_ALIAS_TAKEN",
|
|
28614
|
+
// org template files (ADR-0113)
|
|
28615
|
+
TEMPLATE_NOT_FOUND: "TEMPLATE_NOT_FOUND",
|
|
28616
|
+
TEMPLATE_QUOTA_EXCEEDED: "TEMPLATE_QUOTA_EXCEEDED",
|
|
28617
|
+
TEMPLATE_FILE_TOO_LARGE: "TEMPLATE_FILE_TOO_LARGE",
|
|
28618
|
+
// skill/subagent marketplace (ADR-0185)
|
|
28619
|
+
MARKET_PACKAGE_NOT_FOUND: "MARKET_PACKAGE_NOT_FOUND",
|
|
28620
|
+
MARKET_VERSION_NOT_FOUND: "MARKET_VERSION_NOT_FOUND",
|
|
28621
|
+
MARKET_PACKAGE_EXISTS: "MARKET_PACKAGE_EXISTS",
|
|
28622
|
+
MARKET_VERSION_EXISTS: "MARKET_VERSION_EXISTS",
|
|
28623
|
+
MARKET_INVALID_PACKAGE: "MARKET_INVALID_PACKAGE",
|
|
28624
|
+
MARKET_SCOPE_FORBIDDEN: "MARKET_SCOPE_FORBIDDEN",
|
|
28625
|
+
MARKET_SCOPE_UNSUPPORTED: "MARKET_SCOPE_UNSUPPORTED",
|
|
28626
|
+
MARKET_VERSION_NOT_APPROVED: "MARKET_VERSION_NOT_APPROVED",
|
|
28627
|
+
MARKET_NOT_MODERATABLE: "MARKET_NOT_MODERATABLE",
|
|
28628
|
+
MARKET_UNAVAILABLE: "MARKET_UNAVAILABLE",
|
|
28629
|
+
MARKET_REVIEW_NOT_ELIGIBLE: "MARKET_REVIEW_NOT_ELIGIBLE",
|
|
28630
|
+
MARKET_PAYMENT_REQUIRED: "MARKET_PAYMENT_REQUIRED",
|
|
28631
|
+
MARKET_ORDER_NOT_FOUND: "MARKET_ORDER_NOT_FOUND",
|
|
28632
|
+
MARKET_ALREADY_PURCHASED: "MARKET_ALREADY_PURCHASED",
|
|
28633
|
+
KNOWLEDGE_POST_NOT_FOUND: "KNOWLEDGE_POST_NOT_FOUND",
|
|
28634
|
+
KNOWLEDGE_SCOPE_FORBIDDEN: "KNOWLEDGE_SCOPE_FORBIDDEN",
|
|
28635
|
+
// 4rum post / Messenger message missing or not visible — also a cursor anchor (ADR-0341/0361)
|
|
28636
|
+
POST_NOT_FOUND: "POST_NOT_FOUND",
|
|
28637
|
+
MESSAGE_NOT_FOUND: "MESSAGE_NOT_FOUND",
|
|
28638
|
+
PACKAGE_ALREADY_INSTALLED: "PACKAGE_ALREADY_INSTALLED",
|
|
28639
|
+
// org total hosted storage cap (ADR-0122/0365) — blocks text writes, uploads, memo/book writes and new AI runs
|
|
28640
|
+
STORAGE_QUOTA_EXCEEDED: "STORAGE_QUOTA_EXCEEDED",
|
|
28641
|
+
// Self-managed storage clear (ADR-0365): typed org-name confirmation mismatch; a kind the service
|
|
28642
|
+
// cannot clear; a clear already running for the org.
|
|
28643
|
+
STORAGE_CLEAR_CONFIRM_MISMATCH: "STORAGE_CLEAR_CONFIRM_MISMATCH",
|
|
28644
|
+
STORAGE_CLEAR_KIND_INVALID: "STORAGE_CLEAR_KIND_INVALID",
|
|
28645
|
+
STORAGE_CLEAR_RUNNING: "STORAGE_CLEAR_RUNNING",
|
|
28646
|
+
// project lifecycle (ADR-0092): invalid transition / operation on a paused|closed project
|
|
28647
|
+
PROJECT_STATE_INVALID: "PROJECT_STATE_INVALID",
|
|
28648
|
+
PROJECT_NOT_ACTIVE: "PROJECT_NOT_ACTIVE",
|
|
28649
|
+
// user pause (ADR-0093): user is paused (blocks login/API/token/WS) / invalid pause transition
|
|
28650
|
+
USER_PAUSED: "USER_PAUSED",
|
|
28651
|
+
USER_STATE_INVALID: "USER_STATE_INVALID",
|
|
28652
|
+
// org pause (ADR-0094 admin-0013): whole org paused ⇒ blocks all its users' login/API/token
|
|
28653
|
+
ORG_PAUSED: "ORG_PAUSED",
|
|
28654
|
+
// project-membership pause (ADR-0093): invalid membership pause transition
|
|
28655
|
+
MEMBER_STATE_INVALID: "MEMBER_STATE_INVALID",
|
|
28656
|
+
// soft-delete restore (ADR-0109): restore a record that is not currently deleted
|
|
28657
|
+
PROJECT_NOT_DELETED: "PROJECT_NOT_DELETED",
|
|
28658
|
+
TEAM_NOT_DELETED: "TEAM_NOT_DELETED",
|
|
28659
|
+
USER_NOT_DELETED: "USER_NOT_DELETED",
|
|
28660
|
+
USERNAME_TAKEN: "USERNAME_TAKEN",
|
|
28661
|
+
EMAIL_TAKEN: "EMAIL_TAKEN",
|
|
28662
|
+
// email omitted while the org disallows sub-accounts without email (ADR-0039)
|
|
28663
|
+
EMAIL_REQUIRED: "EMAIL_REQUIRED",
|
|
28664
|
+
// contact-change (self email/phone) verification (ADR-0046)
|
|
28665
|
+
// email and phone cannot be changed in the same request
|
|
28666
|
+
CONTACT_CHANGE_BOTH: "CONTACT_CHANGE_BOTH",
|
|
28667
|
+
// a contact-change is already pending — resolve it before editing again
|
|
28668
|
+
CONTACT_CHANGE_PENDING: "CONTACT_CHANGE_PENDING",
|
|
28669
|
+
// the verifying channel is missing (e.g. no phone on file to OTP an email change)
|
|
28670
|
+
CONTACT_CHANGE_CHANNEL_MISSING: "CONTACT_CHANGE_CHANNEL_MISSING",
|
|
28671
|
+
// the submitted OTP / link token is invalid or expired
|
|
28672
|
+
CONTACT_CHANGE_INVALID: "CONTACT_CHANGE_INVALID",
|
|
28673
|
+
// self email/phone must go through the contact-change flow (not a direct update)
|
|
28674
|
+
CONTACT_CHANGE_REQUIRED: "CONTACT_CHANGE_REQUIRED",
|
|
28675
|
+
ROLE_EXCLUSIVE: "ROLE_EXCLUSIVE",
|
|
28676
|
+
ROOT_IMMUTABLE: "ROOT_IMMUTABLE",
|
|
28677
|
+
// ADMIN role is reserved for the org root; it cannot be granted to sub-accounts
|
|
28678
|
+
ADMIN_ROLE_RESERVED: "ADMIN_ROLE_RESERVED",
|
|
28679
|
+
// a PM may only assign roles below PM (never PM/ADMIN/MACHINE) — anti-escalation (ADR-0051)
|
|
28680
|
+
USER_ROLE_ASSIGN_FORBIDDEN: "USER_ROLE_ASSIGN_FORBIDDEN",
|
|
28681
|
+
// an ADMIN account manages the org only — it cannot be attached to teams/projects
|
|
28682
|
+
ADMIN_NOT_ASSIGNABLE: "ADMIN_NOT_ASSIGNABLE",
|
|
28683
|
+
// a MACHINE account is a worker — it cannot be a project manager (ADR-0041)
|
|
28684
|
+
MACHINE_NOT_MANAGER: "MACHINE_NOT_MANAGER",
|
|
28685
|
+
// a MACHINE account may be a member of at most one project (ADR-0041)
|
|
28686
|
+
MACHINE_ALREADY_IN_PROJECT: "MACHINE_ALREADY_IN_PROJECT",
|
|
28687
|
+
// a MACHINE account is a worker, not a human member — it cannot join a team (ADR-0041)
|
|
28688
|
+
MACHINE_NOT_TEAM_MEMBER: "MACHINE_NOT_TEAM_MEMBER",
|
|
28689
|
+
ALREADY_ATTACHED: "ALREADY_ATTACHED",
|
|
28690
|
+
NOT_ATTACHED: "NOT_ATTACHED",
|
|
28691
|
+
SELF_DELETE_FORBIDDEN: "SELF_DELETE_FORBIDDEN",
|
|
28692
|
+
SELF_SET_PASSWORD_FORBIDDEN: "SELF_SET_PASSWORD_FORBIDDEN",
|
|
28693
|
+
AVATAR_INVALID_TYPE: "AVATAR_INVALID_TYPE",
|
|
28694
|
+
AVATAR_TOO_LARGE: "AVATAR_TOO_LARGE",
|
|
28695
|
+
// permission
|
|
28696
|
+
PERMISSION_CODE_INVALID: "PERMISSION_CODE_INVALID",
|
|
28697
|
+
SUBJECT_INVALID: "SUBJECT_INVALID",
|
|
28698
|
+
// machine
|
|
28699
|
+
HASHCODE_INVALID: "HASHCODE_INVALID",
|
|
28700
|
+
HASHCODE_EXPIRED: "HASHCODE_EXPIRED",
|
|
28701
|
+
LINK_REVOKED: "LINK_REVOKED",
|
|
28702
|
+
LINK_NOT_FOUND: "LINK_NOT_FOUND",
|
|
28703
|
+
WORKER_OFFLINE: "WORKER_OFFLINE",
|
|
28704
|
+
// command-0001 pick:"idle" (ADR-0171) — no idle cli in the project's pool
|
|
28705
|
+
ALL_CLIS_BUSY: "ALL_CLIS_BUSY",
|
|
28706
|
+
// worker pools (ADR-0284)
|
|
28707
|
+
WORKER_POOL_NOT_FOUND: "WORKER_POOL_NOT_FOUND",
|
|
28708
|
+
WORKER_POOL_NAME_TAKEN: "WORKER_POOL_NAME_TAKEN",
|
|
28709
|
+
WORKER_POOL_ATTACHED: "WORKER_POOL_ATTACHED",
|
|
28710
|
+
WORKER_POOL_ALREADY_ATTACHED: "WORKER_POOL_ALREADY_ATTACHED",
|
|
28711
|
+
MACHINE_ALREADY_IN_POOL: "MACHINE_ALREADY_IN_POOL",
|
|
28712
|
+
NOT_MACHINE_USER: "NOT_MACHINE_USER",
|
|
28713
|
+
// worker · physic project
|
|
28714
|
+
WORKER_NOT_FOUND: "WORKER_NOT_FOUND",
|
|
28715
|
+
PHYSIC_PROJECT_NOT_FOUND: "PHYSIC_PROJECT_NOT_FOUND",
|
|
28716
|
+
PHYSIC_PATH_OCCUPIED: "PHYSIC_PATH_OCCUPIED",
|
|
28717
|
+
AUTONOMOUS_CONFLICT: "AUTONOMOUS_CONFLICT",
|
|
28718
|
+
// A disruptive worker op (repo (re)provision / CLI update) was refused because the target
|
|
28719
|
+
// worker's autonomous mode is armed (installed && !paused) — stop it first (ADR-0317).
|
|
28720
|
+
AUTONOMOUS_ACTIVE: "AUTONOMOUS_ACTIVE",
|
|
28721
|
+
// Separation of duties (ADR-0320): a non-ADMIN tried to approve a row they wrote — the writer can't
|
|
28722
|
+
// be the approver of their own row (ADMIN may self-approve).
|
|
28723
|
+
APPROVAL_SELF: "APPROVAL_SELF",
|
|
28724
|
+
CLI_VERSION_UNSUPPORTED: "CLI_VERSION_UNSUPPORTED",
|
|
28725
|
+
// Admin cli version policy rejected (ADR-0363) — meta.reason: minAboveLatest | latestNotBlockable |
|
|
28726
|
+
// deadlinePast | invalidVersion.
|
|
28727
|
+
CLI_VERSION_POLICY_INVALID: "CLI_VERSION_POLICY_INVALID",
|
|
28728
|
+
ORCHESTRATOR_OFFLINE: "ORCHESTRATOR_OFFLINE",
|
|
28729
|
+
WS_TOKEN_INVALID: "WS_TOKEN_INVALID",
|
|
28730
|
+
// A newer cli session for the same link took over ⇒ the older one stops (ADR-0047).
|
|
28731
|
+
SESSION_REPLACED: "SESSION_REPLACED",
|
|
28732
|
+
PATH_INVALID: "PATH_INVALID",
|
|
28733
|
+
// project create/add
|
|
28734
|
+
SPEC_INVALID: "SPEC_INVALID",
|
|
28735
|
+
PATH_OCCUPIED: "PATH_OCCUPIED",
|
|
28736
|
+
GIT_ENV_MISSING: "GIT_ENV_MISSING",
|
|
28737
|
+
CLAUDE_CLI_MISSING: "CLAUDE_CLI_MISSING",
|
|
28738
|
+
SCAFFOLD_FAILED: "SCAFFOLD_FAILED",
|
|
28739
|
+
GIT_OPERATION_FAILED: "GIT_OPERATION_FAILED",
|
|
28740
|
+
AI_INIT_FAILED: "AI_INIT_FAILED",
|
|
28741
|
+
// AI spec-assist (suggest/review/compose) run failed on the worker cli (ADR-0100).
|
|
28742
|
+
AI_ASSIST_FAILED: "AI_ASSIST_FAILED",
|
|
28743
|
+
// Client-side guard (ADR-0255): the built AI prompt is longer than AI_PROMPT_MAX_LEN, so the
|
|
28744
|
+
// web blocks the dispatch and shows an actionable "spec too large" message instead of letting
|
|
28745
|
+
// the server reject it as a confusing VALIDATION_FAILED.
|
|
28746
|
+
AI_PROMPT_TOO_LARGE: "AI_PROMPT_TOO_LARGE",
|
|
28747
|
+
REPO_NOT_FOUND: "REPO_NOT_FOUND",
|
|
28748
|
+
// invitation
|
|
28749
|
+
INVITATION_TOKEN_INVALID: "INVITATION_TOKEN_INVALID",
|
|
28750
|
+
INVITATION_ALREADY_ACCEPTED: "INVITATION_ALREADY_ACCEPTED",
|
|
28751
|
+
INVITATION_ROLE_FORBIDDEN: "INVITATION_ROLE_FORBIDDEN",
|
|
28752
|
+
// notification
|
|
28753
|
+
NOTIFICATION_NOT_FOUND: "NOTIFICATION_NOT_FOUND",
|
|
28754
|
+
// sso (ADR-0024)
|
|
28755
|
+
SSO_IDENTITY_NOT_LINKED: "SSO_IDENTITY_NOT_LINKED",
|
|
28756
|
+
SSO_PROVIDER_INVALID: "SSO_PROVIDER_INVALID",
|
|
28757
|
+
// Cannot unlink the last remaining login method (SSO-only user, ADR-0161)
|
|
28758
|
+
SSO_LAST_LOGIN_METHOD: "SSO_LAST_LOGIN_METHOD",
|
|
28759
|
+
PASSWORD_NOT_SET: "PASSWORD_NOT_SET",
|
|
28760
|
+
// command · memo
|
|
28761
|
+
COMMAND_NOT_FOUND: "COMMAND_NOT_FOUND",
|
|
28762
|
+
// Stop requested for a command that already settled (done/failed/cancelled — ADR-0362).
|
|
28763
|
+
COMMAND_ALREADY_FINISHED: "COMMAND_ALREADY_FINISHED",
|
|
28764
|
+
COMMAND_DISPATCH_LIMITED: "COMMAND_DISPATCH_LIMITED",
|
|
28765
|
+
QUOTA_EXCEEDED: "QUOTA_EXCEEDED",
|
|
28766
|
+
// A single prompt's estimated tokens exceed project `settings.tokens.perPromptTokenLimit` (ADR-0081).
|
|
28767
|
+
PROMPT_TOKEN_LIMIT_EXCEEDED: "PROMPT_TOKEN_LIMIT_EXCEEDED",
|
|
28768
|
+
// An outbound cli evaluated the input as NG (secret/path/repo/environment) — ADR-0082.
|
|
28769
|
+
OUTBOUND_REVIEW_REJECTED: "OUTBOUND_REVIEW_REJECTED",
|
|
28770
|
+
// No outbound cli available (offline/busy/out-of-token) while review is on — ADR-0082.
|
|
28771
|
+
OUTBOUND_REVIEW_UNAVAILABLE: "OUTBOUND_REVIEW_UNAVAILABLE",
|
|
28772
|
+
// A saved outbound rule regex fails to compile or is ReDoS-unsafe (ADR-0087).
|
|
28773
|
+
OUTBOUND_RULE_INVALID: "OUTBOUND_RULE_INVALID",
|
|
28774
|
+
// Console image attachment blocked because the project has `outboundReview.blockImages` (ADR-0257).
|
|
28775
|
+
IMAGE_UPLOAD_BLOCKED: "IMAGE_UPLOAD_BLOCKED",
|
|
28776
|
+
MEMO_TOO_LONG: "MEMO_TOO_LONG",
|
|
28777
|
+
// plan entitlements (ADR-0105) — resource caps + feature gates per plan tier
|
|
28778
|
+
PLAN_USER_LIMIT: "PLAN_USER_LIMIT",
|
|
28779
|
+
PLAN_PROJECT_LIMIT: "PLAN_PROJECT_LIMIT",
|
|
28780
|
+
// Plan memo-item cap reached (`maxMemoItems` — ADR-0365).
|
|
28781
|
+
PLAN_MEMO_LIMIT: "PLAN_MEMO_LIMIT",
|
|
28782
|
+
// An autonomous book reached its monthly `autonomousRequestsPerMonth` cap (ADR-0365).
|
|
28783
|
+
AUTONOMOUS_BOOK_CAP_REACHED: "AUTONOMOUS_BOOK_CAP_REACHED",
|
|
28784
|
+
PLAN_FEATURE_UNAVAILABLE: "PLAN_FEATURE_UNAVAILABLE",
|
|
28785
|
+
// deployment license ceiling (ADR-0135) — a self-host license bounds orgs/seats/projects/
|
|
28786
|
+
// storage across the whole deployment, above the per-org plan caps
|
|
28787
|
+
LICENSE_LIMIT_EXCEEDED: "LICENSE_LIMIT_EXCEEDED",
|
|
28788
|
+
// billing add-ons & rented machine-users (ADR-0123/0126) — payment-server · admin-server
|
|
28789
|
+
// buying an add-on without an active paid plan (ADR-0123)
|
|
28790
|
+
ADDON_REQUIRES_PLAN: "ADDON_REQUIRES_PLAN",
|
|
28791
|
+
// renting a machine-user with no free pool slot (ADR-0126) — the org may be waitlisted
|
|
28792
|
+
NO_HOSTED_SLOT_AVAILABLE: "NO_HOSTED_SLOT_AVAILABLE",
|
|
28793
|
+
// admin changing a rented hosted slot without forceRelease (ADR-0126)
|
|
28794
|
+
SLOT_RENTED: "SLOT_RENTED",
|
|
28795
|
+
// re-renting a machine whose rental is already `releasing` — too late to undo (ADR-0210)
|
|
28796
|
+
RENTED_MACHINE_RELEASING: "RENTED_MACHINE_RELEASING",
|
|
28797
|
+
// credit wallet & coupons (ADR-0118/0119/0120) — served by payment-server
|
|
28798
|
+
CREDIT_INSUFFICIENT: "CREDIT_INSUFFICIENT",
|
|
28799
|
+
COUPON_NOT_FOUND: "COUPON_NOT_FOUND",
|
|
28800
|
+
COUPON_EXPIRED: "COUPON_EXPIRED",
|
|
28801
|
+
COUPON_DISABLED: "COUPON_DISABLED",
|
|
28802
|
+
COUPON_EXHAUSTED: "COUPON_EXHAUSTED",
|
|
28803
|
+
COUPON_ALREADY_REDEEMED: "COUPON_ALREADY_REDEEMED",
|
|
28804
|
+
// payment-server catalog completion (ADR-0207) — credit/addon/plan errors that previously
|
|
28805
|
+
// threw raw strings or literals duplicated inside payment-server; now first-class codes.
|
|
28806
|
+
// credit mutation validation (credit.service)
|
|
28807
|
+
INVALID_AMOUNT: "INVALID_AMOUNT",
|
|
28808
|
+
INVALID_DELTA: "INVALID_DELTA",
|
|
28809
|
+
TOPUP_NOT_FOUND: "TOPUP_NOT_FOUND",
|
|
28810
|
+
// storage add-on SKU management (addon.service — admin-0031/0032)
|
|
28811
|
+
STORAGE_SKU_INVALID: "STORAGE_SKU_INVALID",
|
|
28812
|
+
STORAGE_SKU_NOT_FOUND: "STORAGE_SKU_NOT_FOUND",
|
|
28813
|
+
STORAGE_SIZE_INVALID: "STORAGE_SIZE_INVALID",
|
|
28814
|
+
ADDON_CODE_EXISTS: "ADDON_CODE_EXISTS",
|
|
28815
|
+
ADDON_PRICE_INVALID: "ADDON_PRICE_INVALID",
|
|
28816
|
+
ADDON_PRODUCT_UNKNOWN: "ADDON_PRODUCT_UNKNOWN",
|
|
28817
|
+
ADDON_QUANTITY_INVALID: "ADDON_QUANTITY_INVALID",
|
|
28818
|
+
ADDON_NOT_FOUND: "ADDON_NOT_FOUND",
|
|
28819
|
+
// plan / subscription lifecycle (billing.service — ADR-0163/0142)
|
|
28820
|
+
PLAN_CODE_REQUIRED: "PLAN_CODE_REQUIRED",
|
|
28821
|
+
PLAN_UNCHANGED: "PLAN_UNCHANGED",
|
|
28822
|
+
PLAN_CHANGE_INVALID: "PLAN_CHANGE_INVALID",
|
|
28823
|
+
NO_ACTIVE_SUBSCRIPTION: "NO_ACTIVE_SUBSCRIPTION",
|
|
28824
|
+
NO_PROVIDER_SUBSCRIPTION: "NO_PROVIDER_SUBSCRIPTION",
|
|
28825
|
+
ENTERPRISE_PLAN_NOT_ASSIGNABLE: "ENTERPRISE_PLAN_NOT_ASSIGNABLE",
|
|
28826
|
+
PAYMENT_FAILED: "PAYMENT_FAILED",
|
|
28827
|
+
// support tickets (ADR-0167) + AI help agent (ADR-0168)
|
|
28828
|
+
SUPPORT_TICKET_NOT_FOUND: "SUPPORT_TICKET_NOT_FOUND",
|
|
28829
|
+
// managed legal documents (ADR-0350): unknown/disabled document; accepting a version that is not current
|
|
28830
|
+
LEGAL_DOCUMENT_NOT_FOUND: "LEGAL_DOCUMENT_NOT_FOUND",
|
|
28831
|
+
LEGAL_VERSION_OUTDATED: "LEGAL_VERSION_OUTDATED",
|
|
28832
|
+
SUPPORT_TICKET_CLOSED: "SUPPORT_TICKET_CLOSED",
|
|
28833
|
+
// public (guest) support create (ADR-0279): the self-hosted captcha answer was wrong/expired.
|
|
28834
|
+
CAPTCHA_INVALID: "CAPTCHA_INVALID",
|
|
28835
|
+
HELP_POOL_UNAVAILABLE: "HELP_POOL_UNAVAILABLE",
|
|
28836
|
+
// AI Help daily cap reached (ADR-0286): the asker (or their org) exceeded the per-day question
|
|
28837
|
+
// cap; meta carries { scope, limit, used, resetAt }. Thrown before any dispatch (0 token cost).
|
|
28838
|
+
HELP_RATE_LIMITED: "HELP_RATE_LIMITED",
|
|
28839
|
+
// AI Help admin moderation (ADR-0237): the user/org is blocked from the channel, or the whole
|
|
28840
|
+
// AI support service is toggled off platform-wide.
|
|
28841
|
+
HELP_BLOCKED: "HELP_BLOCKED",
|
|
28842
|
+
HELP_DISABLED: "HELP_DISABLED",
|
|
28843
|
+
// Project GitHub-App git-auth (ADR-0356): method set without a credential; a rejected credential
|
|
28844
|
+
// (App ID / PEM / host / CA); an ssh repo URL under the App method; the primary repo's host differs
|
|
28845
|
+
// from the credential host; the server has no SECRETS_ENC_KEY to store/read secrets.
|
|
28846
|
+
GIT_CREDENTIAL_MISSING: "GIT_CREDENTIAL_MISSING",
|
|
28847
|
+
GIT_CREDENTIAL_INVALID: "GIT_CREDENTIAL_INVALID",
|
|
28848
|
+
GIT_AUTH_REQUIRES_HTTPS: "GIT_AUTH_REQUIRES_HTTPS",
|
|
28849
|
+
GIT_HOST_MISMATCH: "GIT_HOST_MISMATCH",
|
|
28850
|
+
SECRETS_KEY_NOT_CONFIGURED: "SECRETS_KEY_NOT_CONFIGURED",
|
|
28851
|
+
// Org announcements (ADR-0367): a target outside the sender's PM/TL scope; targets resolving to
|
|
28852
|
+
// nobody; the org's daily recipient cap (`announcementDailyRecipients`); unknown history row /
|
|
28853
|
+
// draft; the per-user draft cap.
|
|
28854
|
+
ANNOUNCEMENT_TARGET_FORBIDDEN: "ANNOUNCEMENT_TARGET_FORBIDDEN",
|
|
28855
|
+
ANNOUNCEMENT_NO_RECIPIENTS: "ANNOUNCEMENT_NO_RECIPIENTS",
|
|
28856
|
+
ANNOUNCEMENT_DAILY_LIMIT: "ANNOUNCEMENT_DAILY_LIMIT",
|
|
28857
|
+
ANNOUNCEMENT_NOT_FOUND: "ANNOUNCEMENT_NOT_FOUND",
|
|
28858
|
+
ANNOUNCEMENT_DRAFT_NOT_FOUND: "ANNOUNCEMENT_DRAFT_NOT_FOUND",
|
|
28859
|
+
ANNOUNCEMENT_DRAFT_LIMIT: "ANNOUNCEMENT_DRAFT_LIMIT",
|
|
28860
|
+
// Worker-cli operation failures surfaced to the web/admin so they localize via `errors.*`
|
|
28861
|
+
// (see CLI_ERROR_CODE_MAP below): filesystem guards, RAG, agent/content validation, support
|
|
28862
|
+
// answer, FAQ compose, git host, autonomous base push.
|
|
28863
|
+
WORKER_PATH_ESCAPES_ROOT: "WORKER_PATH_ESCAPES_ROOT",
|
|
28864
|
+
WORKER_NO_PROJECT: "WORKER_NO_PROJECT",
|
|
28865
|
+
WORKER_PATH_EXISTS: "WORKER_PATH_EXISTS",
|
|
28866
|
+
WORKER_ROOT_PROTECTED: "WORKER_ROOT_PROTECTED",
|
|
28867
|
+
WORKER_NOT_A_FILE: "WORKER_NOT_A_FILE",
|
|
28868
|
+
WORKER_INVALID_PAYLOAD: "WORKER_INVALID_PAYLOAD",
|
|
28869
|
+
WORKER_INVALID_NAME: "WORKER_INVALID_NAME",
|
|
28870
|
+
WORKER_CONTENT_REQUIRED: "WORKER_CONTENT_REQUIRED",
|
|
28871
|
+
RAG_PYTHON_MISSING: "RAG_PYTHON_MISSING",
|
|
28872
|
+
RAG_NOT_INSTALLED: "RAG_NOT_INSTALLED",
|
|
28873
|
+
RAG_NO_INDEX: "RAG_NO_INDEX",
|
|
28874
|
+
RAG_INVALID_MODEL: "RAG_INVALID_MODEL",
|
|
28875
|
+
SUPPORT_KB_EMPTY: "SUPPORT_KB_EMPTY",
|
|
28876
|
+
SUPPORT_EMPTY_ANSWER: "SUPPORT_EMPTY_ANSWER",
|
|
28877
|
+
FAQ_NO_WRITE_TOKEN: "FAQ_NO_WRITE_TOKEN",
|
|
28878
|
+
GIT_UNKNOWN_HOST: "GIT_UNKNOWN_HOST",
|
|
28879
|
+
AUTONOMOUS_BASE_PUSH_FAILED: "AUTONOMOUS_BASE_PUSH_FAILED"
|
|
28880
|
+
};
|
|
28881
|
+
var CLI_ERROR_CODE_MAP = {
|
|
28882
|
+
"path escapes the project root": { code: ErrorCode.WORKER_PATH_ESCAPES_ROOT, status: 422 },
|
|
28883
|
+
"no project served": { code: ErrorCode.WORKER_NO_PROJECT, status: 409 },
|
|
28884
|
+
"no project": { code: ErrorCode.WORKER_NO_PROJECT, status: 409 },
|
|
28885
|
+
"This worker has no project folder.": { code: ErrorCode.WORKER_NO_PROJECT, status: 409 },
|
|
28886
|
+
"already exists": { code: ErrorCode.WORKER_PATH_EXISTS, status: 409 },
|
|
28887
|
+
"destination already exists": { code: ErrorCode.WORKER_PATH_EXISTS, status: 409 },
|
|
28888
|
+
"cannot move the project root": { code: ErrorCode.WORKER_ROOT_PROTECTED, status: 422 },
|
|
28889
|
+
"cannot delete the project root": { code: ErrorCode.WORKER_ROOT_PROTECTED, status: 422 },
|
|
28890
|
+
"not a file": { code: ErrorCode.WORKER_NOT_A_FILE, status: 422 },
|
|
28891
|
+
"invalid base64 payload": { code: ErrorCode.WORKER_INVALID_PAYLOAD, status: 422 },
|
|
28892
|
+
"invalid name": { code: ErrorCode.WORKER_INVALID_NAME, status: 422 },
|
|
28893
|
+
"content is required": { code: ErrorCode.WORKER_CONTENT_REQUIRED, status: 422 },
|
|
28894
|
+
"invalid slug": { code: ErrorCode.MARKET_INVALID_PACKAGE, status: 422 },
|
|
28895
|
+
"artifact not found": { code: ErrorCode.MARKET_PACKAGE_NOT_FOUND, status: 404 },
|
|
28896
|
+
"not installed": { code: ErrorCode.MARKET_PACKAGE_NOT_FOUND, status: 404 },
|
|
28897
|
+
"python3 not found": { code: ErrorCode.RAG_PYTHON_MISSING, status: 422 },
|
|
28898
|
+
"python3 not found on the worker": { code: ErrorCode.RAG_PYTHON_MISSING, status: 422 },
|
|
28899
|
+
"RAG is not installed": { code: ErrorCode.RAG_NOT_INSTALLED, status: 409 },
|
|
28900
|
+
"no index \u2014 reindex first": { code: ErrorCode.RAG_NO_INDEX, status: 409 },
|
|
28901
|
+
"invalid model name": { code: ErrorCode.RAG_INVALID_MODEL, status: 422 },
|
|
28902
|
+
"KB repo has no documentation": { code: ErrorCode.SUPPORT_KB_EMPTY, status: 422 },
|
|
28903
|
+
"empty answer": { code: ErrorCode.SUPPORT_EMPTY_ANSWER, status: 422 },
|
|
28904
|
+
"no write token": { code: ErrorCode.FAQ_NO_WRITE_TOKEN, status: 422 },
|
|
28905
|
+
"Unknown git host \u2014 no pull request opened.": { code: ErrorCode.GIT_UNKNOWN_HOST, status: 422 },
|
|
28906
|
+
"could not push the change to the base branch (retry)": { code: ErrorCode.AUTONOMOUS_BASE_PUSH_FAILED, status: 422 },
|
|
28907
|
+
"self-approval blocked": { code: ErrorCode.APPROVAL_SELF, status: 409 }
|
|
28908
|
+
};
|
|
28909
|
+
|
|
28572
28910
|
// vendor/@4pm/constants/preferences.ts
|
|
28573
28911
|
var Locale = {
|
|
28574
28912
|
VI: "vi",
|
|
@@ -28930,7 +29268,11 @@ var en_default = {
|
|
|
28930
29268
|
"autoRun.failed": "Autonomous cycle failed to dispatch: {note}",
|
|
28931
29269
|
"autoRun.noDaemon": 'No running daemon for profile "{profile}" \u2014 start it first: 4pm start --profile {profile}',
|
|
28932
29270
|
"autoRun.timeout": "Autonomous cycle exceeded the time limit \u2014 aborting.",
|
|
28933
|
-
"autoRun.authFailed": "Control-channel authentication failed \u2014 the daemon rejected the token."
|
|
29271
|
+
"autoRun.authFailed": "Control-channel authentication failed \u2014 the daemon rejected the token.",
|
|
29272
|
+
"autonomous.cronMissing": "Could not install the autonomous cron: this worker has no working `crontab` (cron service). Autonomous scheduling requires cron on the worker machine.",
|
|
29273
|
+
"autonomous.settingsInvalidJson": "The autonomous settings are not valid JSON.",
|
|
29274
|
+
"config.notObject": "config.json must be a JSON object.",
|
|
29275
|
+
"config.invalidJson": "Invalid JSON: {message}"
|
|
28934
29276
|
};
|
|
28935
29277
|
|
|
28936
29278
|
// src/i18n/messages/vi.json
|
|
@@ -29115,7 +29457,11 @@ var vi_default = {
|
|
|
29115
29457
|
"autoRun.failed": "Kh\xF4ng \u0111i\u1EC1u ph\u1ED1i \u0111\u01B0\u1EE3c chu k\u1EF3 t\u1EF1 \u0111\u1ED9ng: {note}",
|
|
29116
29458
|
"autoRun.noDaemon": 'Kh\xF4ng c\xF3 ti\u1EBFn tr\xECnh n\u1EC1n n\xE0o cho h\u1ED3 s\u01A1 "{profile}" \u2014 h\xE3y kh\u1EDFi \u0111\u1ED9ng tr\u01B0\u1EDBc: 4pm start --profile {profile}',
|
|
29117
29459
|
"autoRun.timeout": "Chu k\u1EF3 t\u1EF1 \u0111\u1ED9ng v\u01B0\u1EE3t qu\xE1 gi\u1EDBi h\u1EA1n th\u1EDDi gian \u2014 \u0111ang h\u1EE7y.",
|
|
29118
|
-
"autoRun.authFailed": "X\xE1c th\u1EF1c k\xEAnh \u0111i\u1EC1u khi\u1EC3n th\u1EA5t b\u1EA1i \u2014 daemon t\u1EEB ch\u1ED1i token."
|
|
29460
|
+
"autoRun.authFailed": "X\xE1c th\u1EF1c k\xEAnh \u0111i\u1EC1u khi\u1EC3n th\u1EA5t b\u1EA1i \u2014 daemon t\u1EEB ch\u1ED1i token.",
|
|
29461
|
+
"autonomous.cronMissing": "Kh\xF4ng c\xE0i \u0111\u01B0\u1EE3c cron t\u1EF1 h\xE0nh: worker n\xE0y kh\xF4ng c\xF3 `crontab` ho\u1EA1t \u0111\u1ED9ng (d\u1ECBch v\u1EE5 cron). L\u1EADp l\u1ECBch t\u1EF1 h\xE0nh c\u1EA7n cron tr\xEAn m\xE1y worker.",
|
|
29462
|
+
"autonomous.settingsInvalidJson": "C\u1EA5u h\xECnh t\u1EF1 h\xE0nh kh\xF4ng ph\u1EA3i JSON h\u1EE3p l\u1EC7.",
|
|
29463
|
+
"config.notObject": "config.json ph\u1EA3i l\xE0 m\u1ED9t \u0111\u1ED1i t\u01B0\u1EE3ng JSON.",
|
|
29464
|
+
"config.invalidJson": "JSON kh\xF4ng h\u1EE3p l\u1EC7: {message}"
|
|
29119
29465
|
};
|
|
29120
29466
|
|
|
29121
29467
|
// src/i18n/messages/ja.json
|
|
@@ -29300,7 +29646,11 @@ var ja_default = {
|
|
|
29300
29646
|
"autoRun.failed": "\u81EA\u5F8B\u30B5\u30A4\u30AF\u30EB\u306E\u30C7\u30A3\u30B9\u30D1\u30C3\u30C1\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {note}",
|
|
29301
29647
|
"autoRun.noDaemon": '\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB "{profile}" \u306E\u30C7\u30FC\u30E2\u30F3\u304C\u5B9F\u884C\u3055\u308C\u3066\u3044\u307E\u305B\u3093 \u2014 \u5148\u306B\u8D77\u52D5\u3057\u3066\u304F\u3060\u3055\u3044: 4pm start --profile {profile}',
|
|
29302
29648
|
"autoRun.timeout": "\u81EA\u5F8B\u30B5\u30A4\u30AF\u30EB\u304C\u5236\u9650\u6642\u9593\u3092\u8D85\u3048\u307E\u3057\u305F \u2014 \u4E2D\u6B62\u3057\u307E\u3059\u3002",
|
|
29303
|
-
"autoRun.authFailed": "\u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30C1\u30E3\u30CD\u30EB\u306E\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F \u2014 \u30C7\u30FC\u30E2\u30F3\u304C\u30C8\u30FC\u30AF\u30F3\u3092\u62D2\u5426\u3057\u307E\u3057\u305F\u3002"
|
|
29649
|
+
"autoRun.authFailed": "\u30B3\u30F3\u30C8\u30ED\u30FC\u30EB\u30C1\u30E3\u30CD\u30EB\u306E\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F \u2014 \u30C7\u30FC\u30E2\u30F3\u304C\u30C8\u30FC\u30AF\u30F3\u3092\u62D2\u5426\u3057\u307E\u3057\u305F\u3002",
|
|
29650
|
+
"autonomous.cronMissing": "\u81EA\u5F8B cron \u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F: \u3053\u306E\u30EF\u30FC\u30AB\u30FC\u306B\u306F\u52D5\u4F5C\u3059\u308B `crontab`\uFF08cron \u30B5\u30FC\u30D3\u30B9\uFF09\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u81EA\u5F8B\u30B9\u30B1\u30B8\u30E5\u30FC\u30EA\u30F3\u30B0\u306B\u306F\u30EF\u30FC\u30AB\u30FC\u30DE\u30B7\u30F3\u306E cron \u304C\u5FC5\u8981\u3067\u3059\u3002",
|
|
29651
|
+
"autonomous.settingsInvalidJson": "\u81EA\u5F8B\u8A2D\u5B9A\u304C\u6709\u52B9\u306A JSON \u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
|
|
29652
|
+
"config.notObject": "config.json \u306F JSON \u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002",
|
|
29653
|
+
"config.invalidJson": "\u7121\u52B9\u306A JSON: {message}"
|
|
29304
29654
|
};
|
|
29305
29655
|
|
|
29306
29656
|
// src/i18n/messages/zh.json
|
|
@@ -29485,7 +29835,11 @@ var zh_default = {
|
|
|
29485
29835
|
"autoRun.failed": "\u81EA\u4E3B\u5FAA\u73AF\u8C03\u5EA6\u5931\u8D25\uFF1A{note}",
|
|
29486
29836
|
"autoRun.noDaemon": "\u914D\u7F6E\u6587\u4EF6 \u201C{profile}\u201D \u6CA1\u6709\u6B63\u5728\u8FD0\u884C\u7684\u5B88\u62A4\u8FDB\u7A0B \u2014 \u8BF7\u5148\u542F\u52A8\uFF1A4pm start --profile {profile}",
|
|
29487
29837
|
"autoRun.timeout": "\u81EA\u4E3B\u5FAA\u73AF\u8D85\u8FC7\u65F6\u95F4\u9650\u5236 \u2014 \u6B63\u5728\u4E2D\u6B62\u3002",
|
|
29488
|
-
"autoRun.authFailed": "\u63A7\u5236\u901A\u9053\u8BA4\u8BC1\u5931\u8D25 \u2014 \u5B88\u62A4\u8FDB\u7A0B\u62D2\u7EDD\u4E86\u4EE4\u724C\u3002"
|
|
29838
|
+
"autoRun.authFailed": "\u63A7\u5236\u901A\u9053\u8BA4\u8BC1\u5931\u8D25 \u2014 \u5B88\u62A4\u8FDB\u7A0B\u62D2\u7EDD\u4E86\u4EE4\u724C\u3002",
|
|
29839
|
+
"autonomous.cronMissing": "\u65E0\u6CD5\u5B89\u88C5\u81EA\u4E3B cron\uFF1A\u6B64\u5DE5\u4F5C\u673A\u6CA1\u6709\u53EF\u7528\u7684 `crontab`\uFF08cron \u670D\u52A1\uFF09\u3002\u81EA\u4E3B\u8C03\u5EA6\u9700\u8981\u5DE5\u4F5C\u673A\u4E0A\u7684 cron\u3002",
|
|
29840
|
+
"autonomous.settingsInvalidJson": "\u81EA\u4E3B\u8BBE\u7F6E\u4E0D\u662F\u6709\u6548\u7684 JSON\u3002",
|
|
29841
|
+
"config.notObject": "config.json \u5FC5\u987B\u662F JSON \u5BF9\u8C61\u3002",
|
|
29842
|
+
"config.invalidJson": "\u65E0\u6548\u7684 JSON\uFF1A{message}"
|
|
29489
29843
|
};
|
|
29490
29844
|
|
|
29491
29845
|
// src/i18n/messages/index.ts
|
|
@@ -41276,7 +41630,7 @@ async function installCron(root, profileDir2) {
|
|
|
41276
41630
|
await chmod(script, 493).catch(() => void 0);
|
|
41277
41631
|
const kept = (await crontabList()).split("\n").filter((l) => l.trim() && !l.includes(script));
|
|
41278
41632
|
kept.push(`${cfg.cronSchedule} ${script}`);
|
|
41279
|
-
|
|
41633
|
+
return crontabSet(kept.join("\n"));
|
|
41280
41634
|
}
|
|
41281
41635
|
async function syncCron(root, profileDir2) {
|
|
41282
41636
|
if (await cronInstalled(root)) await installCron(root, profileDir2);
|
|
@@ -41353,12 +41707,16 @@ async function writeAutonomous(root, profileDir2, req, by) {
|
|
|
41353
41707
|
try {
|
|
41354
41708
|
if (req.kind === "settings") {
|
|
41355
41709
|
const parsed = parseJson(req.settings);
|
|
41356
|
-
if (!parsed) return { ok: false, error: "
|
|
41710
|
+
if (!parsed) return { ok: false, error: t("autonomous.settingsInvalidJson") };
|
|
41357
41711
|
await writeAutonomousConfig(profileDir2, parsed);
|
|
41358
41712
|
await syncCron(root, profileDir2);
|
|
41359
41713
|
} else if (req.kind === "cron") {
|
|
41360
|
-
if (req.action === "install")
|
|
41361
|
-
|
|
41714
|
+
if (req.action === "install") {
|
|
41715
|
+
const wrote = await installCron(root, profileDir2);
|
|
41716
|
+
if (!wrote || !await cronInstalled(root)) {
|
|
41717
|
+
return { ok: false, error: t("autonomous.cronMissing") };
|
|
41718
|
+
}
|
|
41719
|
+
} else await uninstallCron(root);
|
|
41362
41720
|
} else {
|
|
41363
41721
|
const base = (await resolveBases(root).catch(() => null))?.root.base ?? "";
|
|
41364
41722
|
let res;
|
|
@@ -46369,10 +46727,10 @@ function applyConfigText(profileDir2, text) {
|
|
|
46369
46727
|
try {
|
|
46370
46728
|
parsed = JSON.parse(text);
|
|
46371
46729
|
} catch (err) {
|
|
46372
|
-
return { ok: false, error:
|
|
46730
|
+
return { ok: false, error: t("config.invalidJson", { message: err.message }) };
|
|
46373
46731
|
}
|
|
46374
46732
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
46375
|
-
return { ok: false, error: "config.
|
|
46733
|
+
return { ok: false, error: t("config.notObject") };
|
|
46376
46734
|
}
|
|
46377
46735
|
const next = { ...parsed };
|
|
46378
46736
|
const current2 = readProfileConfig(profileDir2);
|