structured-context 0.9.0 → 0.9.1

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/README.md CHANGED
@@ -1,11 +1,58 @@
1
1
  # structured-context
2
2
 
3
- Tools for working with Opportunity Solution Tree structures and other product management and strategy frameworks
3
+ Keep your content clean and your thinking clear.
4
+
5
+ `structured-context` provides assistive tools for working with structured content, including knowledge wikis (a la [Karpathy](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f)), product/strategy frameworks (like [Teresa Torres' Opportunity Solution Trees](https://www.producttalk.org/opportunity-solution-trees/) and [Martin et al's strategy cascade](https://rogerlmartin.com/thought-pillars/strategy), and more. Great for flat sets of documents, hierarchical or layered context trees, or any kind of knowledge graph.
6
+
7
+ Assign a schema to your markdown content to give humans and AI agents consistent structure and content guidelines.
8
+
9
+ In Claude Code:
10
+ ```
11
+ ❯ Use /structured-context to configure 'my-research' as a knowledge wiki, then organise it
12
+
13
+ ⏺ Skill(structured-context)
14
+ ⎿  Successfully loaded skill
15
+
16
+ ...
17
+
18
+ ```
19
+
20
+ Command line tools:
21
+ ```
22
+ > sctx validate strategy
23
+
24
+ Space Validation Results
25
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
26
+ Content and structure
27
+ Valid 16
28
+ Schema validation errors 0
29
+ Broken links 1
30
+ Duplicate keys 0
31
+ Rule violations 2
32
+ Hierarchy violations 0
33
+ Orphans (hierarchy nodes - no parent) 1
34
+ Ignored during parsing 0
35
+
36
+ Orphans (hierarchy nodes - no parent):
37
+ Solution looking for a problem.md
38
+
39
+ Broken links:
40
+ Steal underpants.md: [[Gnome goals]] → Link target "Gnome goals" in field "related" not found
41
+
42
+ Rule violations:
43
+ workflow (1):
44
+ Build Death Star.md: Opportunities should contribute to at least one Outcome
45
+
46
+ best-practice (1):
47
+ High tech juice press.md: Explore multiple candidate solutions (aim for at least three) for an active target opportunity
48
+ ```
4
49
 
5
50
  ## Installation
6
51
 
7
52
  Requires [Bun](https://bun.sh) runtime.
8
53
 
54
+ Install globally (recommended):
55
+
9
56
  ```bash
10
57
  bun install -g structured-context
11
58
  ```
@@ -18,10 +65,11 @@ bunx structured-context validate <space>
18
65
 
19
66
  ## Setup for AI Agents
20
67
 
21
- A Claude Code plugin is included at `plugin/`. It provides validation hooks, slash commands, and agent skills. Install it with:
68
+ Claude Code plugin, providing validation hooks, slash commands, and agent skills. Install it with:
22
69
 
23
70
  ```
24
- claude plugin install mindsocket/structured-context
71
+ claude plugin marketplace add mindsocket/structured-context
72
+ claude plugin install structured-context
25
73
  ```
26
74
 
27
75
  Skills can also be installed standalone without the plugin:
@@ -38,31 +86,24 @@ See [docs/concepts.md](docs/concepts.md) for the full terminology reference, inc
38
86
 
39
87
  `structured-context` looks for its config file in this order:
40
88
 
41
- 1. `$SCTX_CONFIG` — explicit path override
42
- 2. `~/.config/structured-context/config.json` (or `$XDG_CONFIG_HOME/structured-context/config.json`)
43
- 3. `./config.json` in the current working directory
89
+ 1. `--config` command line argument
90
+ 2. `$SCTX_CONFIG` env var
91
+ 3. `~/.config/structured-context/config.json` (or `$XDG_CONFIG_HOME/structured-context/config.json`)
92
+ 4. `./config.json` in the current working directory
44
93
 
45
- See `config.example.json` for the full structure. The config maps space names to paths, with optional Miro integration fields and global defaults. Paths in config files are resolved relative to the config file.
94
+ See `config.example.json` for the full structure. The config maps space names to paths, with optional additional configuration options for parsing and integrations. Paths in config files are resolved relative to the config file.
46
95
 
47
96
  **Including spaces from other configs:** Use `includeSpacesFrom` to import space definitions from other config files. This is useful for aggregating spaces from multiple projects into a central config, reducing the need to specify `--config` on CLI commands. Duplicate space names are not allowed.
48
97
 
49
98
  **Plugins and markdown plugin config:** See `sctx docs config` for the full reference including `fieldMap`, `typeInference`, `templateDir`, filter views, and plugin loading rules.
50
99
 
51
- ### Spaces
52
-
53
- A space is a named directory or single file registered in the config. Spaces let you reference content by name instead of path:
54
-
55
- ```bash
56
- sctx validate ProductX
57
- ```
58
-
59
100
  ### Schemas
60
101
 
61
102
  Schemas define the structure and rules for the entities in a space, allowing customisation and extension to different models.
62
103
 
63
- Two schemas (`general` and `strict_ost`) are included. The general schema combines a basic vision/mission/goals hierarchy with a hierarchy loosely based on Opportunity Solution Trees. It is intentionally flexible to support rapid initial adoption. The strict OST schema has a narrower scope, and reflects Teresa Torres' specific recommendations for Opportunity Solution Trees more closely.
104
+ Several schemas (`strict_ost`, `knowledge_wiki` and `general`) are included. The general (strategy) schema combines a basic vision/mission/goals hierarchy with a hierarchy loosely based on Opportunity Solution Trees. It is intentionally flexible to support rapid initial adoption. The strict OST schema has a narrower scope, and reflects Teresa Torres' specific recommendations for Opportunity Solution Trees more closely. The knowledge wiki schema defines a flatter set of types used for knowledge bases.
64
105
 
65
- sctx schemas use a metaschema based on JSON Schema Draft-07 that adds a top-level `$metadata` block:
106
+ structured-context schemas use a metaschema based on JSON Schema Draft-07 that adds a top-level `$metadata` block:
66
107
 
67
108
  ```json5
68
109
  "$metadata": {
@@ -91,8 +132,6 @@ sctx schemas use a metaschema based on JSON Schema Draft-07 that adds a top-leve
91
132
  }
92
133
  ```
93
134
 
94
- Rules are a flat array (`rules[]`) with per-rule `category`.
95
-
96
135
  Schema hierarchy levels support DAG (multi-parent) relationships via configurable edge fields. Each entry in `$metadata.hierarchy.levels` can be a plain type name string (defaults to `parent` field on child nodes) or an object:
97
136
 
98
137
  ```json5
@@ -106,7 +106,7 @@ export async function validate(context, options = {}) {
106
106
  duplicateErrors: [],
107
107
  ruleViolations: [],
108
108
  hierarchyViolations: [],
109
- orphanCount: 0,
109
+ orphans: [],
110
110
  parseIgnored: parseIgnored || [],
111
111
  };
112
112
  for (const node of nodes) {
@@ -143,7 +143,7 @@ export async function validate(context, options = {}) {
143
143
  result.hierarchyViolations = [...hierarchyValidation.violations];
144
144
  // Calculate orphan count (informational, not a validation error)
145
145
  if (metadata.hierarchy) {
146
- result.orphanCount = buildSpaceGraph(nodes, metadata.hierarchy.levels).orphans.length;
146
+ result.orphans = [...buildSpaceGraph(nodes, metadata.hierarchy.levels).orphans];
147
147
  }
148
148
  // Load and execute rules validation if schema defines rules
149
149
  if (metadata.rules) {
@@ -187,7 +187,7 @@ export async function validate(context, options = {}) {
187
187
  validCount: result.validCount,
188
188
  errorCount,
189
189
  errors: errorsByFile,
190
- orphanCount: result.orphanCount,
190
+ orphanCount: result.orphans.length,
191
191
  parseIgnored: result.parseIgnored,
192
192
  }, null, 2));
193
193
  return errorCount > 0 ? 1 : 0;
@@ -223,8 +223,13 @@ export async function validate(context, options = {}) {
223
223
  console.log(fmt(' Duplicate keys', result.duplicateErrors.length, true));
224
224
  console.log(fmt(' Rule violations', result.ruleViolations.length, true));
225
225
  console.log(fmt(' Hierarchy violations', result.hierarchyViolations.length, true));
226
- console.log(fmt(' Orphans (hierarchy nodes - no parent)', result.orphanCount, true, true));
226
+ console.log(fmt(' Orphans (hierarchy nodes - no parent)', result.orphans.length, true, true));
227
227
  console.log(fmt(' Ignored during parsing', result.parseIgnored.length, true, true));
228
+ if (result.orphans.length > 0) {
229
+ console.log(`\nOrphans (hierarchy nodes - no parent):`);
230
+ for (const node of result.orphans)
231
+ console.log(` ${node.label}`);
232
+ }
228
233
  if (result.parseIgnored.length > 0) {
229
234
  console.log(`\nIgnored during parsing:`);
230
235
  for (const f of result.parseIgnored)
package/dist/config.js CHANGED
@@ -98,13 +98,24 @@ function resolveRelativePaths(config, configDir) {
98
98
  return p;
99
99
  return resolve(configDir, p);
100
100
  };
101
+ const relSchema = (p) => {
102
+ if (!p || isAbsolute(p) || isUrl(p))
103
+ return p;
104
+ if (!p.includes('/') && !p.includes('\\')) {
105
+ const localPath = resolve(configDir, p);
106
+ if (existsSync(localPath))
107
+ return localPath;
108
+ return join(bundledSchemasDir, p);
109
+ }
110
+ return resolve(configDir, p);
111
+ };
101
112
  return {
102
113
  ...config,
103
- schema: rel(config.schema),
114
+ schema: relSchema(config.schema),
104
115
  spaces: config.spaces.map((s) => ({
105
116
  ...s,
106
117
  path: rel(s.path),
107
- schema: rel(s.schema),
118
+ schema: relSchema(s.schema),
108
119
  plugins: normalizePlugins(s.plugins),
109
120
  })),
110
121
  };
@@ -9,7 +9,9 @@
9
9
  "study": "source",
10
10
  "article": "source",
11
11
  "paper": "source",
12
- "research": "source"
12
+ "research": "source",
13
+ "comparison": "synthesis",
14
+ "query": "synthesis"
13
15
  },
14
16
  "relationships": [
15
17
  {
@@ -26,6 +28,13 @@
26
28
  "fieldOn": "child",
27
29
  "multiple": true
28
30
  },
31
+ {
32
+ "parent": "source",
33
+ "type": "entity",
34
+ "field": "sources",
35
+ "fieldOn": "child",
36
+ "multiple": true
37
+ },
29
38
  {
30
39
  "parent": "concept",
31
40
  "type": "synthesis",
@@ -134,6 +143,36 @@
134
143
  }
135
144
  ]
136
145
  },
146
+ {
147
+ "type": "object",
148
+ "description": "A concrete entity — a person, organisation, product, model, or other named thing. The building blocks of the wiki's knowledge graph alongside concepts. Entities are distinct from concepts: a concept frames an idea or mechanism; an entity is a specific, identifiable thing in the world.",
149
+ "allOf": [{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" }],
150
+ "properties": {
151
+ "type": { "const": "entity" },
152
+ "summary": {
153
+ "$ref": "sctx://_sctx_base#/$defs/summary"
154
+ },
155
+ "sources": {
156
+ "type": "array",
157
+ "items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
158
+ "description": "Wikilinks to source pages that contributed to this entity page"
159
+ },
160
+ "related": {
161
+ "type": "array",
162
+ "items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
163
+ "description": "Wikilinks to related entity, concept, or synthesis pages"
164
+ }
165
+ },
166
+ "required": ["type"],
167
+ "additionalProperties": true,
168
+ "examples": [
169
+ {
170
+ "type": "entity",
171
+ "summary": "AI safety research lab founded by Dario Amodei and Daniela Amodei",
172
+ "tags": ["company", "ai", "safety"]
173
+ }
174
+ ]
175
+ },
137
176
  {
138
177
  "type": "object",
139
178
  "description": "A synthesis page — connects multiple concepts and sources into a coherent model, framework, or thesis. The highest-value pages in a knowledge wiki. Must reference contributing sources.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "structured-context",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Tools for working with Opportunity Solution Tree structures and other product management and strategy frameworks",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",
@@ -9,7 +9,9 @@
9
9
  "study": "source",
10
10
  "article": "source",
11
11
  "paper": "source",
12
- "research": "source"
12
+ "research": "source",
13
+ "comparison": "synthesis",
14
+ "query": "synthesis"
13
15
  },
14
16
  "relationships": [
15
17
  {
@@ -26,6 +28,13 @@
26
28
  "fieldOn": "child",
27
29
  "multiple": true
28
30
  },
31
+ {
32
+ "parent": "source",
33
+ "type": "entity",
34
+ "field": "sources",
35
+ "fieldOn": "child",
36
+ "multiple": true
37
+ },
29
38
  {
30
39
  "parent": "concept",
31
40
  "type": "synthesis",
@@ -134,6 +143,36 @@
134
143
  }
135
144
  ]
136
145
  },
146
+ {
147
+ "type": "object",
148
+ "description": "A concrete entity — a person, organisation, product, model, or other named thing. The building blocks of the wiki's knowledge graph alongside concepts. Entities are distinct from concepts: a concept frames an idea or mechanism; an entity is a specific, identifiable thing in the world.",
149
+ "allOf": [{ "$ref": "sctx://_sctx_base#/$defs/baseNodeProps" }],
150
+ "properties": {
151
+ "type": { "const": "entity" },
152
+ "summary": {
153
+ "$ref": "sctx://_sctx_base#/$defs/summary"
154
+ },
155
+ "sources": {
156
+ "type": "array",
157
+ "items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
158
+ "description": "Wikilinks to source pages that contributed to this entity page"
159
+ },
160
+ "related": {
161
+ "type": "array",
162
+ "items": { "$ref": "sctx://_sctx_base#/$defs/wikilink" },
163
+ "description": "Wikilinks to related entity, concept, or synthesis pages"
164
+ }
165
+ },
166
+ "required": ["type"],
167
+ "additionalProperties": true,
168
+ "examples": [
169
+ {
170
+ "type": "entity",
171
+ "summary": "AI safety research lab founded by Dario Amodei and Daniela Amodei",
172
+ "tags": ["company", "ai", "safety"]
173
+ }
174
+ ]
175
+ },
137
176
  {
138
177
  "type": "object",
139
178
  "description": "A synthesis page — connects multiple concepts and sources into a coherent model, framework, or thesis. The highest-value pages in a knowledge wiki. Must reference contributing sources.",