@genesislcap/blank-app-seed 5.28.1 → 5.29.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.
@@ -14,5 +14,6 @@
14
14
  "key",
15
15
  "inputs",
16
16
  "effects"
17
- ]
17
+ ],
18
+ "shapes": ["row", "key-row"]
18
19
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/blank-app-seed-config",
3
3
  "description": "Genesis Blank App Seed Configuration",
4
- "version": "5.28.1",
4
+ "version": "5.29.0",
5
5
  "license": "Apache-2.0",
6
6
  "scripts": {
7
7
  "lint": "eslint .",
@@ -6,6 +6,11 @@
6
6
  //
7
7
  // baseline ⊆ declaration ⊆ GENESIS_AI_CONSUMES, for the kinds and for the resource fields.
8
8
  //
9
+ // `shapes`, the row-action shapes, is optional on both sides and absent means ["row"]: every
10
+ // assistant that reads `shape` runs a row, and only one that lists more runs more. A declared shape
11
+ // the installed assistant does not run fails the check, so key-row cannot be declared ahead of the
12
+ // assistant pin that runs it.
13
+ //
9
14
  // An assistant with no `./genesis/consumes` entry (before the release that added it) reads the
10
15
  // baseline only, so the declaration must then BE the baseline. Absent means exactly Node's
11
16
  // ERR_PACKAGE_PATH_NOT_EXPORTED for that subpath, when resolving it: the package missing, any error
@@ -38,6 +43,7 @@ if (declaration.version !== 1) problems.push(`version is ${declaration.version},
38
43
  for (const part of ['kinds', 'resourceFields']) {
39
44
  if (!listOfNames(declaration[part])) problems.push(`${part} is not a list of names`);
40
45
  }
46
+ if (declaration.shapes !== undefined && !listOfNames(declaration.shapes)) problems.push('shapes is not a list of names');
41
47
 
42
48
  // See the header for why this runs in a child.
43
49
  const SUBPATH = '@genesislcap/ai-assistant/genesis/consumes';
@@ -96,6 +102,9 @@ if (probed && !said.resolve && !said.load && !consumes) {
96
102
  for (const part of consumes ? ['kinds', 'resourceFields'] : []) {
97
103
  if (!listOfNames(consumes[part])) problems.push(`the installed assistant's ${part} is not a list of names`);
98
104
  }
105
+ if (consumes && consumes.shapes !== undefined && !listOfNames(consumes.shapes)) {
106
+ problems.push("the installed assistant's shapes is not a list of names");
107
+ }
99
108
 
100
109
  const missing = (from, within) => from.filter((item) => !within.includes(item));
101
110
  for (const part of ['kinds', 'resourceFields']) {
@@ -112,5 +121,16 @@ for (const part of ['kinds', 'resourceFields']) {
112
121
  }
113
122
  }
114
123
 
124
+ // What it runs: the shapes it lists, or a row when it lists none. Before the export it reads the
125
+ // baseline only, which has no `shape` at all.
126
+ const declaredShapes = listOfNames(declaration.shapes) ? declaration.shapes : [];
127
+ if (consumes) {
128
+ const runs = consumes.shapes === undefined ? ['row'] : listOfNames(consumes.shapes) ? consumes.shapes : [];
129
+ const beyond = missing(declaredShapes, runs);
130
+ if (beyond.length) problems.push(`shapes names ${beyond.join(', ')}, which the installed assistant does not run`);
131
+ } else if (absent && declaredShapes.length) {
132
+ problems.push(`shapes names ${declaredShapes.join(', ')}, and this assistant reads the baseline only`);
133
+ }
134
+
115
135
  problems.forEach((problem) => console.log(` ${problem}`));
116
136
  process.exit(problems.length ? 1 : 0);
@@ -680,6 +680,8 @@ const { spawnSync } = require('child_process');
680
680
  const [work, consumerFile, check] = process.argv.slice(2);
681
681
  const seed = JSON.parse(fs.readFileSync(consumerFile, 'utf8'));
682
682
  const baseline = { version: 1, kinds: ['request', 'event'], resourceFields: ['name', 'kind', 'op', 'context', 'maxRows'] };
683
+ // Spelled out rather than read from the seed, so these cases hold whatever the seed declares.
684
+ const KEY_ROW = ['row', 'key-row'];
683
685
  const app = (name, exports, files = {}) => {
684
686
  const pkg = path.join(work, name, 'node_modules/@genesislcap/ai-assistant');
685
687
  fs.mkdirSync(pkg, { recursive: true });
@@ -689,7 +691,7 @@ const app = (name, exports, files = {}) => {
689
691
  return path.join(work, name);
690
692
  };
691
693
  const reads = app('reads', { '.': './index.js', './genesis/consumes': './consumes.cjs' }, {
692
- 'consumes.cjs': `exports.GENESIS_AI_CONSUMES = ${JSON.stringify({ kinds: seed.kinds, resourceFields: seed.resourceFields })};`,
694
+ 'consumes.cjs': `exports.GENESIS_AI_CONSUMES = ${JSON.stringify({ kinds: seed.kinds, resourceFields: seed.resourceFields, shapes: KEY_ROW })};`,
693
695
  });
694
696
  const before = app('before-the-export', { '.': './index.js' });
695
697
  const noManifest = app('no-package-json', null);
@@ -697,7 +699,12 @@ const none = path.join(work, 'no-assistant');
697
699
  fs.mkdirSync(none, { recursive: true });
698
700
  fs.writeFileSync(path.join(none, 'package.json'), '{"name":"app"}');
699
701
  const exporting = (name, text) => app(name, { './genesis/consumes': './consumes.cjs' }, { 'consumes.cjs': text });
700
- const seedSet = JSON.stringify({ kinds: seed.kinds, resourceFields: seed.resourceFields });
702
+ const seedSet = JSON.stringify({ kinds: seed.kinds, resourceFields: seed.resourceFields, shapes: KEY_ROW });
703
+ // An assistant that reads every kind and field but lists no shapes, as every one before key-row:
704
+ // it runs a row and nothing more.
705
+ const noShapes = exporting('lists-no-shapes', `exports.GENESIS_AI_CONSUMES = ${JSON.stringify({ kinds: seed.kinds, resourceFields: seed.resourceFields })};`);
706
+ const shapesText = exporting('shapes-not-a-list', `exports.GENESIS_AI_CONSUMES = ${JSON.stringify({ kinds: seed.kinds, resourceFields: seed.resourceFields, shapes: 'row,key-row' })};`);
707
+ const { shapes: _shapes, ...unshaped } = seed;
701
708
  const falsy = exporting('exports-false', 'exports.GENESIS_AI_CONSUMES = false;');
702
709
  const aFunction = exporting('exports-a-function', 'exports.GENESIS_AI_CONSUMES = () => ({});');
703
710
  // Its kinds are text that happens to hold the names: only a list counts.
@@ -718,7 +725,7 @@ const unexported = app('imports-unexported', { './genesis/consumes': './consumes
718
725
  'consumes.cjs': 'require("@genesislcap/ai-assistant/hidden");',
719
726
  });
720
727
  const importOnly = app('import-only', { './genesis/consumes': { import: './consumes.mjs' } }, {
721
- 'consumes.mjs': `export const GENESIS_AI_CONSUMES = ${JSON.stringify({ kinds: seed.kinds, resourceFields: seed.resourceFields })};`,
728
+ 'consumes.mjs': `export const GENESIS_AI_CONSUMES = ${seedSet};`,
722
729
  });
723
730
  const declaring = (name, declaration) => {
724
731
  const file = path.join(work, `${name}.json`);
@@ -750,6 +757,15 @@ const cases = [
750
757
  ['the seed, on a module that keeps the process alive', consumerFile, stays, 0],
751
758
  // Required only, it reads as absent: fail-safe, as that assistant is held to the baseline.
752
759
  ['more than the baseline, on an assistant that exports it for require only', declaring('more', { ...baseline, resourceFields: [...baseline.resourceFields, 'customCode'] }), requireOnly, 1],
760
+ // Shapes: absent means a row, on either side.
761
+ ['key-row, on an assistant that runs it', declaring('key-row', { ...seed, shapes: KEY_ROW }), reads, 0],
762
+ ['key-row, on an assistant that lists no shapes', declaring('key-row', { ...seed, shapes: KEY_ROW }), noShapes, 1],
763
+ ['a row, on an assistant that lists no shapes', declaring('row', { ...seed, shapes: ['row'] }), noShapes, 0],
764
+ ['no shapes, on an assistant that lists none', declaring('unshaped', unshaped), noShapes, 0],
765
+ ['a shape the assistant does not run', declaring('wide', { ...seed, shapes: [...KEY_ROW, 'wide-row'] }), reads, 1],
766
+ ['shapes that are not a list', declaring('shapes-text', { ...seed, shapes: 'row,key-row' }), reads, 1],
767
+ ["no shapes, on an assistant whose shapes are not a list", declaring('unshaped', unshaped), shapesText, 1],
768
+ ['a shape, before the export', declaring('shape-early', { ...baseline, shapes: ['row'] }), before, 1],
753
769
  ];
754
770
  let wrong = 0;
755
771
  for (const [name, declaration, client, want] of cases) {
@@ -759,6 +775,7 @@ for (const [name, declaration, client, want] of cases) {
759
775
  console.log(` ${name}: exit ${run.status}, not ${want}${run.stdout ? `\n${run.stdout}` : ''}${run.stderr}`);
760
776
  }
761
777
  }
778
+ console.log(` ${cases.length - wrong} / ${cases.length} cases as expected`);
762
779
  process.exit(wrong ? 1 : 0);
763
780
  NODE
764
781
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "UI": "15.50.2",
2
+ "UI": "15.54.0",
3
3
  "GSF": "8.15.14",
4
4
  "Auth": "8.15.3"
5
5
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [5.29.0](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v5.28.1...v5.29.0) (2026-10-07)
4
+
5
+
6
+ ### Features
7
+
8
+ * check the declared row-action shapes against the installed assistant GENC-1611 d53350c
9
+ * declare that the seed's assistant runs key-row actions GENC-1611 02a2ab8
10
+ * let the AI chat run key-only handlers as key-row actions GENC-1611 (#645) bcd9d57
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * pin ag-grid-community 36.2.0 in a React app, the version FUI 15.54.0 peers on GENC-1611 9e7d56e
16
+ * update FUI version to 15.54.0, which runs key-row actions GENC-1611 8841afb
17
+
3
18
  ## [5.28.1](https://github.com/genesiscommunitysuccess/blank-app-seed/compare/v5.28.0...v5.28.1) (2026-10-05)
4
19
 
5
20
 
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "dependencies": {
58
58
  "@microsoft/fast-react-wrapper": ">=0.3.25",
59
- "ag-grid-community": "36.0.0",
59
+ "ag-grid-community": "36.2.0",
60
60
  "@genesislcap/ai-assistant": "{{versions.UI}}",
61
61
  "@genesislcap/foundation-auth": "{{versions.UI}}",
62
62
  "@genesislcap/foundation-comms": "{{versions.UI}}",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@genesislcap/blank-app-seed",
3
3
  "description": "Genesis Blank App Seed",
4
- "version": "5.28.1",
4
+ "version": "5.29.0",
5
5
  "license": "Apache-2.0",
6
6
  "scripts": {
7
7
  "release": "semantic-release"