@c4a/context 0.7.50 → 0.7.55

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/docs/README.md CHANGED
@@ -22,6 +22,7 @@ preload the whole manual set.
22
22
 
23
23
  | Current need | Read |
24
24
  |---|---|
25
+ | Associate external knowledge, Skills or plugins without copying them | [External associations](./guides/imports.md) |
25
26
  | Customize website pages, homepage slots or a floating chat widget | [Page Content Customization](./guides/page-customization.md) |
26
27
  | Understand the whole knowledge-project shape | [Getting Started](./getting-started.md) |
27
28
  | Know what the Agent may decide or change | [Agent Guide](./guides/agent-guide.md) and [Agent Dialogue](./guides/agent-dialogue.md) |
@@ -13,6 +13,7 @@
13
13
 
14
14
  | 当前需要 | 阅读内容 |
15
15
  |---|---|
16
+ | 关联外部知识、Skill 或插件,不复制内容 | [外部关联](./guides/imports.md) |
16
17
  | 理解完整知识项目的形态 | [Getting Started](./getting-started.md) |
17
18
  | 判断 Agent 可以决定或修改什么 | [Agent Guide](./guides/agent-guide.md) 和 [Agent Dialogue](./guides/agent-dialogue.md) |
18
19
  | 配置来源、采集、Indexer 或产物 | [Project API](./reference/project-api.md) |
@@ -0,0 +1,84 @@
1
+ # External associations
2
+
3
+ Workspace-root `imports.yaml` declares external entrances without downloading,
4
+ installing or capturing their contents. Maintain it through the Context entry when
5
+ the task requests a lasting association. Temporary query reads do not register
6
+ dependencies. Same-repository authored documents and Skills use
7
+ [repo-content](repo-content.md) instead.
8
+
9
+ ```yaml
10
+ protocol: context.imports/v1
11
+ imports:
12
+ engineering-guide:
13
+ kind: knowledge
14
+ url: https://docs.example.org/engineering/
15
+ description: Engineering conventions
16
+ release-check:
17
+ kind: skill
18
+ url: https://github.com/example/skills/tree/v1/skills/release-check
19
+ path: skills/release-check
20
+ version: v1
21
+ ```
22
+
23
+ The stable ID and `url` are required. `kind`, `format`, `title`, `description`,
24
+ `path` and `version` are optional. Kind and format are open strings; versions are
25
+ opaque hints, not necessarily SemVer. Paths are source-relative without traversal.
26
+ Reader URLs must be HTTP(S), without credentials or whitespace; this is local
27
+ syntax validation, not a provider whitelist or availability check. Do not put
28
+ access tokens in query strings. The SDK exports `importsRegistrySchema` for local
29
+ validation. Unknown providers and offline operation do not cause network checks.
30
+
31
+ Use a new ID when replacing the source identity. A declaration is neither proof
32
+ of reading nor an installation record. Do not expand transitive imports or infer
33
+ permission from a readable service. Only relevant originals are read through
34
+ existing host tools. Installed capability identity belongs to the host, not a
35
+ Context lock file.
36
+
37
+ ## Entrances and evidence
38
+
39
+ An import is a reader entrance, not recorded evidence. It adds no entry to
40
+ `knowledge/structure.yaml` `references[]`, produces no review hint and has no
41
+ `import:` reference format. When an article's conclusion must be traceable or
42
+ tracked for change, register the needed external content as a source and capture
43
+ it; the import can remain as the reader entrance.
44
+
45
+ The CLI never contacts providers or compares versions. When asked to update or
46
+ check imports, the Agent observes current versions with existing authorized host
47
+ tools and compares them with `version`. Unreachable, unauthorized or failed checks
48
+ are reported as "version unknown" and are never treated as a change.
49
+
50
+ ## Links and output
51
+
52
+ `[Engineering guide](context:import/engineering-guide)` in an article projects to
53
+ the declared URL. Build never guesses a provider-specific URL, appends `path` or
54
+ rewrites the version. Use an entrance that already opens the intended target.
55
+ Missing IDs keep the reader label as non-clickable text and produce a build link
56
+ warning. An invalid or unreadable declaration skips the optional directory and
57
+ degrades affected links the same way; unrelated outputs still build. Correct
58
+ `imports.yaml` or the article link to restore navigation. Merely registering
59
+ entries emits no page.
60
+
61
+ For an optional declaration-only directory:
62
+
63
+ ```ts
64
+ kbPackage({
65
+ name: "handbook",
66
+ template: { path: "src/package-templates/kb" },
67
+ importsPage: true,
68
+ })
69
+ ```
70
+
71
+ This generates `wikis/imports.md` and includes it in package navigation. With an
72
+ existing `site` configuration, `importsPage: { site: true }` also adds a website
73
+ navigation item. `false` or omission disables generation. Initialization enables
74
+ the package directory when a valid `imports.yaml` already exists. An invalid
75
+ declaration is preserved with a warning; initialization continues without enabling
76
+ that directory. When first configuring
77
+ a new workspace's KB later, enable it if the declaration is present; preserve
78
+ existing settings and explicit user choices. The directory contains only declared metadata,
79
+ not approved article bodies or installation commands. Check audience suitability
80
+ before exposing private entrances.
81
+
82
+ Navigation links are not source evidence. Imports declaration support alone does
83
+ not authorize fabricated `import:` fragment references or advancement of article
84
+ evidence baselines.
@@ -29,6 +29,19 @@ empty diff. Inspect/edit does not advance references; delivery or an explicit
29
29
  no-impact outcome settles the selected scope. Historical locators always store
30
30
  the real repository path at the cited commit, not today's registration path.
31
31
 
32
+ External associations in `imports.yaml` are entrances, not recorded evidence:
33
+ they create no `references[]` and no review hints, and the CLI never checks
34
+ their versions. When the user asks to update or check external associations,
35
+ use existing authorized Host tools (for example `git ls-remote`, a package
36
+ manager or a web read) to observe each selected entry's current version and
37
+ compare it with its optional `version`. If it differs, read only what the
38
+ linked articles rely on, report whether they need revision and update
39
+ `version` once settled. Unreachable, unauthorized or failed checks are
40
+ "version unknown": report them, keep `version` unchanged, and never treat them
41
+ as changed. When an article's conclusion must trace or track external content,
42
+ register the needed part as a source and capture it; do not cite the
43
+ association itself as evidence.
44
+
32
45
  Before starting production, compare the proposed content with the workspace's
33
46
  reader purpose. For clearly unrelated anecdotes or personal rankings, briefly
34
47
  recommend leaving them out of the formal manual or saving them separately because
@@ -22,6 +22,14 @@ Same-repository originals have an optional [repository entrance](repo-content.md
22
22
  not the full document tree. It does not expose that page on a configured website;
23
23
  use `repoContentPage: { site: true }` to opt in. Existing declarations are kept.
24
24
 
25
+ External associations have an optional [directory](imports.md): `importsPage: true`
26
+ generates `wikis/imports.md` from declarations only; `{ site: true }` also exposes
27
+ it on a configured website. Neither option downloads or installs external content.
28
+
29
+ When first declaring a KB for a new workspace, enable `repoContentPage: true`
30
+ if `repo-content.yaml` exists and `importsPage: true` if `imports.yaml` exists.
31
+ Keep existing package settings and explicit user choices; website exposure stays opt-in.
32
+
25
33
  Output channels support multiple selection. In a new workspace without explicit
26
34
  preferences, the Agent proposes and configures KB + website as the default. Honor
27
35
  user feedback, session authority and existing workspace declarations; LLMS is an
package/imports.d.ts ADDED
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ /** Validate a portable reader entrance, never contact its provider. */
3
+ export declare const importUrlSchema: z.ZodEffects<z.ZodString, string, string>;
4
+ export declare const importIdSchema: z.ZodString;
5
+ export declare const importEntrySchema: z.ZodObject<{
6
+ url: z.ZodEffects<z.ZodString, string, string>;
7
+ kind: z.ZodOptional<z.ZodString>;
8
+ format: z.ZodOptional<z.ZodString>;
9
+ title: z.ZodOptional<z.ZodString>;
10
+ description: z.ZodOptional<z.ZodString>;
11
+ path: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
12
+ version: z.ZodOptional<z.ZodString>;
13
+ }, "strict", z.ZodTypeAny, {
14
+ url: string;
15
+ path?: string | undefined;
16
+ title?: string | undefined;
17
+ description?: string | undefined;
18
+ kind?: string | undefined;
19
+ version?: string | undefined;
20
+ format?: string | undefined;
21
+ }, {
22
+ url: string;
23
+ path?: string | undefined;
24
+ title?: string | undefined;
25
+ description?: string | undefined;
26
+ kind?: string | undefined;
27
+ version?: string | undefined;
28
+ format?: string | undefined;
29
+ }>;
30
+ export declare const importsRegistrySchema: z.ZodObject<{
31
+ protocol: z.ZodLiteral<"context.imports/v1">;
32
+ imports: z.ZodRecord<z.ZodString, z.ZodObject<{
33
+ url: z.ZodEffects<z.ZodString, string, string>;
34
+ kind: z.ZodOptional<z.ZodString>;
35
+ format: z.ZodOptional<z.ZodString>;
36
+ title: z.ZodOptional<z.ZodString>;
37
+ description: z.ZodOptional<z.ZodString>;
38
+ path: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
39
+ version: z.ZodOptional<z.ZodString>;
40
+ }, "strict", z.ZodTypeAny, {
41
+ url: string;
42
+ path?: string | undefined;
43
+ title?: string | undefined;
44
+ description?: string | undefined;
45
+ kind?: string | undefined;
46
+ version?: string | undefined;
47
+ format?: string | undefined;
48
+ }, {
49
+ url: string;
50
+ path?: string | undefined;
51
+ title?: string | undefined;
52
+ description?: string | undefined;
53
+ kind?: string | undefined;
54
+ version?: string | undefined;
55
+ format?: string | undefined;
56
+ }>>;
57
+ }, "strict", z.ZodTypeAny, {
58
+ protocol: "context.imports/v1";
59
+ imports: Record<string, {
60
+ url: string;
61
+ path?: string | undefined;
62
+ title?: string | undefined;
63
+ description?: string | undefined;
64
+ kind?: string | undefined;
65
+ version?: string | undefined;
66
+ format?: string | undefined;
67
+ }>;
68
+ }, {
69
+ protocol: "context.imports/v1";
70
+ imports: Record<string, {
71
+ url: string;
72
+ path?: string | undefined;
73
+ title?: string | undefined;
74
+ description?: string | undefined;
75
+ kind?: string | undefined;
76
+ version?: string | undefined;
77
+ format?: string | undefined;
78
+ }>;
79
+ }>;
80
+ export type ImportEntry = z.infer<typeof importEntrySchema>;
81
+ export type ImportsRegistry = z.infer<typeof importsRegistrySchema>;
package/index.d.ts CHANGED
@@ -5,6 +5,7 @@ import type { PackageNavigationDefinition, PackageSelectDefinition } from "./con
5
5
  import type { PhaseDefinition, PhaseResourceReference } from "./phases.js";
6
6
  import type { ProjectSourceDefinition } from "./sources.js";
7
7
  export * from "./indexerCoreExports.js";
8
+ export { importsRegistrySchema, importEntrySchema, importUrlSchema, importIdSchema, type ImportEntry, type ImportsRegistry } from "./imports.js";
8
9
  export { repoContentRegistrySchema, repoContentEntrySchema, repoContentPathSchema, repoContentMount, parseRepoContentRef, repoContentScopeMatches, type RepoContentEntry, type RepoContentRegistry } from "./repoContent.js";
9
10
  export { indexerComposerContractSchema, indexerComposerDeclarationSchema, indexerExecutionSchema, indexerProviderLayerFragmentSchema, indexerProviderManifestSchema, indexerProviderOperationSchema, indexerToolSourceDeclarationSchema, isIndexerLayerFragmentKind, isIndexerProviderProtocol, loadIndexerProviderManifest, parseIndexerProviderManifest, } from "./indexerProvider.js";
10
11
  export type { IndexerComposerContract, IndexerComposerDeclaration, IndexerExecution, IndexerProviderLayerFragment, IndexerProviderManifest, IndexerProviderOperation, IndexerToolSourceDeclaration, } from "./indexerProvider.js";
@@ -113,6 +114,9 @@ export type KbPackageDefinition = BasePackageDefinition & {
113
114
  repoContentPage?: boolean | {
114
115
  site: true;
115
116
  };
117
+ importsPage?: boolean | {
118
+ site: true;
119
+ };
116
120
  };
117
121
  export type LlmsPackageDefinition = BasePackageDefinition & {
118
122
  kind: "package.llms";
@@ -139,6 +143,9 @@ export declare const kbPackage: (definition: {
139
143
  repoContentPage?: boolean | {
140
144
  site: true;
141
145
  };
146
+ importsPage?: boolean | {
147
+ site: true;
148
+ };
142
149
  }) => KbPackageDefinition;
143
150
  export declare const llmsPackage: (definition: {
144
151
  name: string;
package/index.js CHANGED
@@ -22166,6 +22166,32 @@ function repoContentScopeMatches(scope, reference) {
22166
22166
  const cited = parseRepoContentRef(reference);
22167
22167
  return !!selected && !selected.commit && !!cited && selected.id === cited.id;
22168
22168
  }
22169
+
22170
+ // src/imports.ts
22171
+ var importUrlSchema = exports_external.string().min(1).refine((value) => {
22172
+ if (!/^https?:\/\/[^/?#\\]/iu.test(value) || /[\s\u0000-\u001f\u007f<>\\]/u.test(value))
22173
+ return false;
22174
+ try {
22175
+ const url = new URL(value);
22176
+ return ["https:", "http:"].includes(url.protocol) && !!url.hostname && !url.username && !url.password;
22177
+ } catch {
22178
+ return false;
22179
+ }
22180
+ }, "Use an absolute http:// or https:// entrance without credentials, whitespace or backslashes");
22181
+ var importIdSchema = exports_external.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]*$/u);
22182
+ var importEntrySchema = exports_external.object({
22183
+ url: importUrlSchema,
22184
+ kind: exports_external.string().min(1).optional(),
22185
+ format: exports_external.string().min(1).optional(),
22186
+ title: exports_external.string().min(1).optional(),
22187
+ description: exports_external.string().optional(),
22188
+ path: repoContentPathSchema.optional(),
22189
+ version: exports_external.string().min(1).optional()
22190
+ }).strict();
22191
+ var importsRegistrySchema = exports_external.object({
22192
+ protocol: exports_external.literal("context.imports/v1"),
22193
+ imports: exports_external.record(importIdSchema, importEntrySchema)
22194
+ }).strict();
22169
22195
  // src/indexerRequirementComparison.ts
22170
22196
  function setRelation(oldValues, newValues) {
22171
22197
  const oldContained = [...oldValues].every((value) => newValues.has(value));
@@ -32306,6 +32332,12 @@ var kbPackage = (definition) => {
32306
32332
  const distribution = normalizePackageDistribution(definition.distribution);
32307
32333
  const assets = normalizePackageAssets(definition.assets);
32308
32334
  const site = normalizePackageSite(definition.site);
32335
+ if (definition.importsPage !== undefined && typeof definition.importsPage !== "boolean" && (!definition.importsPage || typeof definition.importsPage !== "object" || definition.importsPage.site !== true || Object.keys(definition.importsPage).some((key) => key !== "site"))) {
32336
+ throw new TypeError("importsPage must be a boolean or { site: true }");
32337
+ }
32338
+ if (typeof definition.importsPage === "object" && !site) {
32339
+ throw new TypeError("importsPage.site requires a configured site");
32340
+ }
32309
32341
  if (definition.repoContentPage !== undefined && typeof definition.repoContentPage !== "boolean" && (!definition.repoContentPage || typeof definition.repoContentPage !== "object" || definition.repoContentPage.site !== true || Object.keys(definition.repoContentPage).some((key) => key !== "site"))) {
32310
32342
  throw new TypeError("repoContentPage must be a boolean or { site: true }");
32311
32343
  }
@@ -32319,7 +32351,8 @@ var kbPackage = (definition) => {
32319
32351
  ...distribution === undefined ? {} : { distribution },
32320
32352
  assets,
32321
32353
  ...site === undefined ? {} : { site },
32322
- ...definition.repoContentPage === undefined ? {} : { repoContentPage: definition.repoContentPage }
32354
+ ...definition.repoContentPage === undefined ? {} : { repoContentPage: definition.repoContentPage },
32355
+ ...definition.importsPage === undefined ? {} : { importsPage: definition.importsPage }
32323
32356
  };
32324
32357
  };
32325
32358
  var llmsPackage = (definition) => ({
@@ -32861,6 +32894,10 @@ export {
32861
32894
  indexerActivationRequestSchema,
32862
32895
  indexRequirementSetSchema,
32863
32896
  indexRequirementSchema,
32897
+ importsRegistrySchema,
32898
+ importUrlSchema,
32899
+ importIdSchema,
32900
+ importEntrySchema,
32864
32901
  failIndexerPostAuthorRun,
32865
32902
  failIndexerMainRun,
32866
32903
  expectedProviderResolutionFromAction,