@neurodock/core 0.0.1 → 0.2.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 (57) hide show
  1. package/LICENSE +657 -7
  2. package/README.md +50 -3
  3. package/data/neurotype-addenda/v1.json +389 -0
  4. package/dist/index.d.ts +5 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +7 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/index.test.d.ts +2 -0
  9. package/dist/index.test.d.ts.map +1 -0
  10. package/dist/index.test.js +29 -0
  11. package/dist/index.test.js.map +1 -0
  12. package/dist/neurotype-addenda.d.ts +91 -0
  13. package/dist/neurotype-addenda.d.ts.map +1 -0
  14. package/dist/neurotype-addenda.js +175 -0
  15. package/dist/neurotype-addenda.js.map +1 -0
  16. package/dist/neurotype-addenda.parity.test.d.ts +2 -0
  17. package/dist/neurotype-addenda.parity.test.d.ts.map +1 -0
  18. package/dist/neurotype-addenda.parity.test.js +69 -0
  19. package/dist/neurotype-addenda.parity.test.js.map +1 -0
  20. package/dist/neurotype-addenda.schema.test.d.ts +2 -0
  21. package/dist/neurotype-addenda.schema.test.d.ts.map +1 -0
  22. package/dist/neurotype-addenda.schema.test.js +83 -0
  23. package/dist/neurotype-addenda.schema.test.js.map +1 -0
  24. package/dist/neurotype-addenda.test.d.ts +2 -0
  25. package/dist/neurotype-addenda.test.d.ts.map +1 -0
  26. package/dist/neurotype-addenda.test.js +165 -0
  27. package/dist/neurotype-addenda.test.js.map +1 -0
  28. package/dist/profile.d.ts +128 -0
  29. package/dist/profile.d.ts.map +1 -0
  30. package/dist/profile.js +27 -0
  31. package/dist/profile.js.map +1 -0
  32. package/dist/profile.presets.test.d.ts +2 -0
  33. package/dist/profile.presets.test.d.ts.map +1 -0
  34. package/dist/profile.presets.test.js +43 -0
  35. package/dist/profile.presets.test.js.map +1 -0
  36. package/dist/profile.schema.test.d.ts +2 -0
  37. package/dist/profile.schema.test.d.ts.map +1 -0
  38. package/dist/profile.schema.test.js +282 -0
  39. package/dist/profile.schema.test.js.map +1 -0
  40. package/dist/profile.test.d.ts +2 -0
  41. package/dist/profile.test.d.ts.map +1 -0
  42. package/dist/profile.test.js +60 -0
  43. package/dist/profile.test.js.map +1 -0
  44. package/dist/test-helpers/ajv.d.ts +22 -0
  45. package/dist/test-helpers/ajv.d.ts.map +1 -0
  46. package/dist/test-helpers/ajv.js +38 -0
  47. package/dist/test-helpers/ajv.js.map +1 -0
  48. package/package.json +16 -9
  49. package/schemas/neurotype-addenda.schema.json +167 -0
  50. package/schemas/plugin.example.yaml +116 -71
  51. package/schemas/plugin.minimal.yaml +18 -12
  52. package/schemas/plugin.schema.json +13 -2
  53. package/schemas/profile.example.yaml +112 -64
  54. package/schemas/profile.minimal.yaml +15 -7
  55. package/schemas/profile.schema.json +116 -0
  56. package/src/index.test.ts +0 -8
  57. package/src/index.ts +0 -1
@@ -0,0 +1,38 @@
1
+ /*
2
+ * SPDX-License-Identifier: AGPL-3.0-or-later
3
+ * Copyright (c) 2026 NeuroDock contributors.
4
+ */
5
+ /**
6
+ * ajv.ts — shared Ajv 2020 builder for the core schema tests.
7
+ *
8
+ * The three core schema tests (profile.test.ts, profile.schema.test.ts,
9
+ * profile.presets.test.ts) all need an identically-configured Ajv2020 instance
10
+ * with ajv-formats applied. This helper is the single source of that config so
11
+ * the `addFormats` interop cast lives in one place rather than being duplicated
12
+ * (and drifting) across three files.
13
+ *
14
+ * Test-only: Ajv + ajv-formats are dev dependencies. Importing this from
15
+ * production code would break the zero-runtime-dependencies invariant, so it
16
+ * lives under `test-helpers/` and is only ever imported by `*.test.ts` files.
17
+ */
18
+ import { Ajv2020 } from "ajv/dist/2020.js";
19
+ import addFormats from "ajv-formats";
20
+ // ajv-formats ships a CommonJS default export whose call signature is not
21
+ // visible through the ESM interop wrapper, so we narrow it once here.
22
+ const applyFormats = addFormats;
23
+ /**
24
+ * Build a fresh Ajv 2020 instance configured exactly as the core schema tests
25
+ * require: lenient strict mode (the schema uses draft-2020 features Ajv's strict
26
+ * mode flags as warnings), union types allowed, all errors collected, and
27
+ * ajv-formats applied so `pattern`/format keywords resolve.
28
+ */
29
+ export function buildAjv() {
30
+ const ajv = new Ajv2020({
31
+ allErrors: true,
32
+ strict: false,
33
+ allowUnionTypes: true,
34
+ });
35
+ applyFormats(ajv);
36
+ return ajv;
37
+ }
38
+ //# sourceMappingURL=ajv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ajv.js","sourceRoot":"","sources":["../../src/test-helpers/ajv.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,UAAU,MAAM,aAAa,CAAC;AAErC,0EAA0E;AAC1E,sEAAsE;AACtE,MAAM,YAAY,GAAG,UAAkD,CAAC;AAExE;;;;;GAKG;AACH,MAAM,UAAU,QAAQ;IACtB,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC;QACtB,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,KAAK;QACb,eAAe,EAAE,IAAI;KACtB,CAAC,CAAC;IACH,YAAY,CAAC,GAAG,CAAC,CAAC;IAClB,OAAO,GAAG,CAAC;AACb,CAAC"}
package/package.json CHANGED
@@ -1,17 +1,21 @@
1
1
  {
2
2
  "name": "@neurodock/core",
3
- "version": "0.0.1",
3
+ "version": "0.2.0",
4
4
  "private": false,
5
5
  "description": "Shared types, profile schema, and plugin protocol for NeuroDock.",
6
6
  "license": "AGPL-3.0-or-later",
7
7
  "type": "module",
8
- "main": "./src/index.ts",
9
- "types": "./src/index.ts",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
10
  "exports": {
11
- ".": "./src/index.ts"
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ }
12
15
  },
13
16
  "files": [
14
- "src",
17
+ "dist",
18
+ "data/neurotype-addenda/v1.json",
15
19
  "schemas",
16
20
  "README.md"
17
21
  ],
@@ -25,13 +29,16 @@
25
29
  },
26
30
  "homepage": "https://github.com/tlennon-ie/neurodock#readme",
27
31
  "devDependencies": {
28
- "vitest": "^2.1.8"
32
+ "ajv": "^8.17.1",
33
+ "ajv-formats": "^3.0.1",
34
+ "vitest": "^3.2.6",
35
+ "yaml": "^2.8.3"
29
36
  },
30
37
  "scripts": {
31
- "build": "echo 'core: build stub' && exit 0",
32
- "lint": "echo 'core: lint stub' && exit 0",
38
+ "build": "tsc -p tsconfig.json",
39
+ "lint": "tsc --noEmit && echo 'core: lint via tsc strict mode'",
33
40
  "test": "vitest run --passWithNoTests",
34
- "typecheck": "echo 'core: typecheck stub' && exit 0",
41
+ "typecheck": "tsc --noEmit",
35
42
  "clean": "rm -rf dist .turbo"
36
43
  }
37
44
  }
@@ -0,0 +1,167 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.neurodock.org/neurotype-addenda/v1/neurotype-addenda.schema.json",
4
+ "title": "NeuroDock Neurotype Addenda Artifact",
5
+ "description": "Validates the language-neutral, enum-keyed prompt-shaping content artifact (data/neurotype-addenda/v1.json). This artifact is CONTENT, not schema shape (ADR 0011): it carries the per-(tool x neurotype) prose blocks that NeuroDock surfaces append to a model prompt, plus the fusion rule, priority ordering, framing, output-format guidance, and the cross-cutting voice-input / tourette / other / generic-fallback blocks. Additive-only versioning: new tools, new neurotypes, and new optional top-level keys are non-breaking. Unknown keys are permitted for forward-compatibility where appropriate.",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "required": [
9
+ "artifact_version",
10
+ "fusion",
11
+ "priority",
12
+ "framing",
13
+ "output_format",
14
+ "voice_input",
15
+ "tourette",
16
+ "other",
17
+ "generic",
18
+ "tools"
19
+ ],
20
+ "properties": {
21
+ "$schema": {
22
+ "type": "string",
23
+ "description": "Optional pointer back to this schema's $id."
24
+ },
25
+ "artifact_version": {
26
+ "type": "string",
27
+ "description": "Semantic version of the artifact content. Additive changes bump minor; a breaking re-shape forks to a new vN.json + a new schema $id.",
28
+ "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
29
+ "examples": ["1.0.0"]
30
+ },
31
+ "description": {
32
+ "type": "string"
33
+ },
34
+ "tokens": {
35
+ "type": "array",
36
+ "description": "The complete set of interpolation tokens any block may contain. Documentation only; the assembler is the authority.",
37
+ "items": { "type": "string" }
38
+ },
39
+ "fusion": {
40
+ "type": "object",
41
+ "description": "The AuDHD substitution rule. When the input set lists the `result` neurotype directly, OR lists every neurotype in `all_of`, the `result` block is substituted and every neurotype in `remove` is dropped.",
42
+ "additionalProperties": true,
43
+ "required": ["result", "all_of", "remove"],
44
+ "properties": {
45
+ "description": { "type": "string" },
46
+ "result": { "type": "string" },
47
+ "any_of": {
48
+ "type": "array",
49
+ "items": { "type": "string" }
50
+ },
51
+ "all_of": {
52
+ "type": "array",
53
+ "items": { "type": "string" }
54
+ },
55
+ "remove": {
56
+ "type": "array",
57
+ "items": { "type": "string" }
58
+ }
59
+ }
60
+ },
61
+ "priority": {
62
+ "type": "array",
63
+ "description": "Neurotype ordering. Higher-priority addenda are placed LATER in the assembled prompt (recency bias). Neurotypes are sorted by their index in this list.",
64
+ "items": { "type": "string" },
65
+ "minItems": 1
66
+ },
67
+ "framing": {
68
+ "type": "object",
69
+ "description": "The wrapper, header, footer, separators, and conflict footer that surround the per-neurotype blocks.",
70
+ "additionalProperties": true,
71
+ "required": [
72
+ "wrapper_prefix",
73
+ "wrapper_suffix",
74
+ "section_separator",
75
+ "block_line_separator",
76
+ "header",
77
+ "footer",
78
+ "conflict_footer_min_neurotypes",
79
+ "conflict_footer"
80
+ ],
81
+ "properties": {
82
+ "wrapper_prefix": { "type": "string" },
83
+ "wrapper_suffix": { "type": "string" },
84
+ "section_separator": { "type": "string" },
85
+ "block_line_separator": { "type": "string" },
86
+ "header": {
87
+ "type": "array",
88
+ "items": { "type": "string" }
89
+ },
90
+ "footer": {
91
+ "type": "array",
92
+ "items": { "type": "string" }
93
+ },
94
+ "conflict_footer_min_neurotypes": {
95
+ "type": "integer",
96
+ "minimum": 1
97
+ },
98
+ "conflict_footer": { "type": "string" }
99
+ }
100
+ },
101
+ "output_format": {
102
+ "type": "object",
103
+ "description": "Per-output-format guidance. The assembler renders `prefix + format + separator + descriptions[format]`.",
104
+ "additionalProperties": true,
105
+ "required": ["prefix", "separator", "descriptions", "default"],
106
+ "properties": {
107
+ "prefix": { "type": "string" },
108
+ "separator": { "type": "string" },
109
+ "descriptions": {
110
+ "type": "object",
111
+ "description": "Map of output-format enum value to its one-line description.",
112
+ "additionalProperties": { "type": "string" },
113
+ "minProperties": 1
114
+ },
115
+ "default": { "type": "string" }
116
+ }
117
+ },
118
+ "voice_input": {
119
+ "type": "object",
120
+ "description": "Cross-cutting voice-input block. Emitted when voice input is preferred, before the per-neurotype blocks.",
121
+ "additionalProperties": true,
122
+ "required": ["block"],
123
+ "properties": {
124
+ "block": { "$ref": "#/$defs/block" }
125
+ }
126
+ },
127
+ "tourette": {
128
+ "type": "object",
129
+ "description": "Tourette special block. Tool-independent; rendered whenever `tourette` is in the effective set.",
130
+ "additionalProperties": true,
131
+ "required": ["block"],
132
+ "properties": {
133
+ "block": { "$ref": "#/$defs/block" }
134
+ }
135
+ },
136
+ "other": {
137
+ "type": "object",
138
+ "description": "Self-described block. Carries the {notes} interpolation token; rendered when `other` is selected with notes, or appended as a footer when notes are present without `other`.",
139
+ "additionalProperties": true,
140
+ "required": ["block"],
141
+ "properties": {
142
+ "block": { "$ref": "#/$defs/block" }
143
+ }
144
+ },
145
+ "generic": {
146
+ "type": "object",
147
+ "description": "Generic per-neurotype fallback blocks (no tool context, or no concrete per-tool block for the pair). Keyed by neurotype enum value.",
148
+ "additionalProperties": { "$ref": "#/$defs/block" }
149
+ },
150
+ "tools": {
151
+ "type": "object",
152
+ "description": "Per-tool matrices of concrete per-neurotype blocks. Keyed by tool name, then by neurotype enum value. Additive: a new tool or a new neurotype within a tool is non-breaking.",
153
+ "additionalProperties": {
154
+ "type": "object",
155
+ "additionalProperties": { "$ref": "#/$defs/block" }
156
+ }
157
+ }
158
+ },
159
+ "$defs": {
160
+ "block": {
161
+ "type": "array",
162
+ "description": "A prose block: an ordered list of lines joined with the framing block_line_separator. Lines may contain {max_chunk_size} and/or {notes} interpolation tokens.",
163
+ "items": { "type": "string" },
164
+ "minItems": 1
165
+ }
166
+ }
167
+ }
@@ -1,75 +1,103 @@
1
- # NeuroDock Plugin — worked example (fictional Hiberno-English language pack).
1
+ # ==============================================================================
2
+ # WELCOME — THIS IS A WORKED EXAMPLE OF A PLUGIN MANIFEST
3
+ # ==============================================================================
4
+ # Plugins are how NeuroDock grows without us having to change the core. This
5
+ # file shows every field you can put in your own plugin's "plugin.yaml" file.
2
6
  #
3
- # This file is illustrative. It is NOT installed by `npx neurodock init`;
4
- # it documents the full shape of a plugin.yaml manifest so contributors
5
- # can copy it as a starting point.
7
+ # You don't need to use every field. Most of them are optional. Copy this
8
+ # file as a starting point and delete anything you don't need.
6
9
  #
7
- # Manifest contract: packages/core/schemas/plugin.schema.json
8
- # Design rationale: docs/decisions/0007-plugin-protocol.md
10
+ # WHERE THE CONTRACT LIVES (for the curious):
11
+ # packages/core/schemas/plugin.schema.json — the machine-checkable rules
12
+ # docs/decisions/0007-plugin-protocol.md — the "why" behind the rules
9
13
  #
10
- # Discovery: the substrate walks plugins/<name>/plugin.yaml (in-repo) and
11
- # $XDG_DATA_HOME/neurodock/plugins/<name>/plugin.yaml (per-user) at init.
12
- # No central registry is required in v0.1.0; the Phase 3 federated registry
13
- # at plugins.neurodock.org is opt-in and indexes signed manifests.
14
+ # HOW PLUGINS GET FOUND:
15
+ # When NeuroDock starts, it looks in two places for plugins:
16
+ # 1. plugins/<your-plugin>/plugin.yaml (lives inside this repo)
17
+ # 2. ~/.local/share/neurodock/plugins/<your-plugin>/plugin.yaml
18
+ # (lives on your own computer, just for you)
19
+ # No central server. No sign-up. No registry to publish to.
14
20
  #
15
- # Forward-compatibility: unknown keys at any nesting level are preserved
16
- # by loaders, not stripped. A v0.1.0 install can round-trip a v0.2.0
17
- # manifest without data loss.
18
-
19
- # Required. Plugin manifest schema version this file targets. Loaders
20
- # accept any version; they only warn when the file is newer than they
21
- # understand.
21
+ # WILL UPGRADING BREAK MY PLUGIN?
22
+ # No. If we add new fields in a future version, older versions of NeuroDock
23
+ # will leave them alone instead of stripping them out. You can edit your
24
+ # plugin on a new install, swap back to an old one, and not lose anything.
25
+ # ==============================================================================
26
+
27
+ # Leave this as "0.1.0". It just tells NeuroDock which version of the plugin
28
+ # format you're using. If you're newer than NeuroDock, you'll get a warning,
29
+ # not an error.
22
30
  schema_version: "0.1.0"
23
31
 
24
- # Required. Globally unique within `type`. Kebab-case. Reverse-DNS
25
- # prefixes (e.g. "org-eobrien-...") are RECOMMENDED for community
26
- # plugins; not enforced in v0.1.0.
32
+ # ------------------------------------------------------------------------------
33
+ # 1. WHO THIS PLUGIN IS (Required)
34
+ # ------------------------------------------------------------------------------
35
+ # A short, unique name. Lowercase, dashes between words.
36
+ # Tip: starting it with your handle (e.g. "org-eobrien-...") helps avoid
37
+ # clashes with other contributors' plugins. Not required.
27
38
  name: "ie-corporate-translation"
28
39
 
29
- # Required. One of:
30
- # skill | mcp-server | profile | translation-pack | language-pack | theme
31
- #
32
- # 'language-pack' shadows existing translation prompts for the manifest's
33
- # `locale`. 'translation-pack' is a domain bundle (engineering review,
34
- # legal correspondence, etc.) that may target any locale. 'theme'
35
- # bundles design-system-keeper-approved visual variants.
40
+ # What kind of plugin is this? Pick one:
41
+ # skill adds a Claude skill (a markdown file with triggers)
42
+ # mcp-server — adds a new MCP server with new tools
43
+ # profile — adds a profile preset users can copy
44
+ # translation-pack adds translation prompts for a domain (legal, sales...)
45
+ # language-pack — adds prompts for a non-US-English workplace culture
46
+ # theme — adds a visual theme for UI surfaces
36
47
  type: "language-pack"
37
48
 
38
- # Required. Strict semver. Patch/minor bumps in v0.1.x MUST be additive.
49
+ # Your plugin's version number. Use semver (e.g. "0.2.1"). Bumping the
50
+ # patch (third) number means "small fix, nothing broke". Bumping the minor
51
+ # (middle) means "added a new feature, nothing broke". Bumping the major
52
+ # (first) means "I changed something that might break people". Try not to
53
+ # bump the major in 0.1.x unless you really have to.
39
54
  version: "0.2.1"
40
55
 
41
- # Required. One-sentence human description shown in plugin listings.
42
- # Must not make clinical claims (per ETHICS commitment 1).
56
+ # A one-sentence description of what this plugin does. This is what people
57
+ # see in plugin listings. Don't make clinical claims here say what the
58
+ # plugin DOES, not what it TREATS.
43
59
  description: "Hiberno-English to neutral corporate English for ND professionals — direct decoding of indirect Irish workplace register without flattening voice."
44
60
 
45
- # Optional. Plugin authors. At least one maintainer is RECOMMENDED for
46
- # community plugins so the substrate can surface a contact in trust
47
- # prompts.
61
+ # ------------------------------------------------------------------------------
62
+ # 2. WHO MADE IT (Optional but appreciated)
63
+ # ------------------------------------------------------------------------------
64
+ # Listing at least one maintainer helps when something needs fixing.
65
+ # "role" is whatever makes sense — maintainer, reviewer, lived-experience reviewer.
48
66
  authors:
49
67
  - name: "Eoin O'Brien"
50
68
  handle: "@eobrien"
51
69
  role: "maintainer"
52
70
  - name: "Síofra Ní Bhriain"
53
71
  handle: "@sionb"
54
- role: "reviewer" # lived-experience reviewer
72
+ role: "reviewer" # lived-experience reviewer
55
73
 
56
- # Optional. Neurotype targeting. Empty / absent = agnostic (auto-activates
57
- # for every user). Non-empty intersection with profile.identity.neurotypes
58
- # = auto-activate. Empty intersection = installed but not auto-activated;
59
- # the user can enable it manually.
74
+ # ------------------------------------------------------------------------------
75
+ # 3. WHO IS THIS PLUGIN FOR? (Optional)
76
+ # ------------------------------------------------------------------------------
77
+ # Which neurotypes does this plugin help? Leave the list empty (or remove
78
+ # this block) if it works for everyone — most plugins do.
79
+ #
80
+ # If a user's profile lists any of these neurotypes, NeuroDock turns this
81
+ # plugin on for them automatically. If not, they can still turn it on by
82
+ # hand — your plugin isn't blocked, just not on by default.
60
83
  neurotypes:
61
84
  - "adhd"
62
85
  - "audhd"
63
86
  - "asd"
64
87
 
65
- # REQUIRED for type 'language-pack' and 'translation-pack'. BCP 47 tags.
66
- # Substrate prefers locale-matched plugins over locale-agnostic ones
67
- # when both apply.
88
+ # Which spoken-language / workplace cultures is this plugin for?
89
+ # REQUIRED if type is "language-pack" or "translation-pack".
90
+ # Use BCP 47 tags ("en-IE" = Irish English, "ja-JP" = Japanese, etc.)
68
91
  locale:
69
92
  - "en-IE"
70
- - "en-GB" # ie-IE register often surfaces in en-GB workplaces too
71
-
72
- # Optional. Hard runtime requirements.
93
+ - "en-GB" # Irish-English register often shows up in UK workplaces too
94
+
95
+ # ------------------------------------------------------------------------------
96
+ # 4. WHAT THIS PLUGIN NEEDS TO RUN (Optional)
97
+ # ------------------------------------------------------------------------------
98
+ # If your plugin needs a specific version of NeuroDock or another MCP server,
99
+ # say so here. NeuroDock will skip loading your plugin (cleanly) if any of
100
+ # these aren't around.
73
101
  requires:
74
102
  substrate_version: ">=0.1.0"
75
103
  mcp_servers:
@@ -78,15 +106,18 @@ requires:
78
106
  skills: []
79
107
  plugins: []
80
108
 
81
- # Required-shape (may be empty array). Assets this plugin exposes to
82
- # the substrate. Each `path` is sandboxed: it MUST resolve inside the
83
- # plugin's directory after normalisation.
109
+ # ------------------------------------------------------------------------------
110
+ # 5. WHAT YOUR PLUGIN PROVIDES
111
+ # ------------------------------------------------------------------------------
112
+ # This is the actual content your plugin ships. Each entry points at a file
113
+ # inside your plugin's directory. All paths are relative — your plugin can't
114
+ # reach outside its own folder. That's a deliberate safety rule.
84
115
  provides:
85
116
  - type: "language-prompt-override"
86
117
  id: "translate-incoming-en-ie"
87
118
  path: "./prompts/translate-incoming.md"
88
- # Optional per-asset predicate. Defaults to inheriting manifest-level
89
- # neurotypes + locale. When present, overrides for this asset only.
119
+ # You can narrow when a single file applies, separate from the
120
+ # whole-plugin neurotypes/locale settings above.
90
121
  applies_to:
91
122
  locale: ["en-IE", "en-GB"]
92
123
 
@@ -101,19 +132,23 @@ provides:
101
132
  - type: "translation-prompt"
102
133
  id: "decode-grand"
103
134
  path: "./prompts/idioms/decode-grand.md"
104
- # "Grand" in Hiberno-English ranges from "excellent" to "this is
105
- # not fine and we are not going to discuss it further." Worth its
106
- # own prompt.
107
-
108
- # Required. Trust + provenance.
135
+ # "Grand" in Hiberno-English can mean anything from "excellent" to
136
+ # "this is not fine and we are not going to discuss it further." It
137
+ # earns its own prompt.
138
+
139
+ # ------------------------------------------------------------------------------
140
+ # 6. WHERE THIS PLUGIN CAME FROM (Required)
141
+ # ------------------------------------------------------------------------------
142
+ # This is the "trust" block. It tells NeuroDock how much social process has
143
+ # touched this plugin so it knows whether to prompt the user before activating.
144
+ #
145
+ # Levels:
146
+ # official — published by the NeuroDock maintainer; installs silently
147
+ # verified — signed against the maintainer keyring; installs silently
148
+ # community — your own plugin, author-signed; user gets a one-time prompt
149
+ # experimental — unsigned; NeuroDock refuses by default unless user opts in
109
150
  #
110
- # Four-tier ladder (see ADR 0007):
111
- # official — NeuroDock council-published; installs without prompting
112
- # verified — signed by a verified contributor (council keyring);
113
- # installs without prompting
114
- # community — author-signed; provenance recorded but not vouched;
115
- # prompts the user per profile preference
116
- # experimental — unsigned; substrate refuses by default
151
+ # Most contributor plugins are "community". That's a good thing.
117
152
  trust:
118
153
  level: "community"
119
154
  signature: |
@@ -123,12 +158,18 @@ trust:
123
158
  keyring_fingerprint: "A1B2 C3D4 E5F6 7890 1234 5678 9ABC DEF0 1234 5678"
124
159
  source_url: "https://github.com/eobrien/ie-corporate-translation"
125
160
 
126
- # Required. SPDX identifier. Must be on the v0.1.0 whitelist
127
- # (AGPL-3.0-or-later-compatible). Non-whitelisted licenses refuse to
128
- # load with a 'license_not_allowed' error.
161
+ # ------------------------------------------------------------------------------
162
+ # 7. LICENSE (Required)
163
+ # ------------------------------------------------------------------------------
164
+ # Your plugin's licence. Must be one of the allowed-list licences (they all
165
+ # play nicely with AGPL-3.0). If you pick one that isn't on the list,
166
+ # NeuroDock will refuse to load the plugin with a clear "license_not_allowed"
167
+ # error so nothing silently fails.
129
168
  license: "AGPL-3.0-or-later"
130
169
 
131
- # Optional. Discovery surface.
170
+ # ------------------------------------------------------------------------------
171
+ # 8. WHERE PEOPLE CAN LEARN MORE (Optional)
172
+ # ------------------------------------------------------------------------------
132
173
  homepage: "https://hiberno-translate.example.org"
133
174
  repository: "https://github.com/eobrien/ie-corporate-translation"
134
175
  keywords:
@@ -137,12 +178,16 @@ keywords:
137
178
  - "corporate"
138
179
  - "indirect-speech"
139
180
 
140
- # Optional. Lifecycle hooks. v0.1.0 sandbox refuses to run hooks unless
141
- # trust.level in {'official', 'verified'}. Community plugins MAY declare
142
- # hooks; they will be ignored until the hook sandbox lands in Phase 3.
181
+ # ------------------------------------------------------------------------------
182
+ # 9. LIFECYCLE HOOKS (Optional, advanced)
183
+ # ------------------------------------------------------------------------------
184
+ # Scripts that run on install/uninstall. For safety, NeuroDock will only
185
+ # run these for "official" or "verified" plugins right now. You can declare
186
+ # them for a community plugin — they'll just sit there politely ignored
187
+ # until the safer hook sandbox lands.
143
188
  hooks:
144
- on_install: "./install.sh" # idempotent setup; no network, no out-of-dir writes
145
- on_uninstall: "./uninstall.sh" # cleanup of any plugin-local state
189
+ on_install: "./install.sh" # idempotent; no network, no writing outside the plugin dir
190
+ on_uninstall: "./uninstall.sh" # clean up anything you created locally
146
191
 
147
- # Optional. Forward-compat declarations. Reserved.
192
+ # Reserved for future use. Leave empty.
148
193
  compatibility: {}
@@ -1,14 +1,19 @@
1
- # NeuroDock Plugin — minimal valid manifest.
1
+ # ==============================================================================
2
+ # THE SMALLEST POSSIBLE PLUGIN MANIFEST
3
+ # ==============================================================================
4
+ # This file contains ONLY the required fields for a NeuroDock plugin. Every
5
+ # other field is optional. If you're just starting out, this is the shape to
6
+ # copy.
2
7
  #
3
- # Required fields ONLY. Every other block is optional.
8
+ # For the full version with every option explained, see:
9
+ # packages/core/schemas/plugin.example.yaml
4
10
  #
5
- # Manifest contract: packages/core/schemas/plugin.schema.json
6
- # Worked example: packages/core/schemas/plugin.example.yaml
7
- # Design rationale: docs/decisions/0007-plugin-protocol.md
11
+ # For the design rationale behind why these fields exist:
12
+ # docs/decisions/0007-plugin-protocol.md
8
13
  #
9
- # This minimal shape is what `neurodock plugin scaffold` would emit.
10
- # It is valid against plugin.schema.json: every required field is
11
- # present, and no optional field is included.
14
+ # The "neurodock plugin scaffold" command would write something close to
15
+ # this file. Every required field is present, no optional ones are.
16
+ # ==============================================================================
12
17
 
13
18
  schema_version: "0.1.0"
14
19
  name: "minimal-example"
@@ -18,7 +23,8 @@ description: "Minimal valid plugin manifest — replace with your one-sentence s
18
23
  license: "AGPL-3.0-or-later"
19
24
  trust:
20
25
  level: "experimental"
21
- # NOTE: with trust.level = 'experimental' the substrate refuses this
22
- # plugin by default. To install, either:
23
- # (a) bump trust.level to 'community' and add `source_url`, or
24
- # (b) opt in explicitly via `neurodock plugin trust <name> --once`.
26
+ # Heads up: with trust.level = "experimental" NeuroDock will refuse to
27
+ # load this plugin by default that's a safety feature, not a bug.
28
+ # To get it loading, do one of:
29
+ # (a) bump trust.level to "community" and add a "source_url", or
30
+ # (b) opt in just this once: `neurodock plugin trust <name> --once`
@@ -6,7 +6,15 @@
6
6
  "$comment": "Discovery is filesystem-based in v0.1.0: the substrate walks plugins/*/plugin.yaml (in-repo) and $XDG_DATA_HOME/neurodock/plugins/*/plugin.yaml (per-user) at init. The Phase 3 federated registry at plugins.neurodock.org is opt-in and indexes signed manifests; the protocol does NOT depend on a central registry. Loaders MUST preserve unknown top-level and nested keys when round-tripping a manifest so a v0.1.0 install can read and re-emit a v0.2.0 manifest without data loss. Asset paths in `provides[].path` and `hooks.*` are sandboxed: the resolved absolute path MUST remain inside the plugin's directory after normalisation. Symlinks pointing outside the plugin dir MUST be rejected by the loader.",
7
7
  "type": "object",
8
8
  "additionalProperties": true,
9
- "required": ["schema_version", "name", "type", "version", "description", "license", "trust"],
9
+ "required": [
10
+ "schema_version",
11
+ "name",
12
+ "type",
13
+ "version",
14
+ "description",
15
+ "license",
16
+ "trust"
17
+ ],
10
18
  "properties": {
11
19
  "schema_version": {
12
20
  "type": "string",
@@ -224,7 +232,10 @@
224
232
  "type": "string",
225
233
  "description": "Path to the asset, RELATIVE to the plugin directory. MUST start with './' or a non-leading-slash subdirectory. Loader normalises and rejects any path resolving outside the plugin directory or pointing through a symlink that does so.",
226
234
  "pattern": "^(\\./)?[^/\\\\][^\\\\:*?\"<>|]*$",
227
- "examples": ["./prompts/translate-hiberno-direct.md", "prompts/tone-warm.md"]
235
+ "examples": [
236
+ "./prompts/translate-hiberno-direct.md",
237
+ "prompts/tone-warm.md"
238
+ ]
228
239
  },
229
240
  "applies_to": {
230
241
  "type": "object",