@mamund/grail 0.0.0-stage → 0.1.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.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +328 -2
  3. package/affordanceModel.js +23 -0
  4. package/affordanceRegistry.js +14 -0
  5. package/bindings/binding.js +229 -0
  6. package/bindings/httpBinding.js +173 -0
  7. package/bindings/nodeBinding.js +25 -0
  8. package/bindings/stdioBinding.js +58 -0
  9. package/cli/grail-cli.js +565 -0
  10. package/client.js +77 -0
  11. package/config-loader/loadEnvironment.js +71 -0
  12. package/docs/ENVIRONMENT.md +381 -0
  13. package/docs/grail-trust-model.md +665 -0
  14. package/examples/cli-tour/README.md +346 -0
  15. package/examples/cli-tour/capabilities/farewell.js +3 -0
  16. package/examples/cli-tour/capabilities/hello.js +3 -0
  17. package/examples/cli-tour/config/goal.json +3 -0
  18. package/examples/cli-tour/config/inputs.json +3 -0
  19. package/examples/cli-tour/config/observations.json +23 -0
  20. package/examples/cli-tour/config/registry.json +48 -0
  21. package/examples/cli-tour/config/worldstate.json +4 -0
  22. package/examples/cli-tour/g-loop.sh +7 -0
  23. package/examples/cli-tour/inputs/jane.json +3 -0
  24. package/examples/cli-tour/inputs/mike.json +3 -0
  25. package/examples/cli-tour/inputs/ruth.json +3 -0
  26. package/grail.js +59 -0
  27. package/images/grail-release-banner.png +0 -0
  28. package/index.js +2 -0
  29. package/observationStore.js +110 -0
  30. package/package.json +57 -4
  31. package/schemas/goal.schema.json +14 -0
  32. package/schemas/inputs.schema.json +6 -0
  33. package/schemas/observations.schema.json +75 -0
  34. package/schemas/registry.schema.json +285 -0
  35. package/schemas/worldstate.schema.json +7 -0
  36. package/server.js +201 -0
  37. package/utils/loadJSON.js +33 -0
  38. package/utils/validateWithSchema.js +42 -0
  39. package/worldState.js +36 -0
@@ -0,0 +1,42 @@
1
+ // utils/validateWithSchema.js
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import Ajv2020 from 'ajv/dist/2020.js';
6
+ import addFormats from 'ajv-formats';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+
11
+ const ajv = new Ajv2020({ allErrors: true });
12
+ addFormats(ajv);
13
+
14
+ function loadSchema(schemaName) {
15
+ const schemaPath = path.join(__dirname, '../schemas', schemaName);
16
+ const raw = fs.readFileSync(schemaPath, 'utf8');
17
+ return JSON.parse(raw);
18
+ }
19
+
20
+ export function validateConfig(
21
+ data,
22
+ schemaName,
23
+ label = 'config',
24
+ { silent = false } = {}
25
+ ) {
26
+ const schema = loadSchema(schemaName);
27
+ const validate = ajv.compile(schema);
28
+ const valid = validate(data);
29
+
30
+ if (!valid) {
31
+ if (!silent) {
32
+ console.error(`❌ Validation failed for ${label}:`);
33
+ console.error(validate.errors);
34
+ }
35
+
36
+ const error = new Error(`Invalid ${label} file`);
37
+ error.validationErrors = validate.errors;
38
+ throw error;
39
+ }
40
+
41
+ return true;
42
+ }
package/worldState.js ADDED
@@ -0,0 +1,36 @@
1
+ // worldState.js (now applies external worldstate.json overrides)
2
+
3
+ export class WorldState {
4
+ constructor(affordanceRegistry, worldStateFilePath) {
5
+ this.state = this.buildInitialState(affordanceRegistry, worldStateFilePath);
6
+ }
7
+
8
+ buildInitialState(registry, worldState) {
9
+ const allKeys = new Set();
10
+ for (let key in registry) {
11
+ const aff = registry[key];
12
+ aff.preconditions.forEach(pre => allKeys.add(pre));
13
+ aff.effects.forEach(eff => allKeys.add(eff));
14
+ }
15
+ const state = {};
16
+ allKeys.forEach(k => state[k] = false);
17
+
18
+ for (let key in worldState) {
19
+ if (key in state) {
20
+ state[key] = worldState[key];
21
+ }
22
+ }
23
+ return state;
24
+ }
25
+
26
+ applyEffects(effects) {
27
+ for (let effect of effects) {
28
+ this.state[effect] = true;
29
+ }
30
+ }
31
+
32
+ isPreconditionMet(precondition) {
33
+ return this.state[precondition] === true;
34
+ }
35
+ }
36
+