@antglobal/copilot-cards-core 0.0.20260806095059-dev.1 → 0.0.20260811080429-dev.5

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.cjs CHANGED
@@ -1937,6 +1937,7 @@ function validateSchema(input) {
1937
1937
  }
1938
1938
  const REPEAT_SLOT_LAYOUTS = new Set([
1939
1939
  'default',
1940
+ 'flex',
1940
1941
  'list',
1941
1942
  'grid',
1942
1943
  'horizontalScroll',
@@ -2050,11 +2051,15 @@ function readRepeatBindingFields(value) {
2050
2051
  const template = readOwnData(value, 'template');
2051
2052
  const item = readOwnData(value, 'item');
2052
2053
  const index = readOwnData(value, 'index');
2054
+ const emptyTemplate = readOwnData(value, 'emptyTemplate');
2053
2055
  return {
2054
2056
  source: source.kind === 'value' ? source.value : undefined,
2055
2057
  template: template.kind === 'value' ? template.value : undefined,
2056
- item: item.kind === 'value' ? item.value : undefined,
2058
+ ...(item.kind === 'value' ? { item: item.value } : {}),
2057
2059
  ...(index.kind === 'value' ? { index: index.value } : {}),
2060
+ ...(emptyTemplate.kind === 'value'
2061
+ ? { emptyTemplate: emptyTemplate.value }
2062
+ : {}),
2058
2063
  };
2059
2064
  }
2060
2065
  function slotStaticReferences(slot) {
@@ -2179,6 +2184,10 @@ function elementReferences(element) {
2179
2184
  if (typeof binding?.template === 'string' && binding.template) {
2180
2185
  references.push(binding.template);
2181
2186
  }
2187
+ if (typeof binding?.emptyTemplate === 'string'
2188
+ && binding.emptyTemplate) {
2189
+ references.push(binding.emptyTemplate);
2190
+ }
2182
2191
  const a2ui = getA2UIChildBinding(slot);
2183
2192
  if (typeof a2ui?.templateId === 'string' && a2ui.templateId) {
2184
2193
  references.push(a2ui.templateId);
@@ -2257,13 +2266,27 @@ function validateRepeatBindings(schema, errors) {
2257
2266
  else if (!getOwnElement(schema, binding.template)) {
2258
2267
  errors.push(`Element "${id}" slot "${slotName}" repeat references unknown template "${binding.template}"`);
2259
2268
  }
2260
- validateAlias(id, slotName, 'item', binding.item, errors);
2269
+ if (binding.item !== undefined) {
2270
+ validateAlias(id, slotName, 'item', binding.item, errors);
2271
+ }
2261
2272
  if (binding.index !== undefined) {
2262
2273
  validateAlias(id, slotName, 'index', binding.index, errors);
2263
2274
  }
2264
- if (binding.index !== undefined && binding.item === binding.index) {
2275
+ if (binding.index !== undefined
2276
+ && (binding.item ?? '$item') === binding.index) {
2265
2277
  errors.push(`Element "${id}" slot "${slotName}" repeat item and index aliases must be different`);
2266
2278
  }
2279
+ if (binding.emptyTemplate !== undefined) {
2280
+ if (typeof binding.emptyTemplate !== 'string') {
2281
+ errors.push(`Element "${id}" slot "${slotName}" repeat emptyTemplate must be a string`);
2282
+ }
2283
+ else if (!binding.emptyTemplate) {
2284
+ errors.push(`Element "${id}" slot "${slotName}" repeat emptyTemplate must be a non-empty string`);
2285
+ }
2286
+ else if (!getOwnElement(schema, binding.emptyTemplate)) {
2287
+ errors.push(`Element "${id}" slot "${slotName}" repeat references unknown empty template "${binding.emptyTemplate}"`);
2288
+ }
2289
+ }
2267
2290
  }
2268
2291
  }
2269
2292
  validateRepeatNesting(schema, dynamicBindings, errors);
@@ -2283,6 +2306,17 @@ function validateAlias(owner, slotName, kind, alias, errors) {
2283
2306
  function validateRepeatNesting(schema, bindings, errors) {
2284
2307
  const reportedCycles = new Set();
2285
2308
  const reportedCollisions = new Set();
2309
+ function effectiveAliases(binding) {
2310
+ if (!binding)
2311
+ return [];
2312
+ if (binding.item !== undefined) {
2313
+ return [binding.item, binding.index].filter((alias) => typeof alias === 'string');
2314
+ }
2315
+ return [
2316
+ '$item',
2317
+ binding.index === undefined ? '$index' : binding.index,
2318
+ ].filter((alias) => typeof alias === 'string');
2319
+ }
2286
2320
  function visitElement(id, activeAliases, repeatPath, visitedStatic) {
2287
2321
  const element = getOwnElement(schema, id);
2288
2322
  if (!element || visitedStatic.has(id))
@@ -2297,8 +2331,10 @@ function validateRepeatNesting(schema, bindings, errors) {
2297
2331
  ? readRepeatBindingFields(repeat.value)
2298
2332
  : undefined;
2299
2333
  const a2uiBinding = getA2UIChildBinding(slot);
2300
- const template = nativeBinding?.template ?? a2uiBinding?.templateId;
2301
- if (typeof template === 'string' && template) {
2334
+ const itemTemplate = nativeBinding?.template ?? a2uiBinding?.templateId;
2335
+ const visitDynamicTemplate = (template, aliases) => {
2336
+ if (!template)
2337
+ return;
2302
2338
  const cycleAt = repeatPath.indexOf(template);
2303
2339
  if (cycleAt >= 0) {
2304
2340
  const cycle = [...repeatPath.slice(cycleAt), template].join(' -> ');
@@ -2308,9 +2344,8 @@ function validateRepeatNesting(schema, bindings, errors) {
2308
2344
  ? `Element "${id}" slot "${slotName}" has repeat template cycle: ${cycle}`
2309
2345
  : `Element "${id}" slot "${slotName}" has dynamic template cycle: ${cycle}`);
2310
2346
  }
2311
- continue;
2347
+ return;
2312
2348
  }
2313
- const aliases = [nativeBinding?.item, nativeBinding?.index].filter((alias) => typeof alias === 'string');
2314
2349
  for (const alias of aliases) {
2315
2350
  if (activeAliases.has(alias)) {
2316
2351
  const key = `${id}:${slotName}:${alias}`;
@@ -2324,7 +2359,9 @@ function validateRepeatNesting(schema, bindings, errors) {
2324
2359
  for (const alias of aliases)
2325
2360
  nestedAliases.add(alias);
2326
2361
  visitElement(template, nestedAliases, [...repeatPath, template], new Set());
2327
- }
2362
+ };
2363
+ visitDynamicTemplate(itemTemplate, effectiveAliases(nativeBinding));
2364
+ visitDynamicTemplate(nativeBinding?.emptyTemplate, []);
2328
2365
  for (const child of slotStaticReferences(slot)) {
2329
2366
  visitElement(child, activeAliases, repeatPath, nextVisitedStatic);
2330
2367
  }
@@ -2332,10 +2369,14 @@ function validateRepeatNesting(schema, bindings, errors) {
2332
2369
  }
2333
2370
  for (const dynamic of bindings) {
2334
2371
  const { owner, binding, template } = dynamic;
2335
- const aliases = new Set([binding?.item, binding?.index].filter((alias) => typeof alias === 'string'));
2372
+ const aliases = new Set(effectiveAliases(binding));
2336
2373
  if (typeof template === 'string' && template) {
2337
2374
  visitElement(template, aliases, [owner, template], new Set());
2338
2375
  }
2376
+ if (typeof binding?.emptyTemplate === 'string'
2377
+ && binding.emptyTemplate) {
2378
+ visitElement(binding.emptyTemplate, new Set(), [owner, binding.emptyTemplate], new Set());
2379
+ }
2339
2380
  }
2340
2381
  }
2341
2382
  function validateDynamicClosures(schema, repeats, errors) {
@@ -2882,6 +2923,7 @@ function materializeCard(input, variables, options = {}) {
2882
2923
  template: native.template,
2883
2924
  item: native.item,
2884
2925
  index: native.index,
2926
+ emptyTemplate: native.emptyTemplate,
2885
2927
  };
2886
2928
  }
2887
2929
  else {
@@ -2909,6 +2951,9 @@ function materializeCard(input, variables, options = {}) {
2909
2951
  sourceOwnerId: sourceId,
2910
2952
  slot: slotName,
2911
2953
  templateId: binding.template,
2954
+ ...(binding.emptyTemplate
2955
+ ? { emptyTemplateId: binding.emptyTemplate }
2956
+ : {}),
2912
2957
  ...(sourcePath === undefined ? {} : { sourcePath }),
2913
2958
  dataPath: activeScope.dataPath,
2914
2959
  instancePath,
@@ -2920,6 +2965,9 @@ function materializeCard(input, variables, options = {}) {
2920
2965
  repeatOwners.set(ownerKey, owner);
2921
2966
  slotOwners.set(slotName, { owner, binding, sourcePath, depth });
2922
2967
  addDependency('component', binding.template, ownerKey);
2968
+ if (binding.emptyTemplate) {
2969
+ addDependency('component', binding.emptyTemplate, ownerKey);
2970
+ }
2923
2971
  const runtimeKeys = runtimeOwnerKeys.get(id) ?? [];
2924
2972
  if (runtimeKeys.length > 0) {
2925
2973
  for (const key of runtimeKeys)
@@ -3000,15 +3048,30 @@ function materializeCard(input, variables, options = {}) {
3000
3048
  Reflect.deleteProperty(slot, 'repeat');
3001
3049
  Reflect.deleteProperty(slot, A2UI_CHILD_BINDING);
3002
3050
  slot.children = [];
3051
+ if (items.length === 0
3052
+ && binding.dialect === 'native'
3053
+ && binding.emptyTemplate) {
3054
+ const emptyPath = appendOccurrence(structuralPath, 'item', sourceId, slotName, `${binding.emptyTemplate}:empty`);
3055
+ const empty = buildNode(binding.emptyTemplate, activeScope, emptyPath, emptyPath, true, id, depth, owner.key, nextActiveDefinitions);
3056
+ slot.children.push(empty.id);
3057
+ node.children.push(empty);
3058
+ }
3003
3059
  items.forEach((item, index) => {
3004
3060
  const dataPath = sourcePath === undefined
3005
3061
  ? activeScope.dataPath
3006
3062
  : joinPointer(sourcePath, [String(index)]);
3007
- const locals = binding.dialect === 'native' && binding.item
3008
- ? {
3009
- [binding.item]: item,
3010
- ...(binding.index ? { [binding.index]: index } : {}),
3011
- }
3063
+ const locals = binding.dialect === 'native'
3064
+ ? binding.item !== undefined
3065
+ ? {
3066
+ [binding.item]: item,
3067
+ ...(binding.index === undefined
3068
+ ? {}
3069
+ : { [binding.index]: index }),
3070
+ }
3071
+ : {
3072
+ $item: item,
3073
+ [binding.index ?? '$index']: index,
3074
+ }
3012
3075
  : {};
3013
3076
  const childScope = {
3014
3077
  root: rootVariables,
@@ -3018,14 +3081,23 @@ function materializeCard(input, variables, options = {}) {
3018
3081
  bindingDialect: binding.dialect,
3019
3082
  };
3020
3083
  const aliases = new Map();
3021
- if (binding.dialect === 'native' && binding.item) {
3022
- aliases.set(binding.item, sourcePath === undefined ? undefined : dataPath);
3023
- if (binding.index)
3024
- aliases.set(binding.index, sourcePath);
3084
+ if (binding.dialect === 'native') {
3085
+ const itemAlias = binding.item ?? '$item';
3086
+ const indexAlias = binding.item === undefined
3087
+ ? binding.index ?? '$index'
3088
+ : binding.index;
3089
+ aliases.set(itemAlias, sourcePath === undefined ? undefined : dataPath);
3090
+ if (indexAlias !== undefined) {
3091
+ aliases.set(indexAlias, sourcePath);
3092
+ }
3025
3093
  }
3026
3094
  scopeAliasPaths.set(childScope, aliases);
3027
- scopeIndexAliases.set(childScope, new Set(binding.dialect === 'native' && binding.index
3028
- ? [binding.index]
3095
+ scopeIndexAliases.set(childScope, new Set(binding.dialect === 'native'
3096
+ ? binding.item === undefined
3097
+ ? [binding.index ?? '$index']
3098
+ : binding.index === undefined
3099
+ ? []
3100
+ : [binding.index]
3029
3101
  : []));
3030
3102
  const itemPath = appendOccurrence(structuralPath, 'item', sourceId, slotName, `${binding.template}:${index}`);
3031
3103
  const child = buildNode(binding.template, childScope, itemPath, itemPath, true, id, depth, owner.key, nextActiveDefinitions);
package/dist/index.d.ts CHANGED
@@ -151,6 +151,7 @@ interface ExpressionValue {
151
151
  /**
152
152
  * Slot layout mode — the key name in `props.slots` determines the layout:
153
153
  * - default: no special layout, children appended directly
154
+ * - flex: one-dimensional Flexbox layout applied to the host container
154
155
  * - columns: multi-column layout using groups (each group = one column)
155
156
  * - grid: CSS grid with configurable column count and gap
156
157
  * - horizontalScroll: horizontal scrollable container with drag and snap
@@ -158,13 +159,14 @@ interface ExpressionValue {
158
159
  * - list: vertical list with optional ordered/unordered markers
159
160
  * - float: relative container with absolutely positioned overlays
160
161
  */
161
- type SlotLayout = 'default' | 'columns' | 'grid' | 'horizontalScroll' | 'carousel' | 'list' | 'float' | 'keyValue' | 'table' | 'chart';
162
+ type SlotLayout = 'default' | 'flex' | 'columns' | 'grid' | 'horizontalScroll' | 'carousel' | 'list' | 'float' | 'keyValue' | 'table' | 'chart';
162
163
  /** Binds a slot to a template that is instantiated once per source item. */
163
164
  interface RepeatBinding {
164
165
  source: string;
165
166
  template: string;
166
- item: string;
167
+ item?: string;
167
168
  index?: string;
169
+ emptyTemplate?: string;
168
170
  }
169
171
  /**
170
172
  * Content of a named slot.
@@ -468,6 +470,7 @@ interface RepeatOwner {
468
470
  sourceOwnerId: string;
469
471
  slot: SlotLayout;
470
472
  templateId: string;
473
+ emptyTemplateId?: string;
471
474
  sourcePath?: string;
472
475
  dataPath: string;
473
476
  instancePath: string;
package/dist/index.js CHANGED
@@ -1935,6 +1935,7 @@ function validateSchema(input) {
1935
1935
  }
1936
1936
  const REPEAT_SLOT_LAYOUTS = new Set([
1937
1937
  'default',
1938
+ 'flex',
1938
1939
  'list',
1939
1940
  'grid',
1940
1941
  'horizontalScroll',
@@ -2048,11 +2049,15 @@ function readRepeatBindingFields(value) {
2048
2049
  const template = readOwnData(value, 'template');
2049
2050
  const item = readOwnData(value, 'item');
2050
2051
  const index = readOwnData(value, 'index');
2052
+ const emptyTemplate = readOwnData(value, 'emptyTemplate');
2051
2053
  return {
2052
2054
  source: source.kind === 'value' ? source.value : undefined,
2053
2055
  template: template.kind === 'value' ? template.value : undefined,
2054
- item: item.kind === 'value' ? item.value : undefined,
2056
+ ...(item.kind === 'value' ? { item: item.value } : {}),
2055
2057
  ...(index.kind === 'value' ? { index: index.value } : {}),
2058
+ ...(emptyTemplate.kind === 'value'
2059
+ ? { emptyTemplate: emptyTemplate.value }
2060
+ : {}),
2056
2061
  };
2057
2062
  }
2058
2063
  function slotStaticReferences(slot) {
@@ -2177,6 +2182,10 @@ function elementReferences(element) {
2177
2182
  if (typeof binding?.template === 'string' && binding.template) {
2178
2183
  references.push(binding.template);
2179
2184
  }
2185
+ if (typeof binding?.emptyTemplate === 'string'
2186
+ && binding.emptyTemplate) {
2187
+ references.push(binding.emptyTemplate);
2188
+ }
2180
2189
  const a2ui = getA2UIChildBinding(slot);
2181
2190
  if (typeof a2ui?.templateId === 'string' && a2ui.templateId) {
2182
2191
  references.push(a2ui.templateId);
@@ -2255,13 +2264,27 @@ function validateRepeatBindings(schema, errors) {
2255
2264
  else if (!getOwnElement(schema, binding.template)) {
2256
2265
  errors.push(`Element "${id}" slot "${slotName}" repeat references unknown template "${binding.template}"`);
2257
2266
  }
2258
- validateAlias(id, slotName, 'item', binding.item, errors);
2267
+ if (binding.item !== undefined) {
2268
+ validateAlias(id, slotName, 'item', binding.item, errors);
2269
+ }
2259
2270
  if (binding.index !== undefined) {
2260
2271
  validateAlias(id, slotName, 'index', binding.index, errors);
2261
2272
  }
2262
- if (binding.index !== undefined && binding.item === binding.index) {
2273
+ if (binding.index !== undefined
2274
+ && (binding.item ?? '$item') === binding.index) {
2263
2275
  errors.push(`Element "${id}" slot "${slotName}" repeat item and index aliases must be different`);
2264
2276
  }
2277
+ if (binding.emptyTemplate !== undefined) {
2278
+ if (typeof binding.emptyTemplate !== 'string') {
2279
+ errors.push(`Element "${id}" slot "${slotName}" repeat emptyTemplate must be a string`);
2280
+ }
2281
+ else if (!binding.emptyTemplate) {
2282
+ errors.push(`Element "${id}" slot "${slotName}" repeat emptyTemplate must be a non-empty string`);
2283
+ }
2284
+ else if (!getOwnElement(schema, binding.emptyTemplate)) {
2285
+ errors.push(`Element "${id}" slot "${slotName}" repeat references unknown empty template "${binding.emptyTemplate}"`);
2286
+ }
2287
+ }
2265
2288
  }
2266
2289
  }
2267
2290
  validateRepeatNesting(schema, dynamicBindings, errors);
@@ -2281,6 +2304,17 @@ function validateAlias(owner, slotName, kind, alias, errors) {
2281
2304
  function validateRepeatNesting(schema, bindings, errors) {
2282
2305
  const reportedCycles = new Set();
2283
2306
  const reportedCollisions = new Set();
2307
+ function effectiveAliases(binding) {
2308
+ if (!binding)
2309
+ return [];
2310
+ if (binding.item !== undefined) {
2311
+ return [binding.item, binding.index].filter((alias) => typeof alias === 'string');
2312
+ }
2313
+ return [
2314
+ '$item',
2315
+ binding.index === undefined ? '$index' : binding.index,
2316
+ ].filter((alias) => typeof alias === 'string');
2317
+ }
2284
2318
  function visitElement(id, activeAliases, repeatPath, visitedStatic) {
2285
2319
  const element = getOwnElement(schema, id);
2286
2320
  if (!element || visitedStatic.has(id))
@@ -2295,8 +2329,10 @@ function validateRepeatNesting(schema, bindings, errors) {
2295
2329
  ? readRepeatBindingFields(repeat.value)
2296
2330
  : undefined;
2297
2331
  const a2uiBinding = getA2UIChildBinding(slot);
2298
- const template = nativeBinding?.template ?? a2uiBinding?.templateId;
2299
- if (typeof template === 'string' && template) {
2332
+ const itemTemplate = nativeBinding?.template ?? a2uiBinding?.templateId;
2333
+ const visitDynamicTemplate = (template, aliases) => {
2334
+ if (!template)
2335
+ return;
2300
2336
  const cycleAt = repeatPath.indexOf(template);
2301
2337
  if (cycleAt >= 0) {
2302
2338
  const cycle = [...repeatPath.slice(cycleAt), template].join(' -> ');
@@ -2306,9 +2342,8 @@ function validateRepeatNesting(schema, bindings, errors) {
2306
2342
  ? `Element "${id}" slot "${slotName}" has repeat template cycle: ${cycle}`
2307
2343
  : `Element "${id}" slot "${slotName}" has dynamic template cycle: ${cycle}`);
2308
2344
  }
2309
- continue;
2345
+ return;
2310
2346
  }
2311
- const aliases = [nativeBinding?.item, nativeBinding?.index].filter((alias) => typeof alias === 'string');
2312
2347
  for (const alias of aliases) {
2313
2348
  if (activeAliases.has(alias)) {
2314
2349
  const key = `${id}:${slotName}:${alias}`;
@@ -2322,7 +2357,9 @@ function validateRepeatNesting(schema, bindings, errors) {
2322
2357
  for (const alias of aliases)
2323
2358
  nestedAliases.add(alias);
2324
2359
  visitElement(template, nestedAliases, [...repeatPath, template], new Set());
2325
- }
2360
+ };
2361
+ visitDynamicTemplate(itemTemplate, effectiveAliases(nativeBinding));
2362
+ visitDynamicTemplate(nativeBinding?.emptyTemplate, []);
2326
2363
  for (const child of slotStaticReferences(slot)) {
2327
2364
  visitElement(child, activeAliases, repeatPath, nextVisitedStatic);
2328
2365
  }
@@ -2330,10 +2367,14 @@ function validateRepeatNesting(schema, bindings, errors) {
2330
2367
  }
2331
2368
  for (const dynamic of bindings) {
2332
2369
  const { owner, binding, template } = dynamic;
2333
- const aliases = new Set([binding?.item, binding?.index].filter((alias) => typeof alias === 'string'));
2370
+ const aliases = new Set(effectiveAliases(binding));
2334
2371
  if (typeof template === 'string' && template) {
2335
2372
  visitElement(template, aliases, [owner, template], new Set());
2336
2373
  }
2374
+ if (typeof binding?.emptyTemplate === 'string'
2375
+ && binding.emptyTemplate) {
2376
+ visitElement(binding.emptyTemplate, new Set(), [owner, binding.emptyTemplate], new Set());
2377
+ }
2337
2378
  }
2338
2379
  }
2339
2380
  function validateDynamicClosures(schema, repeats, errors) {
@@ -2880,6 +2921,7 @@ function materializeCard(input, variables, options = {}) {
2880
2921
  template: native.template,
2881
2922
  item: native.item,
2882
2923
  index: native.index,
2924
+ emptyTemplate: native.emptyTemplate,
2883
2925
  };
2884
2926
  }
2885
2927
  else {
@@ -2907,6 +2949,9 @@ function materializeCard(input, variables, options = {}) {
2907
2949
  sourceOwnerId: sourceId,
2908
2950
  slot: slotName,
2909
2951
  templateId: binding.template,
2952
+ ...(binding.emptyTemplate
2953
+ ? { emptyTemplateId: binding.emptyTemplate }
2954
+ : {}),
2910
2955
  ...(sourcePath === undefined ? {} : { sourcePath }),
2911
2956
  dataPath: activeScope.dataPath,
2912
2957
  instancePath,
@@ -2918,6 +2963,9 @@ function materializeCard(input, variables, options = {}) {
2918
2963
  repeatOwners.set(ownerKey, owner);
2919
2964
  slotOwners.set(slotName, { owner, binding, sourcePath, depth });
2920
2965
  addDependency('component', binding.template, ownerKey);
2966
+ if (binding.emptyTemplate) {
2967
+ addDependency('component', binding.emptyTemplate, ownerKey);
2968
+ }
2921
2969
  const runtimeKeys = runtimeOwnerKeys.get(id) ?? [];
2922
2970
  if (runtimeKeys.length > 0) {
2923
2971
  for (const key of runtimeKeys)
@@ -2998,15 +3046,30 @@ function materializeCard(input, variables, options = {}) {
2998
3046
  Reflect.deleteProperty(slot, 'repeat');
2999
3047
  Reflect.deleteProperty(slot, A2UI_CHILD_BINDING);
3000
3048
  slot.children = [];
3049
+ if (items.length === 0
3050
+ && binding.dialect === 'native'
3051
+ && binding.emptyTemplate) {
3052
+ const emptyPath = appendOccurrence(structuralPath, 'item', sourceId, slotName, `${binding.emptyTemplate}:empty`);
3053
+ const empty = buildNode(binding.emptyTemplate, activeScope, emptyPath, emptyPath, true, id, depth, owner.key, nextActiveDefinitions);
3054
+ slot.children.push(empty.id);
3055
+ node.children.push(empty);
3056
+ }
3001
3057
  items.forEach((item, index) => {
3002
3058
  const dataPath = sourcePath === undefined
3003
3059
  ? activeScope.dataPath
3004
3060
  : joinPointer(sourcePath, [String(index)]);
3005
- const locals = binding.dialect === 'native' && binding.item
3006
- ? {
3007
- [binding.item]: item,
3008
- ...(binding.index ? { [binding.index]: index } : {}),
3009
- }
3061
+ const locals = binding.dialect === 'native'
3062
+ ? binding.item !== undefined
3063
+ ? {
3064
+ [binding.item]: item,
3065
+ ...(binding.index === undefined
3066
+ ? {}
3067
+ : { [binding.index]: index }),
3068
+ }
3069
+ : {
3070
+ $item: item,
3071
+ [binding.index ?? '$index']: index,
3072
+ }
3010
3073
  : {};
3011
3074
  const childScope = {
3012
3075
  root: rootVariables,
@@ -3016,14 +3079,23 @@ function materializeCard(input, variables, options = {}) {
3016
3079
  bindingDialect: binding.dialect,
3017
3080
  };
3018
3081
  const aliases = new Map();
3019
- if (binding.dialect === 'native' && binding.item) {
3020
- aliases.set(binding.item, sourcePath === undefined ? undefined : dataPath);
3021
- if (binding.index)
3022
- aliases.set(binding.index, sourcePath);
3082
+ if (binding.dialect === 'native') {
3083
+ const itemAlias = binding.item ?? '$item';
3084
+ const indexAlias = binding.item === undefined
3085
+ ? binding.index ?? '$index'
3086
+ : binding.index;
3087
+ aliases.set(itemAlias, sourcePath === undefined ? undefined : dataPath);
3088
+ if (indexAlias !== undefined) {
3089
+ aliases.set(indexAlias, sourcePath);
3090
+ }
3023
3091
  }
3024
3092
  scopeAliasPaths.set(childScope, aliases);
3025
- scopeIndexAliases.set(childScope, new Set(binding.dialect === 'native' && binding.index
3026
- ? [binding.index]
3093
+ scopeIndexAliases.set(childScope, new Set(binding.dialect === 'native'
3094
+ ? binding.item === undefined
3095
+ ? [binding.index ?? '$index']
3096
+ : binding.index === undefined
3097
+ ? []
3098
+ : [binding.index]
3027
3099
  : []));
3028
3100
  const itemPath = appendOccurrence(structuralPath, 'item', sourceId, slotName, `${binding.template}:${index}`);
3029
3101
  const child = buildNode(binding.template, childScope, itemPath, itemPath, true, id, depth, owner.key, nextActiveDefinitions);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antglobal/copilot-cards-core",
3
- "version": "0.0.20260806095059-dev.1",
3
+ "version": "0.0.20260811080429-dev.5",
4
4
  "description": "Core logic engine for copilot bot card SDK — no UI, pure logic (Expression Engine, Action Runner, Schema Parser, Lifecycle Manager)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",