Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package agama-web-ui for openSUSE:Factory 
checked in at 2026-01-30 18:19:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/agama-web-ui (Old)
 and      /work/SRC/openSUSE:Factory/.agama-web-ui.new.1995 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "agama-web-ui"

Fri Jan 30 18:19:40 2026 rev:34 rq:1329818 version:0

Changes:
--------
--- /work/SRC/openSUSE:Factory/agama-web-ui/agama-web-ui.changes        
2026-01-28 15:06:18.655914354 +0100
+++ /work/SRC/openSUSE:Factory/.agama-web-ui.new.1995/agama-web-ui.changes      
2026-01-30 18:20:03.451930254 +0100
@@ -1,0 +2,20 @@
+Thu Jan 29 10:26:49 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Do not crash when selecting a pattern (gh#agama-project/agama#3097,
+  bsc#1257454).
+
+-------------------------------------------------------------------
+Wed Jan 28 12:43:13 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Force the user to select a mode when it is needed (related to
+  jsc#PED-14307).
+- Do not loose the mode when registering a product (related to
+  jsc#PED-14307).
+- Reset the configuration when selecting a new product.
+
+-------------------------------------------------------------------
+Wed Jan 28 11:00:28 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Allow selecting the mode in the product selection screen (jsc#PED-14307).
+
+-------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ agama.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/package/agama-web-ui.changes 
new/agama/package/agama-web-ui.changes
--- old/agama/package/agama-web-ui.changes      2026-01-26 15:26:53.000000000 
+0100
+++ new/agama/package/agama-web-ui.changes      2026-01-29 11:55:42.000000000 
+0100
@@ -1,4 +1,24 @@
 -------------------------------------------------------------------
+Thu Jan 29 10:26:49 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Do not crash when selecting a pattern (gh#agama-project/agama#3097,
+  bsc#1257454).
+
+-------------------------------------------------------------------
+Wed Jan 28 12:43:13 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Force the user to select a mode when it is needed (related to
+  jsc#PED-14307).
+- Do not loose the mode when registering a product (related to
+  jsc#PED-14307).
+- Reset the configuration when selecting a new product.
+
+-------------------------------------------------------------------
+Wed Jan 28 11:00:28 UTC 2026 - Imobach Gonzalez Sosa <[email protected]>
+
+- Allow selecting the mode in the product selection screen (jsc#PED-14307).
+
+-------------------------------------------------------------------
 Fri Jan 23 15:34:08 UTC 2026 - Ladislav Slezák <[email protected]>
 
 - Fixed removing automatically selected recommended patterns
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/agama/src/components/core/ChangeProductOption.test.tsx 
new/agama/src/components/core/ChangeProductOption.test.tsx
--- old/agama/src/components/core/ChangeProductOption.test.tsx  2026-01-26 
15:26:53.000000000 +0100
+++ new/agama/src/components/core/ChangeProductOption.test.tsx  2026-01-29 
11:55:42.000000000 +0100
@@ -24,9 +24,9 @@
 import { screen } from "@testing-library/react";
 import { installerRender } from "~/test-utils";
 import { useSystem } from "~/hooks/model/system";
-import { Product } from "~/types/software";
 import { PRODUCT as PATHS } from "~/routes/paths";
 import ChangeProductOption from "./ChangeProductOption";
+import { Product } from "~/model/system";
 
 const tumbleweed: Product = {
   id: "Tumbleweed",
@@ -34,6 +34,7 @@
   icon: "tumbleweed.svg",
   description: "Tumbleweed description...",
   registration: false,
+  modes: [],
 };
 
 const microos: Product = {
@@ -42,6 +43,7 @@
   icon: "MicroOS.svg",
   description: "MicroOS description",
   registration: false,
+  modes: [],
 };
 
 // let registrationInfoMock: RegistrationInfo;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/src/components/core/ChangeProductOption.tsx 
new/agama/src/components/core/ChangeProductOption.tsx
--- old/agama/src/components/core/ChangeProductOption.tsx       2026-01-26 
15:26:53.000000000 +0100
+++ new/agama/src/components/core/ChangeProductOption.tsx       2026-01-29 
11:55:42.000000000 +0100
@@ -28,6 +28,7 @@
 import { _ } from "~/i18n";
 import { useSystem } from "~/hooks/model/system";
 import { useStatus } from "~/hooks/model/status";
+import { isEmpty } from "radashi";
 
 /**
  * DropdownItem Option for navigating to the selection product.
@@ -37,15 +38,22 @@
   const { stage } = useStatus();
   const currentLocation = useLocation();
   const to = useHref(PATHS.changeProduct);
+  const hasModes = products.find((p) => !isEmpty(p.modes));
 
-  if (products.length <= 1) return null;
+  if (products.length <= 1 && !hasModes) return null;
   if (software?.registration) return null;
   if (SIDE_PATHS.includes(currentLocation.pathname)) return null;
   if (stage !== "configuring") return null;
 
+  const getLabel = () => {
+    if (products.length === 1 && hasModes) return _("Change mode");
+    if (hasModes) return _("Change product or mode");
+    return _("Change product");
+  };
+
   return (
     <DropdownItem to={to} {...props}>
-      {children || _("Change product")}
+      {children || getLabel()}
     </DropdownItem>
   );
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/src/components/layout/Header.test.tsx 
new/agama/src/components/layout/Header.test.tsx
--- old/agama/src/components/layout/Header.test.tsx     2026-01-26 
15:26:53.000000000 +0100
+++ new/agama/src/components/layout/Header.test.tsx     2026-01-29 
11:55:42.000000000 +0100
@@ -23,16 +23,17 @@
 import React from "react";
 import { screen, within } from "@testing-library/react";
 import { plainRender, installerRender } from "~/test-utils";
-import { Product } from "~/types/software";
 import { System } from "~/model/system/network";
 import Header from "./Header";
 import { useSystem } from "~/hooks/model/system";
+import { Product } from "~/model/system";
 
 const tumbleweed: Product = {
   id: "Tumbleweed",
   name: "openSUSE Tumbleweed",
   description: "Tumbleweed description...",
   registration: false,
+  modes: [],
 };
 
 const microos: Product = {
@@ -40,6 +41,7 @@
   name: "openSUSE MicroOS",
   description: "MicroOS description",
   registration: false,
+  modes: [],
 };
 
 const network: System = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/agama/src/components/product/ProductRegistrationPage.test.tsx 
new/agama/src/components/product/ProductRegistrationPage.test.tsx
--- old/agama/src/components/product/ProductRegistrationPage.test.tsx   
2026-01-26 15:26:53.000000000 +0100
+++ new/agama/src/components/product/ProductRegistrationPage.test.tsx   
2026-01-29 11:55:42.000000000 +0100
@@ -35,12 +35,14 @@
   id: "Tumbleweed",
   name: "openSUSE Tumbleweed",
   registration: false,
+  modes: [],
 };
 
 const sle: Product = {
   id: "sle",
   name: "SLE",
   registration: true,
+  modes: [],
 };
 
 let mockSelectedProduct: Product | undefined;
@@ -78,7 +80,7 @@
 
 describe("ProductRegistrationPage", () => {
   beforeEach(() => {
-    mockConfig = { product: { id: "sle", registrationCode: "" } };
+    mockConfig = { product: { id: "sle", mode: "standard", registrationCode: 
"" } };
     mockIssues = [];
     mockProductConfig(mockConfig.product);
     // @ts-ignore
@@ -142,6 +144,7 @@
         ...mockConfig,
         product: {
           id: "sle",
+          mode: "standard",
           registrationCode: "INTERNAL-USE-ONLY-1234-5678",
           registrationEmail: undefined,
           registrationUrl: undefined,
@@ -170,6 +173,7 @@
         ...mockConfig,
         product: {
           id: "sle",
+          mode: "standard",
           registrationCode: "INTERNAL-USE-ONLY-1234-5678",
           registrationEmail: "[email protected]",
           registrationUrl: undefined,
@@ -209,6 +213,7 @@
         ...mockConfig,
         product: {
           id: "sle",
+          mode: "standard",
           registrationUrl: "https://custom-server.test";,
           registrationCode: undefined,
           registrationEmail: undefined,
@@ -270,6 +275,7 @@
             ...mockConfig,
             product: {
               id: "sle",
+              mode: "standard",
               registrationUrl: "https://custom-server.test";,
               registrationCode: "INTERNAL-USE-ONLY-1234-5678",
               registrationEmail: undefined,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/agama/src/components/product/ProductRegistrationPage.tsx 
new/agama/src/components/product/ProductRegistrationPage.tsx
--- old/agama/src/components/product/ProductRegistrationPage.tsx        
2026-01-26 15:26:53.000000000 +0100
+++ new/agama/src/components/product/ProductRegistrationPage.tsx        
2026-01-29 11:55:42.000000000 +0100
@@ -328,6 +328,7 @@
       ...config,
       product: {
         id: product.id,
+        mode: product.mode,
         registrationCode: isKeyRequired ? key : undefined,
         registrationEmail: provideEmail ? email : undefined,
         registrationUrl: isUrlRequired ? url : undefined,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/agama/src/components/product/ProductSelectionPage.test.tsx 
new/agama/src/components/product/ProductSelectionPage.test.tsx
--- old/agama/src/components/product/ProductSelectionPage.test.tsx      
2026-01-26 15:26:53.000000000 +0100
+++ new/agama/src/components/product/ProductSelectionPage.test.tsx      
2026-01-29 11:55:42.000000000 +0100
@@ -25,9 +25,9 @@
 import { installerRender, mockNavigateFn, mockProduct } from "~/test-utils";
 import { useSystem } from "~/hooks/model/system";
 import { useSystem as useSystemSoftware } from "~/hooks/model/system/software";
-import { Product } from "~/types/software";
 import { ROOT } from "~/routes/paths";
 import ProductSelectionPage from "./ProductSelectionPage";
+import { Product } from "~/model/system";
 
 const tumbleweed: Product = {
   id: "Tumbleweed",
@@ -35,6 +35,7 @@
   icon: "tumbleweed.svg",
   description: "Tumbleweed description...",
   registration: false,
+  modes: [],
 };
 
 const microOs: Product = {
@@ -44,9 +45,10 @@
   description: "MicroOS description",
   registration: false,
   license: "fake.license",
+  modes: [],
 };
 
-const mockPatchConfigFn = jest.fn();
+const mockPutConfigFn = jest.fn();
 const mockUseSystemFn: jest.Mock<ReturnType<typeof useSystem>> = jest.fn();
 const mockUseSystemSoftwareFn: jest.Mock<ReturnType<typeof useSystemSoftware>> 
= jest.fn();
 
@@ -59,7 +61,7 @@
 
 jest.mock("~/api", () => ({
   ...jest.requireActual("~/api"),
-  patchConfig: (payload) => mockPatchConfigFn(payload),
+  putConfig: (payload) => mockPutConfigFn(payload),
 }));
 
 jest.mock("~/hooks/model/system", () => ({
@@ -181,7 +183,7 @@
     const selectButton = screen.getByRole("button", { name: "Select" });
     await user.click(productOption);
     await user.click(selectButton);
-    expect(mockPatchConfigFn).toHaveBeenCalledWith({ product: { id: 
tumbleweed.id } });
+    expect(mockPutConfigFn).toHaveBeenCalledWith({ product: { id: 
tumbleweed.id } });
   });
 
   it("does not trigger the product selection if user selects a product but 
clicks o cancel button", async () => {
@@ -192,7 +194,7 @@
     expect(cancel).toHaveAttribute("href", ROOT.overview);
     await user.click(productOption);
     await user.click(cancel);
-    expect(mockPatchConfigFn).not.toHaveBeenCalled();
+    expect(mockPutConfigFn).not.toHaveBeenCalled();
   });
 
   it.todo("make navigation test work");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/agama/src/components/product/ProductSelectionPage.tsx 
new/agama/src/components/product/ProductSelectionPage.tsx
--- old/agama/src/components/product/ProductSelectionPage.tsx   2026-01-26 
15:26:53.000000000 +0100
+++ new/agama/src/components/product/ProductSelectionPage.tsx   2026-01-29 
11:55:42.000000000 +0100
@@ -56,8 +56,8 @@
 import LicenseDialog from "~/components/product/LicenseDialog";
 import Text from "~/components/core/Text";
 import agama from "~/agama";
-import { patchConfig } from "~/api";
-import { useProductInfo } from "~/hooks/model/config/product";
+import { putConfig } from "~/api";
+import { useProduct, useProductInfo } from "~/hooks/model/config/product";
 import { useSystem } from "~/hooks/model/system";
 import { useSystem as useSystemSoftware } from "~/hooks/model/system/software";
 import { ROOT } from "~/routes/paths";
@@ -76,6 +76,8 @@
   isChecked: boolean;
   /** Callback fired when the product is selected */
   onChange: () => void;
+  /** Callback fired when the mode is changed */
+  onModeChange: (mode: string) => void;
 };
 
 /**
@@ -85,6 +87,7 @@
   product,
   isChecked,
   onChange,
+  onModeChange,
 }: ProductFormProductOptionProps) => {
   const detailsId = `${product.id}-details`;
   const currentLocale = agama.language.replace("-", "_");
@@ -111,13 +114,20 @@
                 }
                 body={
                   <Stack hasGutter id={detailsId}>
-                    {product.license && (
+                    {(product.license || product.modes) && (
                       <Split hasGutter>
                         {product.license && (
                           <Label variant="outline" isCompact>
                             <Text component="small">{_("License acceptance 
required")}</Text>
                           </Label>
                         )}
+                        {!isEmpty(product.modes) && (
+                          <Label variant="outline" isCompact>
+                            <Text component="small">
+                              {sprintf(_("%d modes available"), 
product.modes.length)}
+                            </Text>
+                          </Label>
+                        )}
                       </Split>
                     )}
 
@@ -129,6 +139,22 @@
                     >
                       <SubtleContent>{translatedDescription}</SubtleContent>
                     </ExpandableSection>
+                    {isChecked && product.modes && (
+                      <Split hasGutter>
+                        {product.modes.map((mode) => (
+                          <FlexItem key={mode.id}>
+                            <Radio
+                              key={mode.id}
+                              id={mode.id}
+                              name="mode"
+                              onChange={() => onModeChange(mode.id)}
+                              label={<Text isBold>{mode.name}</Text>}
+                              description={mode.description}
+                            />
+                          </FlexItem>
+                        ))}
+                      </Split>
+                    )}
                   </Stack>
                 }
               />
@@ -230,6 +256,7 @@
   currentProduct,
   selectedProduct,
 }: ProductFormSubmitLabelProps) => {
+  // FIXME: add logic to include information about the mode
   const action = currentProduct ? _("Change to %s") : _("Select %s");
   const fallback = currentProduct ? _("Change") : _("Select");
 
@@ -293,7 +320,7 @@
   /** The product currently configured in the system */
   currentProduct?: Product;
   /** Callback fired when the form is submitted with a selected product */
-  onSubmit: (product: Product) => void;
+  onSubmit: (product: Product, mode: string) => void;
   /** Whether the form was already submitted */
   isSubmitted: boolean;
 };
@@ -327,23 +354,30 @@
  *
  * Manages product selection state, license acceptance, and form validation.
  * Excludes the current product from the list of options.
+ *
+ * TODO: use a reducer instead of bunch of isolated state pieces
  */
 const ProductForm = ({ products, currentProduct, isSubmitted, onSubmit }: 
ProductFormProps) => {
   const [selectedProduct, setSelectedProduct] = useState<Product>();
+  const [selectedMode, setSelectedMode] = useState<string>();
   const [eulaAccepted, setEulaAccepted] = useState(false);
   const mountEulaCheckbox = selectedProduct && 
!isEmpty(selectedProduct.license);
   const isSelectionDisabled =
-    !selectedProduct || isSubmitted || (mountEulaCheckbox && !eulaAccepted);
+    !selectedProduct ||
+    isSubmitted ||
+    (mountEulaCheckbox && !eulaAccepted) ||
+    (!isEmpty(selectedProduct.modes) && !selectedMode);
 
   const onProductSelectionChange = (product) => {
     setEulaAccepted(false);
+    setSelectedMode(undefined);
     setSelectedProduct(product);
   };
 
   const onFormSubmission = (e: React.FormEvent) => {
     e.preventDefault();
 
-    onSubmit(selectedProduct);
+    onSubmit(selectedProduct, selectedMode);
   };
 
   return (
@@ -359,7 +393,7 @@
       >
         <List isPlain>
           {products.map((product, index) => {
-            if (product.id === currentProduct?.id) return undefined;
+            if (product.id === currentProduct?.id && !product.modes) return 
undefined;
 
             return (
               <ProductFormProductOption
@@ -367,6 +401,7 @@
                 product={product}
                 isChecked={selectedProduct?.id === product?.id}
                 onChange={() => onProductSelectionChange(product)}
+                onModeChange={setSelectedMode}
               />
             );
           })}
@@ -422,6 +457,8 @@
 type CurrentProductInfoProps = {
   /** The currently configured product to display */
   product?: Product;
+  /** The selected mode */
+  modeId?: string;
 };
 
 /**
@@ -429,9 +466,14 @@
  *
  * Shows product name, description, and a link to view the license if 
applicable.
  */
-const CurrentProductInfo = ({ product }: CurrentProductInfoProps) => {
+const CurrentProductInfo = ({ product, modeId }: CurrentProductInfoProps) => {
   if (!product) return;
 
+  let mode;
+  if (modeId) {
+    mode = product.modes.find((m) => m.id === modeId);
+  }
+
   return (
     <Card variant="secondary" component="section" className="sticky-top">
       <CardTitle component="h2">{_("Current selection")}</CardTitle>
@@ -443,6 +485,15 @@
           <Divider />
           <SubtleContent>{product.description}</SubtleContent>
 
+          {mode && (
+            <>
+              <Title headingLevel="h3">{mode.name}</Title>
+
+              <Divider />
+              <SubtleContent>{mode.description}</SubtleContent>
+            </>
+          )}
+
           {product.license && (
             <LicenseButton product={product} variant="secondary" isInline>
               {_("View license")}
@@ -465,6 +516,7 @@
  */
 const ProductSelectionContent = () => {
   const navigate = useNavigate();
+  const product = useProduct();
   const { products } = useSystem();
   const currentProduct = useProductInfo();
   const [submittedSelection, setSubmmitedSelection] = useState<Product>();
@@ -479,10 +531,11 @@
     }
   }, [navigate, isSubmitted, currentProduct, submittedSelection]);
 
-  const onSubmit = async (selectedProduct: Product) => {
+  const onSubmit = async (selectedProduct: Product, selectedMode: string) => {
     setIsSubmmited(true);
     setSubmmitedSelection(selectedProduct);
-    patchConfig({ product: { id: selectedProduct.id } });
+    // FIXME: use Mode as expected
+    putConfig({ product: { id: selectedProduct.id, mode: selectedMode } });
   };
 
   const introText = n_(
@@ -518,7 +571,7 @@
             />
           </GridItem>
           <GridItem sm={12} md={4} order={{ default: "0", md: "1" }}>
-            {!isWaiting && <CurrentProductInfo product={currentProduct} />}
+            {!isWaiting && <CurrentProductInfo product={currentProduct} 
modeId={product?.mode} />}
           </GridItem>
         </Grid>
       </Page.Content>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/agama/src/components/questions/LuksActivationQuestion.test.tsx 
new/agama/src/components/questions/LuksActivationQuestion.test.tsx
--- old/agama/src/components/questions/LuksActivationQuestion.test.tsx  
2026-01-26 15:26:53.000000000 +0100
+++ new/agama/src/components/questions/LuksActivationQuestion.test.tsx  
2026-01-29 11:55:42.000000000 +0100
@@ -27,9 +27,9 @@
 import { useProductInfo } from "~/hooks/model/config/product";
 import { installerRender } from "~/test-utils";
 import { AnswerCallback, Question, FieldType } from "~/model/question";
-import { Product } from "~/types/software";
 import type { Locale, Keymap } from "~/model/system/l10n";
 import LuksActivationQuestion from 
"~/components/questions/LuksActivationQuestion";
+import { Product } from "~/model/system";
 
 let question: Question;
 const questionMock: Question = {
@@ -50,6 +50,7 @@
   icon: "tumbleweed.svg",
   description: "Tumbleweed description...",
   registration: false,
+  modes: [],
 };
 
 const locales: Locale[] = [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/agama/src/components/questions/QuestionWithPassword.test.tsx 
new/agama/src/components/questions/QuestionWithPassword.test.tsx
--- old/agama/src/components/questions/QuestionWithPassword.test.tsx    
2026-01-26 15:26:53.000000000 +0100
+++ new/agama/src/components/questions/QuestionWithPassword.test.tsx    
2026-01-29 11:55:42.000000000 +0100
@@ -24,12 +24,12 @@
 import { screen } from "@testing-library/react";
 import { installerRender } from "~/test-utils";
 import { Question, FieldType } from "~/model/question";
-import { Product } from "~/types/software";
 import { useSystem } from "~/hooks/model/system";
 import { useProductInfo } from "~/hooks/model/config/product";
 import { useStatus } from "~/hooks/model/status";
 import { Locale, Keymap } from "~/model/system/l10n";
 import QuestionWithPassword from "~/components/questions/QuestionWithPassword";
+import { Product } from "~/model/system";
 
 const answerFn = jest.fn();
 const question: Question = {
@@ -50,6 +50,7 @@
   icon: "tumbleweed.svg",
   description: "Tumbleweed description...",
   registration: false,
+  modes: [],
 };
 
 const locales: Locale[] = [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/agama/src/components/software/SoftwarePatternsSelection.tsx 
new/agama/src/components/software/SoftwarePatternsSelection.tsx
--- old/agama/src/components/software/SoftwarePatternsSelection.tsx     
2026-01-26 15:26:53.000000000 +0100
+++ new/agama/src/components/software/SoftwarePatternsSelection.tsx     
2026-01-29 11:55:42.000000000 +0100
@@ -107,7 +107,8 @@
  */
 function SoftwarePatternsSelection(): React.ReactNode {
   const { patterns } = useSystem();
-  const { patterns: selection } = useProposal();
+  const proposal = useProposal();
+  const selection = proposal?.patterns || [];
   const [searchValue, setSearchValue] = useState("");
 
   const onToggle = (name: string, selected: boolean) => {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/src/model/config/product.ts 
new/agama/src/model/config/product.ts
--- old/agama/src/model/config/product.ts       2026-01-26 15:26:53.000000000 
+0100
+++ new/agama/src/model/config/product.ts       2026-01-29 11:55:42.000000000 
+0100
@@ -22,6 +22,7 @@
 
 type Config = {
   id?: string;
+  mode?: string;
   registrationCode?: string;
   registrationEmail?: string;
   registrationUrl?: string;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/src/model/system.ts 
new/agama/src/model/system.ts
--- old/agama/src/model/system.ts       2026-01-26 15:26:53.000000000 +0100
+++ new/agama/src/model/system.ts       2026-01-29 11:55:42.000000000 +0100
@@ -55,6 +55,16 @@
     /** The key is the locale (e.g., "en", "pt_BR") */
     description: Record<string, string>;
   };
+  modes: Mode[];
 };
 
-export type { System, Product, L10n, Hardware, Hostname, Network, Software, 
Storage };
+type Mode = {
+  /** Mode ID (e.g., "traditional") */
+  id: string;
+  /** Mode name (e.g., "Traditional") */
+  name: string;
+  /** Mode description (e.g., "Traditional system") */
+  description: string;
+};
+
+export type { System, Product, L10n, Hardware, Hostname, Mode, Network, 
Software, Storage };

++++++ agama.obsinfo ++++++
--- /var/tmp/diff_new_pack.9NqKe2/_old  2026-01-30 18:20:27.620938702 +0100
+++ /var/tmp/diff_new_pack.9NqKe2/_new  2026-01-30 18:20:27.636939370 +0100
@@ -1,5 +1,5 @@
 name: agama
-version: 19.pre+1189.efc3a4978
-mtime: 1769437613
-commit: efc3a497809aa4a54ee0169dd81aa92f5eab5e64
+version: 19.pre+1272.5cc4683a6
+mtime: 1769684142
+commit: 5cc4683a6ab4f762313e05e8e14cd9deea4ab46a
 

Reply via email to