context-sync
1.0.501
See the version list below for details.
dotnet tool install --global context-sync --version 1.0.501
dotnet new tool-manifest
dotnet tool install --local context-sync --version 1.0.501
#tool dotnet:?package=context-sync&version=1.0.501
nuke :add-package context-sync --version 1.0.501
context-sync
context-sync is the command-line companion to the Silkyware KnowledgeOps Platform.
It connects your CI pipeline (or your terminal) to a KnowledgeOps workspace: it delivers workflow, skill and ontology definitions to the platform, writes the step-type catalogue and the workspace's knowledge graph as files an AI agent can read, reports on the live graph, scaffolds a customer workflow repository, and files capability gaps.
A repository like this delivers artifacts; it cannot change graph data. A merge publishes workflows, skills and ontologies - it never creates, edits or deletes a node or an edge. Changing data is a workflow run against the instance, which produces a proposal a person approves.
The tool is deliberately thin. Validation runs server-side, on the KnowledgeOps instance you point it at, so the rules can never go stale inside your pipeline - the tool sends your artifact set and prints the server's per-file verdicts verbatim.
You need access to a Silkyware KnowledgeOps instance (an API URL, a workspace id, and a credential - your own sign-in token, or a machine credential issued by your organization) for the tool to be useful.
See Authentication before anything else: every verb is answered by the server, validate included.
Install
dotnet tool install -g context-sync
The same binary is also published as a container image for runners without the .NET SDK: ghcr.io/silkyware/context-sync.
Commands
| Verb | What it does |
|---|---|
init |
Scaffold a customer workflow repository: workflows/, skills/, ontologies/ folders, context-sync.json, a README, an agent orientation file, and a ready-made pipeline for --platform github, azuredevops or gitlab. Refuses to overwrite existing files. context-sync init --url <base> --organization <id> scaffolds the hierarchy-shaped layout below across every workspace of that organization and fills it from the live instance. |
steps |
Write the step-type catalogue under --out: one page per step type with its exact inputs, outputs and description, plus an INDEX.md. Generated from the platform's running registry, so it is what the engine will actually accept - read it instead of guessing what a step takes. Small and deterministic, but gitignored rather than committed: the running registry is the authority, so regenerate it on demand rather than trusting a copy. Needs your own sign-in token: the catalogue is not a workspace route, so a machine credential is refused. |
context |
Materialise the workspace's knowledge graph into agent-readable files under --out: INDEX.md plus one page per node grouped by kind, and brain.json (the raw export). This is your domain content, not the step catalogue, and there is a page per node - it runs to thousands of files for a real workspace and is stale as soon as anyone edits a node, so generate it on demand and keep it out of git (init scaffolds a .gitignore that does). Fails without writing anything when the context would be empty or a --require <kind>[=<min>] expectation is unmet. |
graph |
Report a workspace's live graph, read-only: node and edge kinds with counts, the data checked against the ontologies bound to it (including edge kinds no ontology declares, which a conformance audit cannot flag), and nodes with no relations. Use it to ask a question about the graph instead of materialising a copy of it. |
pull |
Bring the server's artifacts into the repository - the way to adopt a workspace that already has them, and to re-sync afterwards. Only what is defined at each layer is written; what is inherited is listed in a generated INHERITED.md. A file that differs on both sides stops the run and is named; --force takes the server's version. Nothing is ever deleted for you. |
validate |
Dry-run the artifact set under --root ({workflows,skills,ontologies}/*.json) against the server. Non-zero exit with every per-file verdict. |
publish |
Deliver the same set for real. Versions are minted server-side; nothing is activated unless you pass --activate (or the artifact is brand new, with nothing live to change). |
run |
Run a workflow definition file once, without saving it (--file <definition.json>, optional --variables <object.json>) - for a one-time data correction that should not leave a single-use workflow in the workspace. The server validates it exactly as a save would and refuses anything that could change data without review (outputMode: persist, autoApprove, PersistToBrain, triggers), so a correction arrives as a pending proposal someone approves in the product. Prints the proposal or run and the SHA-256 the server recorded for the definition. Needs a credential with both artifacts.publish and workflows.run. |
gap |
Register "this needs a step that does not exist" as a structured capability gap, or --list the workspace's gaps and their statuses. A filing failure prints loudly and still exits 0, so capture can never fail your build - pass --strict to opt out. |
Run context-sync --help for the full option reference.
Configuration
Three sources, in precedence order: flags over environment over the config file.
- Flags:
--url,--workspace,--layer, and the rest. - Environment:
CONTEXTHUB_URL,CONTEXTHUB_WORKSPACE. - Config file:
context-sync.jsonin the root directory (written byinit), carryingurl,workspaceandlayerso a scaffolded pipeline stays at about five lines.
In a hierarchy-shaped repository (below) a node folder's config names only its workspace and layer.
The url is then taken from the nearest context-sync.json above it, so --root <node> works without repeating the url in every node; with no ancestor naming one, the refusal lists the directories it searched.
validate and publish need --layer (local | project | organization); there is deliberately no default, because pushing to the wrong layer creates a shadow copy that silently stops receiving higher-layer edits.
One repository, several layers
A repository can also be shaped like the hierarchy it delivers to.
The root's context-sync.json then names { "url", "organization" } and no layer, and each nested folder is a node:
context-sync.json { "url": ..., "organization": "acme" }
acme/ the organization layer
context-sync.json { "workspace": "acme-ops", "layer": "organization" }
workflows/ skills/ ontologies/
INHERITED.md generated: what applies here from further up
acme-platform/ a project layer
context-sync.json { "workspace": "acme-ops", "layer": "project" }
acme-ops/ a workspace layer
context-sync.json { "workspace": "acme-ops", "layer": "local" }
Position encodes the layer, so a repository owning artifacts at more than one layer no longer needs one root per layer.
Only the root's config names the url; a node inherits it from the nearest one above, so --root <node> works on any folder without the url being copied into each of them.
--layer is refused against a tree: one flag must not retarget every node at once.
validate and publish walk every node.
A reference across nodes resolves, and neither verb needs anything published first.
Each node is its own delivered set, so an artifact referencing one defined a layer above it used to be refused until that higher layer was already on the server.
Every node's request now names what the rest of the run is delivering, so the reference resolves while nothing has been written yet.
validate --root . therefore accepts a pull request that introduces a new cross-layer dependency, which is the whole point: the gate is green before the merge that lands both halves.
publish dry-runs every node before writing any of them, and if any node is refused it writes nothing anywhere.
The real deliveries then run outermost layer first - organization, then project, then workspace.
That order no longer decides whether anything resolves; it is kept so that a partial state left by a transport failure reads sensibly.
This is not a transaction - each node's import is atomic only on its own, and there is no envelope across nodes. A node that fails AFTER the dry run passed leaves the tree partly delivered; re-running finishes it, because an unchanged artifact mints no version.
Each node records the workspace id its calls go through, because no artifact route is organization-addressed: an organization-layer write is a call to a workspace of that organization carrying layer=organization. The workspace is picked for you from the organization; pass --workspace only if you want a particular one.
Only layers that already define something get a folder; add one by hand (a context-sync.json and the artifact beside it) when a layer gets its first artifact.
workflows, skills and ontologies are reserved folder names.
A flat repository is not a tree and never becomes one. If your root's context-sync.json names a layer, every verb behaves exactly as it always has.
Authentication
The credential is environment-only: set CONTEXTHUB_TOKEN.
There is no --token flag (it would land the secret in shell history and CI logs), and a token key inside context-sync.json is refused outright - a committed file is the one place a credential must never live.
Every verb that talks to the server needs it, validate included.
Validation runs server-side, so without a credential the tool cannot tell you whether an artifact is correct.
The tool sends whatever CONTEXTHUB_TOKEN holds as a bearer token and never inspects its shape, so the machine credential your organization issued and your own sign-in token are interchangeable.
In CI, use the machine credential.
On your own machine, prefer your own sign-in token: it expires by itself, and anything it publishes is attributed to you rather than to a shared robot.
If your instance signs in with Microsoft Entra, the Azure CLI mints one:
az login
export CONTEXTHUB_TOKEN=$(az account get-access-token --scope 'api://<the API app id>/access_as_user' --query accessToken -o tsv)
Whoever administers your instance can tell you the scope; for the Silkyware-hosted instance it is api://928e06e6-84f2-4919-9e72-39c7715faa68/access_as_user.
A 401 later in the day means the token expired, not that something is misconfigured.
Exit codes
| Code | Meaning |
|---|---|
0 |
Success. |
1 |
The server refused the artifact set (per-file verdicts printed), or a context guard tripped (empty context, unmet --require). |
2 |
Configuration, authentication or transport: the call itself could not be made or answered. |
3 |
Throttled by the organization's import quota - nothing is wrong with the artifacts or the configuration, retry later. validate is never throttled. |
A minimal pipeline
dotnet tool install -g context-sync
context-sync validate --root . --layer organization # dry-run on pull requests
context-sync publish --root . --layer organization # deliver on merge
init writes exactly this pipeline for your platform, wired to context-sync.json.
License
Apache-2.0.
The license covers this package - the context-sync tool and its ContextHub.Client.Contracts wire-contract assembly - not the Silkyware KnowledgeOps Platform it talks to.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.508 | 36 | 9/18/2026 |
| 1.0.507 | 38 | 9/18/2026 |
| 1.0.506 | 52 | 9/17/2026 |
| 1.0.504 | 41 | 9/17/2026 |
| 1.0.503 | 51 | 9/16/2026 |
| 1.0.501 | 44 | 9/16/2026 |
| 1.0.500 | 43 | 9/16/2026 |
| 1.0.498 | 47 | 9/16/2026 |
| 1.0.497 | 48 | 9/16/2026 |
| 1.0.496 | 45 | 9/16/2026 |
| 1.0.494 | 41 | 9/16/2026 |
| 1.0.491 | 66 | 9/15/2026 |
| 1.0.490 | 63 | 9/15/2026 |
| 1.0.489 | 57 | 9/15/2026 |
| 1.0.486 | 65 | 9/15/2026 |
| 1.0.485 | 62 | 9/15/2026 |
| 1.0.476 | 85 | 9/14/2026 |
| 1.0.472 | 93 | 9/14/2026 |
| 1.0.471 | 86 | 9/14/2026 |
| 1.0.469 | 96 | 9/13/2026 |