@c4a/context-cli 0.7.55 → 0.7.60

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "protocol": "context.indexer.cli-release-manifest/v1",
3
3
  "package": "@c4a/context-cli",
4
- "version": "0.7.55",
4
+ "version": "0.7.60",
5
5
  "issuer": "context4ai/context",
6
6
  "bundles": [
7
7
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c4a/context-cli",
3
- "version": "0.7.55",
3
+ "version": "0.7.60",
4
4
  "type": "module",
5
5
  "description": "Local runtime and Agent integration for traceable knowledge production",
6
6
  "license": "MIT",
@@ -24,17 +24,17 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@c4a/agent-graph": "0.3.0",
27
- "@c4a/context": "0.7.55",
28
- "@c4a/extract": "0.7.55",
29
- "@c4a/extract-contract": "0.7.55",
30
- "@c4a/extract-go": "0.7.55",
31
- "@c4a/extract-mdx": "0.7.55",
32
- "@c4a/extract-proto": "0.7.55",
33
- "@c4a/extract-rush": "0.7.55",
34
- "@c4a/extract-sql": "0.7.55",
35
- "@c4a/extract-style": "0.7.55",
36
- "@c4a/extract-thrift": "0.7.55",
37
- "@c4a/extract-ts": "0.7.55",
27
+ "@c4a/context": "0.7.60",
28
+ "@c4a/extract": "0.7.60",
29
+ "@c4a/extract-contract": "0.7.60",
30
+ "@c4a/extract-go": "0.7.60",
31
+ "@c4a/extract-mdx": "0.7.60",
32
+ "@c4a/extract-proto": "0.7.60",
33
+ "@c4a/extract-rush": "0.7.60",
34
+ "@c4a/extract-sql": "0.7.60",
35
+ "@c4a/extract-style": "0.7.60",
36
+ "@c4a/extract-thrift": "0.7.60",
37
+ "@c4a/extract-ts": "0.7.60",
38
38
  "@mermaid-js/layout-elk": "0.2.0",
39
39
  "commander": "^11.0.0",
40
40
  "fast-xml-parser": "^5.10.1",
@@ -4535,7 +4535,7 @@ var init_siteTheme = __esm(() => {
4535
4535
  });
4536
4536
 
4537
4537
  // ../context/src/packageSite.ts
4538
- var siteHrefSchema, packageSiteHomeActionSchema, packageSiteHomeResourceSchema, packageSiteHomeSchema, packageSiteSchema;
4538
+ var siteHrefSchema, packageSiteHomeActionSchema, packageSiteHomeResourceSchema, packageSiteHomeSchema, localeTagSchema, localizedTextSchema, packageSiteLocaleSchema, packageSiteNavLinkSchema, packageSiteMoreItemSchema, packageSiteSocialLinkSchema, packageSiteSchema;
4539
4539
  var init_packageSite = __esm(() => {
4540
4540
  init_siteTheme();
4541
4541
  init_zod();
@@ -4562,6 +4562,32 @@ var init_packageSite = __esm(() => {
4562
4562
  actions: exports_external.array(packageSiteHomeActionSchema).optional(),
4563
4563
  resources: exports_external.array(packageSiteHomeResourceSchema).optional()
4564
4564
  }).strict();
4565
+ localeTagSchema = exports_external.string().regex(/^[a-zA-Z]{2,3}(?:-[a-zA-Z0-9]{2,8})*$/u, "Use a BCP 47 language tag, such as zh-CN");
4566
+ localizedTextSchema = exports_external.record(localeTagSchema, exports_external.string().trim().min(1));
4567
+ packageSiteLocaleSchema = exports_external.object({
4568
+ label: exports_external.string().trim().min(1).optional(),
4569
+ title: exports_external.string().trim().min(1).optional(),
4570
+ description: exports_external.string().optional(),
4571
+ home: packageSiteHomeSchema.optional()
4572
+ }).strict();
4573
+ packageSiteNavLinkSchema = exports_external.object({
4574
+ text: exports_external.string().trim().min(1),
4575
+ link: siteHrefSchema,
4576
+ locales: localizedTextSchema.optional()
4577
+ }).strict();
4578
+ packageSiteMoreItemSchema = exports_external.object({
4579
+ text: exports_external.string().trim().min(1),
4580
+ link: siteHrefSchema.optional(),
4581
+ target: exports_external.object({ artifact_ref: exports_external.string().trim().min(1) }).strict().optional(),
4582
+ locales: localizedTextSchema.optional()
4583
+ }).strict().refine((value) => value.link === undefined !== (value.target === undefined), {
4584
+ message: "A More menu item requires exactly one of link or target"
4585
+ });
4586
+ packageSiteSocialLinkSchema = exports_external.object({
4587
+ icon: exports_external.enum(["github", "discord", "x", "youtube", "slack", "linkedin", "mastodon", "npm"]),
4588
+ link: exports_external.string().regex(/^https:\/\//u, "Use an https URL"),
4589
+ ariaLabel: exports_external.string().trim().min(1).optional()
4590
+ }).strict();
4565
4591
  packageSiteSchema = exports_external.object({
4566
4592
  theme: siteThemeSchema.optional(),
4567
4593
  title: exports_external.string().trim().min(1).optional(),
@@ -4569,9 +4595,16 @@ var init_packageSite = __esm(() => {
4569
4595
  lang: exports_external.string().min(1).default("en-US"),
4570
4596
  base: exports_external.string().regex(/^\/(?:[a-zA-Z0-9_-]+\/)*$/, "Use / or a slash-delimited deployment path, such as /docs/").default("/"),
4571
4597
  home: packageSiteHomeSchema.optional(),
4598
+ locales: exports_external.record(localeTagSchema, packageSiteLocaleSchema).optional(),
4599
+ titleLink: siteHrefSchema.optional(),
4600
+ nav: exports_external.array(packageSiteNavLinkSchema).optional(),
4601
+ more: exports_external.array(packageSiteMoreItemSchema).optional(),
4602
+ socialLinks: exports_external.array(packageSiteSocialLinkSchema).optional(),
4603
+ localePreferenceKey: exports_external.string().regex(/^[a-zA-Z0-9:._-]+$/u).optional(),
4572
4604
  extensions: exports_external.object({
4573
4605
  root: exports_external.string().regex(/^src\/(?:[a-zA-Z0-9_-]+\/)*[a-zA-Z0-9_-]+$/).default("src/site"),
4574
4606
  slots: exports_external.object({
4607
+ brand: exports_external.string().min(1).optional(),
4575
4608
  banner: exports_external.union([exports_external.string().min(1), exports_external.literal(false)]).optional(),
4576
4609
  knowledge: exports_external.union([exports_external.string().min(1), exports_external.literal(false)]).optional(),
4577
4610
  resources: exports_external.union([exports_external.string().min(1), exports_external.literal(false)]).optional(),
@@ -4580,7 +4613,13 @@ var init_packageSite = __esm(() => {
4580
4613
  }).strict().optional(),
4581
4614
  pages: exports_external.record(exports_external.string().regex(/^[a-zA-Z0-9_-]+$/), exports_external.string().min(1)).optional()
4582
4615
  }).strict().optional()
4583
- }).strict();
4616
+ }).strict().superRefine((value, context) => {
4617
+ for (const tag of Object.keys(value.locales ?? {})) {
4618
+ if (tag.toLowerCase() === value.lang.toLowerCase()) {
4619
+ context.addIssue({ code: exports_external.ZodIssueCode.custom, path: ["locales", tag], message: "An additional locale must differ from the primary site lang" });
4620
+ }
4621
+ }
4622
+ });
4584
4623
  });
4585
4624
 
4586
4625
  // ../context/src/contracts.ts
package/plugins/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.55
1
+ 0.7.60
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "c4a",
3
3
  "description": "Start or continue a project-local knowledge workspace through one graph-routed entry.",
4
- "version": "0.7.55",
4
+ "version": "0.7.60",
5
5
  "author": {
6
6
  "name": "c4a"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c4a",
3
- "version": "0.7.55",
3
+ "version": "0.7.60",
4
4
  "description": "Start or continue a project-local knowledge workspace through one graph-routed entry.",
5
5
  "author": { "name": "c4a" },
6
6
  "homepage": "https://github.com/context4ai/c4a",
@@ -10,7 +10,7 @@
10
10
  "skills": "./skills/",
11
11
  "interface": {
12
12
  "displayName": "C4A Context",
13
- "shortDescription": "Initialize and advance a local, source-linked project knowledge workspace.\nv0.7.55",
13
+ "shortDescription": "Initialize and advance a local, source-linked project knowledge workspace.\nv0.7.60",
14
14
  "longDescription": "Create a Context workspace and use agent-guided next steps to register sources, run extraction, review candidates, build package outputs, and verify health without silently mutating source repositories.",
15
15
  "developerName": "c4a",
16
16
  "category": "Productivity",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "c4a",
3
3
  "displayName": "C4A Context",
4
- "version": "0.7.55",
4
+ "version": "0.7.60",
5
5
  "description": "Start or continue a project-local knowledge workspace through one graph-routed entry.",
6
6
  "author": {
7
7
  "name": "Context4AI",
@@ -0,0 +1,5 @@
1
+ schema: agent-graph.action.v1
2
+ id: translate-site-locales
3
+ runner: agent
4
+ effect: write
5
+ skill: skills/translate-site-locales/SKILL.md
@@ -10,6 +10,7 @@ codes:
10
10
  - { code: route.production.prepare-required, kind: route-reason, summary: Prepare the next eligible production directories. }
11
11
  - { code: route.production.writing-required, kind: route-reason, summary: Complete the issued production tasks using stage-local files. }
12
12
  - { code: route.production.scope-incomplete, kind: route-reason, summary: Resolve remaining investigation and material gaps without discarding accepted articles. }
13
+ - { code: route.translation.pending, kind: route-reason, summary: Translate approved knowledge for the website locales or publish it in the primary language. }
13
14
  - { code: route.version.content-changed, kind: route-reason, summary: Record an increasing workspace version and changelog for formal content changes. }
14
15
  - { code: route.workspace.recovery, kind: route-reason, summary: Inspect a stuck task independently of normal workflow evaluation., document: resources/procedures/task-recovery.md }
15
16
  - { code: route.indexer.maintenance, kind: route-reason, summary: Advance registered knowledge maintenance at a safe boundary., document: resources/procedures/knowledge-maintenance.md }
@@ -328,6 +328,18 @@ nodes:
328
328
  kind: terminal
329
329
  terminalOutcome: completed
330
330
 
331
+ - id: translate-site-locales
332
+ kind: action
333
+ reasonCode: route.translation.pending
334
+ action: actions/translate-site-locales.yaml
335
+ satisfiedBy:
336
+ - path: translation.route_satisfied
337
+ equals: true
338
+ resources:
339
+ recommended:
340
+ - resources/manuals/guides/site-translation.md
341
+ - resources/manuals/guides/package-outputs.md
342
+
331
343
  - id: record-workspace-version
332
344
  kind: action
333
345
  reasonCode: route.version.content-changed
@@ -350,7 +362,8 @@ edges:
350
362
  - { from: close-approved-knowledge, to: choose-package-output }
351
363
  - { from: choose-package-output, to: configure-package-output, kind: gatedBy }
352
364
  - { from: configure-package-output, to: review-package-template }
353
- - { from: review-package-template, to: record-workspace-version, kind: gatedBy }
365
+ - { from: review-package-template, to: translate-site-locales, kind: gatedBy }
366
+ - { from: translate-site-locales, to: record-workspace-version }
354
367
  - { from: record-workspace-version, to: build-next }
355
368
  - { from: build-next, to: flush-logs-after-build }
356
369
  - { from: flush-logs-after-build, to: current-scope-complete }
@@ -2,7 +2,7 @@
2
2
  "schema": "agent-graph.bundle.v1",
3
3
  "provider": {
4
4
  "id": "c4a/context",
5
- "version": "0.7.55"
5
+ "version": "0.7.60"
6
6
  },
7
7
  "providerManifest": "provider.yaml",
8
8
  "graphs": [
@@ -14,7 +14,7 @@
14
14
  {
15
15
  "id": "workspace",
16
16
  "path": "graphs/workspace.yaml",
17
- "digest": "sha256:ba5d93d4883c28e9dfd21829528684d8d6ad9b1523d5e1895b67dc5106b43f7c"
17
+ "digest": "sha256:f72cdb49e298f081c148bf2b58929a415f93890450522da8fd0ab09ec30b2f92"
18
18
  }
19
19
  ],
20
20
  "actions": [
@@ -153,6 +153,11 @@
153
153
  "path": "actions/run-indexer-lifecycle.yaml",
154
154
  "digest": "sha256:1de783b14a3558f4ef540a42515a04c37f91a66d3266233834d9d5fbf09158c3"
155
155
  },
156
+ {
157
+ "id": "translate-site-locales",
158
+ "path": "actions/translate-site-locales.yaml",
159
+ "digest": "sha256:28f5e4ef974197b2533319e019e32cb5e5b8899fb47b8cd8706a4b0c16bb4b9b"
160
+ },
156
161
  {
157
162
  "id": "work-production-stage",
158
163
  "path": "actions/work-production-stage.yaml",
@@ -188,7 +193,7 @@
188
193
  {
189
194
  "id": "context.sdk.package-outputs",
190
195
  "path": "resources/manuals/guides/package-outputs.md",
191
- "digest": "sha256:000255fafc7794d2c82880aa2cfcab7126929850ea6b77a29cecb272c9fd1683"
196
+ "digest": "sha256:b148a151ab78f64b9f35eecf300931c1dfe6b593dcd170cda2e7aed103ed43ad"
192
197
  },
193
198
  {
194
199
  "id": "context.sdk.package-templates",
@@ -198,12 +203,17 @@
198
203
  {
199
204
  "id": "context.sdk.page-customization",
200
205
  "path": "resources/manuals/guides/page-customization.md",
201
- "digest": "sha256:57695bbbe3223c3c695029747856baae9e230059848e8f37506f908e843f9b0e"
206
+ "digest": "sha256:c8ba4cfe671f68a5bd27187e6f3c4d68a4c014f1f7018baaebf088decc404755"
202
207
  },
203
208
  {
204
209
  "id": "context.sdk.project-api",
205
210
  "path": "resources/manuals/reference/project-api.md",
206
- "digest": "sha256:d7af120518aa721f06ae2233a824a674b50eee5096244d1b9eb5efb659f8ea90"
211
+ "digest": "sha256:50a520214d64ef465a3048eaf9880ac20c95140b4be74d885a8a9ba493ba5531"
212
+ },
213
+ {
214
+ "id": "context.sdk.site-translation",
215
+ "path": "resources/manuals/guides/site-translation.md",
216
+ "digest": "sha256:369ffdc81481e48843891f5e007129d38047e4077a693b3bc58fa6c8e8f86666"
207
217
  },
208
218
  {
209
219
  "id": "context.sdk.template-variables",
@@ -557,13 +567,17 @@
557
567
  "path": "actions/run-indexer-lifecycle.yaml",
558
568
  "digest": "sha256:1de783b14a3558f4ef540a42515a04c37f91a66d3266233834d9d5fbf09158c3"
559
569
  },
570
+ {
571
+ "path": "actions/translate-site-locales.yaml",
572
+ "digest": "sha256:28f5e4ef974197b2533319e019e32cb5e5b8899fb47b8cd8706a4b0c16bb4b9b"
573
+ },
560
574
  {
561
575
  "path": "actions/work-production-stage.yaml",
562
576
  "digest": "sha256:d03f6a3bc90ae2f9ab266a58c55e36b4d8af364dc701d3ea4db4696a05fdb1f8"
563
577
  },
564
578
  {
565
579
  "path": "codes.yaml",
566
- "digest": "sha256:89f188064a3d1a46b4a4356a5d20edf06cc93a5d2cd89f87618324369aa3b2b8"
580
+ "digest": "sha256:a4d4b0dccf5d2146e91f7baa1fe16e34d8c410fd1096e9ad9a75214a9006ee22"
567
581
  },
568
582
  {
569
583
  "path": "graphs/indexer.yaml",
@@ -571,11 +585,11 @@
571
585
  },
572
586
  {
573
587
  "path": "graphs/workspace.yaml",
574
- "digest": "sha256:ba5d93d4883c28e9dfd21829528684d8d6ad9b1523d5e1895b67dc5106b43f7c"
588
+ "digest": "sha256:f72cdb49e298f081c148bf2b58929a415f93890450522da8fd0ab09ec30b2f92"
575
589
  },
576
590
  {
577
591
  "path": "provider.yaml",
578
- "digest": "sha256:728b4b7df2a248903d6108df23e5e8b2538c1ee1c50f40b5dbe2c05d4c9bdb63"
592
+ "digest": "sha256:b345fe294b44ff2a0b37201fe76a164a802f8d06a7b0597402a15d2d005b4ab6"
579
593
  },
580
594
  {
581
595
  "path": "resources/contracts/indexer-provider-guide.yaml",
@@ -651,11 +665,11 @@
651
665
  },
652
666
  {
653
667
  "path": "resources/manuals/guides/package-outputs.md",
654
- "digest": "sha256:000255fafc7794d2c82880aa2cfcab7126929850ea6b77a29cecb272c9fd1683"
668
+ "digest": "sha256:b148a151ab78f64b9f35eecf300931c1dfe6b593dcd170cda2e7aed103ed43ad"
655
669
  },
656
670
  {
657
671
  "path": "resources/manuals/guides/page-customization.md",
658
- "digest": "sha256:57695bbbe3223c3c695029747856baae9e230059848e8f37506f908e843f9b0e"
672
+ "digest": "sha256:c8ba4cfe671f68a5bd27187e6f3c4d68a4c014f1f7018baaebf088decc404755"
659
673
  },
660
674
  {
661
675
  "path": "resources/manuals/guides/repo-content.md",
@@ -665,6 +679,10 @@
665
679
  "path": "resources/manuals/guides/sessions.md",
666
680
  "digest": "sha256:b1d86d1fb96f1caba5baf7859bf20ac43e4fe890a40db453727cf2627d44fac6"
667
681
  },
682
+ {
683
+ "path": "resources/manuals/guides/site-translation.md",
684
+ "digest": "sha256:369ffdc81481e48843891f5e007129d38047e4077a693b3bc58fa6c8e8f86666"
685
+ },
668
686
  {
669
687
  "path": "resources/manuals/guides/source-batches.md",
670
688
  "digest": "sha256:9e338332986deab67932e62398db0221a7be139ac056f0856a46738164df411e"
@@ -691,7 +709,7 @@
691
709
  },
692
710
  {
693
711
  "path": "resources/manuals/reference/project-api.md",
694
- "digest": "sha256:d7af120518aa721f06ae2233a824a674b50eee5096244d1b9eb5efb659f8ea90"
712
+ "digest": "sha256:50a520214d64ef465a3048eaf9880ac20c95140b4be74d885a8a9ba493ba5531"
695
713
  },
696
714
  {
697
715
  "path": "resources/manuals/reference/template-variables.md",
@@ -863,7 +881,7 @@
863
881
  },
864
882
  {
865
883
  "path": "skills/record-workspace-version/SKILL.md",
866
- "digest": "sha256:695b6b384a94743de08451f447bc8a135b6a7446dfab8e9b52ae16de54fd2903"
884
+ "digest": "sha256:87cf750c65ddcf7182c58ea7f60d507cb5c2c2366815303f950faa07084341d6"
867
885
  },
868
886
  {
869
887
  "path": "skills/recover-workspace/SKILL.md",
@@ -881,6 +899,10 @@
881
899
  "path": "skills/run-indexer-lifecycle/SKILL.md",
882
900
  "digest": "sha256:e56bf044855a3a66aa75a12d16ecba730b11a1e695f1ce75f2ea0af81384a011"
883
901
  },
902
+ {
903
+ "path": "skills/translate-site-locales/SKILL.md",
904
+ "digest": "sha256:b5197f6568b1443022d631f661d7484291c9be512b78109f91e6b42806294e7e"
905
+ },
884
906
  {
885
907
  "path": "skills/work-production-stage/SKILL.md",
886
908
  "digest": "sha256:676289693df57b5887f104d751dd9c8cc73fb1c903e4df7088f110ef6147388a"
@@ -890,5 +912,5 @@
890
912
  "indexer": [],
891
913
  "workspace": []
892
914
  },
893
- "digest": "sha256:53f022509a8a69dbf8e50b826083bb143997a758aa8d212614d4b72d020a7909"
915
+ "digest": "sha256:a96b398fb201f27c2c8af56ab7a17c8d50fba2742eb35bc0e2f60f50da7977ef"
894
916
  }
@@ -1,6 +1,6 @@
1
1
  schema: agent-graph.provider.v1
2
2
  id: c4a/context
3
- version: 0.7.55
3
+ version: 0.7.60
4
4
  name: Context workflow
5
5
  description: Internal work contract for Context knowledge workspaces.
6
6
  graphs:
@@ -108,10 +108,14 @@ screens the homepage content aligns with article content while preserving the
108
108
  sidebar rail; on narrow screens it uses the available width. Motion is limited
109
109
  to short card entrance and hover feedback and is disabled when the reader asks
110
110
  the operating system to reduce motion.
111
- The website uses a full-width VitePress theme with system fonts, compact navigation,
112
- a wide reading area and a smaller article outline. It starts in
113
- light mode regardless of the operating system; an explicit reader choice is
114
- remembered in browser storage. Search runs locally, without a search service.
111
+ The website uses a VitePress theme with system fonts and compact navigation. The
112
+ top bar, homepage and articles share a centered 1440px container with 32px
113
+ margins (16px on phones); on wide screens the sidebar sits at its left edge and
114
+ articles keep a wide reading area and a smaller outline. Navigation is centered
115
+ in the top bar, which ends with icon buttons for search, theme, social links and
116
+ reader language; search, or Cmd/Ctrl+K, opens a dialog over a blurred page. The theme follows the
117
+ operating system until the reader switches it; that choice is remembered in
118
+ browser storage. Search runs locally, without a search service.
115
119
  Mermaid renders in the browser using the website theme, with fit, original-size,
116
120
  zoom, full-screen and source controls. Controls appear on hover or keyboard focus
117
121
  (and remain visible on touch devices). Layout and source/copy actions are on the
@@ -141,6 +145,32 @@ reachable as linked read-only pages, but have no automatically added navigation
141
145
  section. A reader-facing usage guide can link them where appropriate.
142
146
  Section landing pages have stable URLs separate from article URLs.
143
147
 
148
+ `site.nav` appends links after the reading directories, and `site.more` adds
149
+ items to the More menu before LLM Docs and Changelog. A More item uses either
150
+ `link` or `target: { artifact_ref }`; a target is an approved article kept
151
+ outside the knowledge map (for example release notes or a contribution guide),
152
+ so it is not reported as unplaced. A missing target blocks the build. Links that
153
+ start with `/` are origin paths, such as a sibling application on the same
154
+ domain, and are not prefixed with `site.base`. `locales` on a nav or More item
155
+ translates its text per language tag. `socialLinks` adds icon links in the top
156
+ bar; each requires an `https` URL.
157
+
158
+ `site.locales` adds reader languages, for example
159
+ `locales: { "zh-CN": { title: "项目知识" } }`. Every page keeps one URL and
160
+ carries each language; the reader's language decides which one is shown, so
161
+ links, navigation and custom pages need no per-language routes. Each locale may
162
+ override `label`, `title`, `description` and `home`. Translations are stored in
163
+ the workspace under `translations/<tag>/` and follow the
164
+ [site translation](site-translation.md) procedure. The top bar language button
165
+ switches the current page in place. A saved choice wins, then the browser
166
+ languages, then `site.lang`; the choice is remembered under
167
+ `site.localePreferenceKey` (default `context-locale:<package>:<base>`), which
168
+ sites on one origin can share. Pages without a current translation show the
169
+ original with a notice. LLM Docs and Changelog stay in the primary language.
170
+ `context-site-map.json` lists translated, stale and missing counts per locale.
171
+ Without `site.locales` the button still switches the interface between Chinese
172
+ and English.
173
+
144
174
  `dist/<base>-site/context-site-map.json` records each article's approved path, KB path and
145
175
  site path, plus the projected menu and unresolved targets. URLs are derived from
146
176
  article identity; legacy pages without `artifact_ref` use their approved path,
@@ -38,11 +38,27 @@ credentials or private configuration in frontend files. Hidden files,
38
38
  | `resources` | Resource card group | Replace with a component |
39
39
  | `footer` | Existing homepage footer | Replace with a component |
40
40
  | `floating` | Empty | Client-only component fixed at the bottom right on all pages |
41
+ | `brand` | Site title text | Component shown at the start of the top bar, for example a logo |
42
+
43
+ `site.titleLink` sets where the top-bar title leads; it defaults to the site
44
+ home. A root-relative link such as `/` addresses the site origin rather than
45
+ the site `base`, so a documentation site under `/docs/` can return to a product
46
+ homepage.
41
47
 
42
48
  Omit a slot to retain its default; set it to `false` to hide it. A component
43
49
  replaces only its slot, not the global navigation, language switch or article
44
50
  provenance. Components can use VitePress `useData()` and `useRoute()` for theme,
45
51
  page and route information. Import scoped CSS from components for local styling.
52
+ Pages prerender in the light theme. For a reader who starts in the dark theme,
53
+ slot components are mounted again after the page loads, so markup bound to
54
+ `isDark` matches the reader's theme.
55
+
56
+ Pages keep one URL for every reader language. `useData().lang` is the reader's
57
+ language after mount and `site.lang` during static rendering;
58
+ `theme.contextLocales` lists `primary`, `tags` and `labels`. To show the right
59
+ language from the first paint, render each language and mark it with
60
+ `data-context-locales="<tag>"` (a space-separated list for shared content); the
61
+ site stylesheet hides the others.
46
62
 
47
63
  The floating component owns its button, chat/bot panel and open/close behavior.
48
64
  Keep its panel within the viewport and preserve keyboard focus and close controls.
@@ -0,0 +1,78 @@
1
+ ---
2
+ id: context.sdk.site-translation
3
+ kind: procedure
4
+ mediaType: text/markdown
5
+ ---
6
+
7
+ # Site translation
8
+
9
+ A knowledge package website can publish translated copies of approved
10
+ knowledge for each language tag declared in `site.locales`. Approved knowledge
11
+ in the primary language remains the only source of truth; translations are a
12
+ reader projection and never change Review, Verify or the KB output.
13
+
14
+ ## Storage
15
+
16
+ | Path | Content |
17
+ | --- | --- |
18
+ | `translations/<tag>/<approved-path>.md` | Translated article. Frontmatter holds `title`, optional `description` and a `translation` record with `locale`, `artifact_ref`, `source_digest` and `translated_at`. |
19
+ | `translations/<tag>/knowledge-map.yaml` | Translated navigation titles keyed by knowledge map entry `key`. |
20
+
21
+ `<approved-path>` is the path below `knowledge/`. Translations are formal
22
+ workspace content: they are included in workspace versions and package
23
+ fingerprints, so changing one rebuilds the website.
24
+
25
+ ## Freshness
26
+
27
+ Each translation records the digest of the approved title, description and
28
+ body it was written from. A translation is `current` when the digest matches,
29
+ `stale` when the approved article changed, and `missing` when no file exists.
30
+ Runtime metadata changes do not make a translation stale. Files whose approved
31
+ article no longer exists are reported as orphans and removed by the next
32
+ submission.
33
+
34
+ When a package declares locales and any item is not current, the workspace Route
35
+ selects `translate-site-locales` after package template approval and before the
36
+ workspace version is recorded.
37
+
38
+ ## Commands
39
+
40
+ ```bash
41
+ context translate status --format json
42
+ context translate prepare --format json
43
+ context translate submit --input <file> --format json
44
+ context translate skip --digest <expected_digest> --format json
45
+ ```
46
+
47
+ `prepare` lists each pending article and navigation title with
48
+ `expected_digest`. `submit` accepts:
49
+
50
+ ```yaml
51
+ expected_digest: <from prepare>
52
+ articles:
53
+ - locale: zh-CN
54
+ approved_path: knowledge/codeindex/app/start.md
55
+ file: .tmp/agent-payloads/translations/zh-CN/codeindex/app/start.md
56
+ map_entries:
57
+ - locale: zh-CN
58
+ key: getting-started
59
+ title: 入门
60
+ ```
61
+
62
+ A translated article keeps every `context:section` marker, id and order, every
63
+ fenced code block with its language and content (Mermaid labels may change), and
64
+ every link target. Submission validates all items first and saves nothing when
65
+ any item fails. A digest from before an approved content change is rejected.
66
+
67
+ `skip` records that the current pending items are published in the primary
68
+ language. Use it only when the user declines translation for this iteration;
69
+ the next approved change asks again.
70
+
71
+ ## Website
72
+
73
+ Each page is published once and contains every language; the reader's language
74
+ selects what is shown at the same URL. A stale page shows the translation with
75
+ an outdated notice and a button that switches to the original; a missing page
76
+ shows the original with a notice. Navigation titles without a translation use
77
+ the translated article title, then the primary title. Site search covers every
78
+ language; opening a result in another language switches to it.
@@ -189,7 +189,8 @@ may be rebuilt; it is not an authoring source.
189
189
  `kbPackage.site` optionally adds a VitePress website at `dist/<base>-site/` in
190
190
  the same build, beside the KB directory. `<base>` removes one trailing `-kb`
191
191
  from the package name, if present. Omit it for KB-only output. It accepts `title`, `description`,
192
- `lang`, a deployment `base` path, and an optional `home` presentation. `home`
192
+ `lang`, a deployment `base` path, an optional top-bar `titleLink`, and an
193
+ optional `home` presentation. `home`
193
194
  accepts `title`, `slogan`, `description`, hero `actions`, and `resources` shown
194
195
  below the generated site map. Each resource needs an `href`, a copyable
195
196
  `command`, or both. Omit unknown resources; the builder never invents service
@@ -9,7 +9,8 @@ checks real changes and an increasing SemVer; you decide the wording and impact.
9
9
  Do not summarize temporary execution progress as knowledge changes.
10
10
 
11
11
  This action is selected at completed-scope delivery, after Review, Close and
12
- package configuration/template approval, before the final package build.
12
+ package configuration/template approval and website translation, before the final
13
+ package build.
13
14
  Record one version for the completed scope, then follow the returned workspace
14
15
  Route to build outputs with that version. A failed build alone does not require
15
16
  another version; retry through the Route using the recorded version. Do not
@@ -26,7 +27,7 @@ Use the returned digest in `context version record --input <file> --format json`
26
27
  Input fields: `expected_digest`, `version`, `title`, `changes` (nonempty list),
27
28
  `triggers` (nonempty list of `{kind, description}`), and optional
28
29
  `actor: {name, kind}`. Trigger kinds are initial, note, sessions, mr, module,
29
- document, navigation, repair, dist, other. Describe what actually triggered the
30
+ document, navigation, repair, dist, translation, other. Describe what actually triggered the
30
31
  iteration, not merely the CLI command. Never include raw private transcripts,
31
32
  credentials, local absolute paths or private account IDs in public history.
32
33
 
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: translate-site-locales
3
+ description: Translate approved knowledge for the website locales declared in site.locales when the workspace Route selects this action.
4
+ ---
5
+
6
+ Run `context translate prepare --format json`. The task lists every article and
7
+ knowledge map title that is missing or stale for each declared locale, with the
8
+ `expected_digest` to submit. Approved knowledge in the primary language remains
9
+ the only source of truth; translations never change it.
10
+
11
+ For each article, read the approved file and write a complete translation to a
12
+ temporary file under `.tmp/agent-payloads/`. Keep its structure exactly:
13
+
14
+ - frontmatter contains only a translated `title` and optional `description`;
15
+ - keep every `context:section` marker, id and order unchanged;
16
+ - keep every fenced code block, language and content unchanged; only Mermaid
17
+ labels may be translated;
18
+ - keep every link target unchanged; translate link labels only;
19
+ - keep product names, commands, file paths, identifiers and API names as written.
20
+
21
+ Translate knowledge map titles as short navigation labels. Submit with
22
+ `context translate submit --input <file> --format json`. Input fields:
23
+ `expected_digest`, `articles` (list of `{locale, approved_path, file}`) and
24
+ `map_entries` (list of `{locale, key, title}`). Validation is all-or-nothing:
25
+ fix each reported item and submit again. A large task may be submitted in
26
+ several batches with the same digest; untranslated pages show the original with
27
+ a notice.
28
+
29
+ When the user declines translation for this iteration, run
30
+ `context translate skip --digest <expected_digest> --format json`. The website
31
+ then publishes the pending pages in the primary language with a notice. Do not
32
+ skip on your own judgment.
33
+
34
+ Consume the returned `workflow.current` directly. In managed mode resume
35
+ `context run --managed --until blocked-or-complete --format json`. Translating
36
+ does not authorize a commit, upload or deployment.