@native-knowledge/cli 0.1.0-rc.1 → 0.1.0-rc.3

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 (94) hide show
  1. package/LICENSE +202 -21
  2. package/NOTICE +29 -0
  3. package/dist/agent-entry-cli.js +90 -0
  4. package/dist/auth-commands.js +102 -0
  5. package/dist/cli.js +106 -4874
  6. package/dist/commands.js +41 -0
  7. package/dist/download.js +45 -0
  8. package/dist/errors.js +7 -0
  9. package/dist/input.js +89 -0
  10. package/dist/internal/contracts/artifact.js +103 -0
  11. package/dist/internal/contracts/collection-control.js +69 -0
  12. package/dist/internal/contracts/collection.js +174 -0
  13. package/dist/internal/contracts/common.js +16 -0
  14. package/dist/internal/contracts/currentness.js +221 -0
  15. package/dist/internal/contracts/event.js +35 -0
  16. package/dist/internal/contracts/evidence.js +171 -0
  17. package/dist/internal/contracts/index.js +55 -0
  18. package/dist/internal/contracts/material-capability.js +8 -0
  19. package/dist/internal/contracts/material-carrier.js +15 -0
  20. package/dist/internal/contracts/material-context.js +9 -0
  21. package/dist/internal/contracts/material-read.js +12 -0
  22. package/dist/internal/contracts/observation.js +39 -0
  23. package/dist/internal/contracts/persistence.js +239 -0
  24. package/dist/internal/contracts/project-intent.js +121 -0
  25. package/dist/internal/contracts/projection.js +194 -0
  26. package/dist/internal/contracts/public-reference.js +87 -0
  27. package/dist/internal/contracts/reference-record.js +55 -0
  28. package/dist/internal/contracts/remote-file.js +159 -0
  29. package/dist/internal/contracts/resource-scope.js +38 -0
  30. package/dist/internal/contracts/resource-transfer.js +11 -0
  31. package/dist/internal/contracts/review-packet.js +61 -0
  32. package/dist/internal/contracts/review-plane.js +89 -0
  33. package/dist/internal/contracts/rich-document.js +184 -0
  34. package/dist/internal/contracts/runtime-compatibility.js +55 -0
  35. package/dist/internal/contracts/runtime.js +68 -0
  36. package/dist/internal/contracts/scheduler.js +256 -0
  37. package/dist/internal/contracts/signal.js +77 -0
  38. package/dist/internal/contracts/source-governance.js +194 -0
  39. package/dist/internal/contracts/source.js +32 -0
  40. package/dist/internal/contracts/tenant-budget.js +34 -0
  41. package/dist/internal/contracts/tenant-collection-request.js +58 -0
  42. package/dist/internal/contracts/tenant-collection.js +66 -0
  43. package/dist/internal/contracts/tenant-currentness.js +26 -0
  44. package/dist/internal/contracts/tenant-management.js +27 -0
  45. package/dist/internal/contracts/tenant-material-api.js +46 -0
  46. package/dist/internal/contracts/tenant-material-json-schema.js +16 -0
  47. package/dist/internal/contracts/tenant-pdf-text.js +13 -0
  48. package/dist/internal/contracts/tenant-project-control.js +19 -0
  49. package/dist/internal/contracts/tenant-public-reference.js +26 -0
  50. package/dist/internal/contracts/tenant-resource-api.js +70 -0
  51. package/dist/internal/contracts/tenant-resource.js +118 -0
  52. package/dist/internal/contracts/tenant-rich-document.js +17 -0
  53. package/dist/internal/contracts/tenant-source-binding.js +33 -0
  54. package/dist/internal/contracts/tenant-source-bridge.js +9 -0
  55. package/dist/internal/contracts/tenant-source-cutover.js +26 -0
  56. package/dist/internal/contracts/tenant-source-document.js +38 -0
  57. package/dist/internal/contracts/tenant-source-lease.js +5 -0
  58. package/dist/internal/contracts/tenant-source.js +83 -0
  59. package/dist/internal/contracts/tenant-web-collection.js +118 -0
  60. package/dist/internal/contracts/tenant-web-content-plan.js +39 -0
  61. package/dist/internal/contracts/tenant-web-content-result.js +15 -0
  62. package/dist/internal/contracts/tenant-web-content.js +16 -0
  63. package/dist/internal/contracts/tenant-web-crawl.js +55 -0
  64. package/dist/internal/contracts/tenant-web-dynamic.js +68 -0
  65. package/dist/internal/contracts/tenant-web-results.js +41 -0
  66. package/dist/internal/contracts/tenant-web-workflow.js +29 -0
  67. package/dist/internal/serving-contracts/agent-catalog.js +56 -0
  68. package/dist/internal/serving-contracts/agent-entry.js +57 -0
  69. package/dist/internal/serving-contracts/agent-guidance-shapes.js +12 -0
  70. package/dist/internal/serving-contracts/agent-input-hints.js +104 -0
  71. package/dist/internal/serving-contracts/body-search.js +16 -0
  72. package/dist/internal/serving-contracts/consumer.js +45 -0
  73. package/dist/internal/serving-contracts/core.js +76 -0
  74. package/dist/internal/serving-contracts/http.js +64 -0
  75. package/dist/internal/serving-contracts/index.js +25 -0
  76. package/dist/internal/serving-contracts/management.js +15 -0
  77. package/dist/internal/serving-contracts/material-capabilities.js +14 -0
  78. package/dist/internal/serving-contracts/material-index-status.js +5 -0
  79. package/dist/internal/serving-contracts/mcp.js +137 -0
  80. package/dist/internal/serving-contracts/tenant-governance.js +13 -0
  81. package/dist/internal/serving-contracts/tenant-management.js +89 -0
  82. package/dist/internal/serving-contracts/tenant-project.js +39 -0
  83. package/dist/internal/serving-contracts/tenant-runtime.js +37 -0
  84. package/dist/internal/serving-contracts/tenant-session.js +8 -0
  85. package/dist/internal/serving-contracts/tenant-web-content.js +20 -0
  86. package/dist/internal/serving-contracts/tenant-web-crawl.js +13 -0
  87. package/dist/internal/serving-contracts/tenant-web-dynamic.js +20 -0
  88. package/dist/internal/serving-contracts/tenant-web-workflow.js +36 -0
  89. package/dist/internal/serving-contracts/tenant-web.js +53 -0
  90. package/dist/internal/serving-contracts/tenant-workspace.js +28 -0
  91. package/dist/internal/serving-contracts/workflow.js +37 -0
  92. package/dist/profile-store.js +142 -0
  93. package/package.json +7 -17
  94. package/README.md +0 -28
@@ -0,0 +1,37 @@
1
+ /** Provider20只增加明确授权的运行元数据;不扩展旧版本工具或授予正文读取。 */
2
+ import { z } from 'zod';
3
+ import { materialTenantIdSchema, isoDateTimeSchema, stableUriSchema, sha256Schema, projectKeySchema, tenantResourceRefSchema, tenantBudgetPolicySchema, tenantStorageKey, parseTenantResourceRef, parseTenantCollectionBatchRef, tenantBudgetReasonSchema } from '../contracts/index.js';
4
+ import { tenantProjectWorkspaceToolSchemas, tenantProjectWorkspaceDataSchemas, tenantProjectScopesForInput, tenantProjectAuthorization, tenantProjectErrorSchema, tenantProjectProviderSchema } from './tenant-project.js';
5
+ const count = z.number().int().nonnegative().safe(), cursor = z.string().min(1).max(4096), state = z.enum(['MATCH', 'MISSING', 'UNAVAILABLE', 'INTEGRITY_MISMATCH', 'NOT_REGISTERED']);
6
+ export const tenantRuntimeKindSchema = z.enum(['REQUESTS', 'RESOURCES', 'PROJECTIONS', 'PROJECTS']);
7
+ export const tenantRuntimeInputSchema = z.object({ kind: tenantRuntimeKindSchema.default('REQUESTS'), after: cursor.optional(), limit: z.number().int().min(1).max(20).default(20), requestRef: z.string().regex(/^tenant-collection-request:\/\/[a-f0-9]{64}\/[a-f0-9]{64}$/).optional() }).strict().superRefine((v, ctx) => { if (v.requestRef && (v.kind !== 'REQUESTS' || v.after))
8
+ ctx.addIssue({ code: 'custom', message: 'Exact request lookup requires REQUESTS without a page cursor' }); });
9
+ export const tenantRuntimeProcessSchema = z.object({ runtimeNodeId: projectKeySchema, workloadId: z.string().min(1).max(256), runId: z.string().min(1).max(256), attribution: z.enum(['COMPLETION_RUN', 'FAILURE_RUN', 'SOURCE_WORKLOAD_LATEST', 'PROJECT_WORKLOAD_LATEST']), batchMatches: z.boolean().nullable(), outcome: z.enum(['SUCCEEDED', 'FAILED', 'TIMED_OUT', 'OUTPUT_LIMIT', 'SPAWN_FAILED', 'RECEIPT_MISSING']).nullable(), receiptStatus: z.enum(['SUCCEEDED', 'PARTIAL', 'FAILED', 'BLOCKED', 'SKIPPED']).nullable(), durationMs: count.nullable(), finishedAt: isoDateTimeSchema, category: z.enum(['NONE', 'TIMEOUT', 'OUTPUT_LIMIT', 'SPAWN_FAILURE', 'V8_HEAP_EXHAUSTED', 'NATIVE_ASSERTION_FAILURE', 'UNCAUGHT_EXCEPTION', 'PROCESS_SIGNAL', 'UNKNOWN_FAILURE']).nullable(), peakRssBytes: count.nullable(), sampleCount: count.nullable() }).strict();
10
+ export const tenantRuntimeResourceSchema = z.object({ ref: tenantResourceRefSchema, contentHash: sha256Schema.nullable(), recordedBytes: count.nullable(), manifest: z.enum(['PRESENT', 'MISSING', 'UNAVAILABLE', 'INTEGRITY_MISMATCH']), blob: z.enum(['PRESENT_UNVERIFIED', 'MISSING', 'UNAVAILABLE', 'INTEGRITY_MISMATCH']), contentHashReverified: z.literal(false), catalog: state, directory: state, search: state }).strict();
11
+ const request = z.object({ kind: z.literal('REQUESTS'), requestRef: stableUriSchema, batchRef: stableUriSchema, admission: z.enum(['PENDING', 'STOPPED', 'COMPLETED', 'FAILED']), failureCode: z.literal('TENANT_SOURCE_HTTP_TERMINAL').nullable().optional(), stopReason: z.enum(['GRANT_REVOKED', 'DELEGATION_SUPERSEDED']).nullable(), executionAuthority: z.enum(['CURRENT', 'BLOCKED', 'NOT_CONFIGURED', 'NOT_PENDING', 'UNAVAILABLE']), budgetReason: tenantBudgetReasonSchema.nullable(), captureRecord: z.enum(['PRESENT', 'MISSING', 'UNAVAILABLE']), raw: tenantRuntimeResourceSchema, derivation: z.enum(['NOT_REQUIRED', 'REGISTERED', 'PENDING', 'UNAVAILABLE']), completedPhase: z.enum(['RAW_REGISTERED', 'DERIVED_REGISTERED']).nullable(), process: tenantRuntimeProcessSchema.nullable() }).strict();
12
+ const resources = tenantRuntimeResourceSchema.extend({ kind: z.literal('RESOURCES') }).strict(), projection = tenantRuntimeResourceSchema.extend({ kind: z.literal('PROJECTIONS'), expectedManifestRevision: sha256Schema, preparedAt: isoDateTimeSchema }).strict();
13
+ const project = z.object({ kind: z.literal('PROJECTS'), projectKey: projectKeySchema, lifecycle: z.enum(['ACTIVE', 'ARCHIVED']), runtimeState: z.enum(['AVAILABLE', 'UNAVAILABLE']), projection: z.object({ requestedGeneration: count, completedGeneration: count, pendingGenerationDelta: count }).strict().nullable(), checkpointState: z.enum(['READY', 'UNAVAILABLE', 'EPOCH_MISMATCH']), directoryThroughSeq: count.nullable(), searchThroughSeq: count.nullable(), searchObservedMaxSeq: count.nullable(), searchSequenceDelta: count.nullable(), process: tenantRuntimeProcessSchema.nullable() }).strict();
14
+ const budget = z.discriminatedUnion('state', [
15
+ z.object({ state: z.literal('READY'), scope: z.literal('RUNTIME_OWNER_DATA_ROOT'), windowStart: isoDateTimeSchema, windowEnd: isoDateTimeSchema, usage: z.object({ inFlight: count, workUnits: count, runtimeMs: count }).strict(), limits: tenantBudgetPolicySchema, maxWaitRounds: z.number().int().min(1).max(2048) }).strict(),
16
+ z.object({ state: z.enum(['NOT_CONFIGURED', 'UNAVAILABLE']), reason: z.enum(['CONFIGURATION_REQUIRED', 'TENANT_NOT_CONFIGURED', 'BINDING_MISMATCH', 'STATE_UNAVAILABLE']) }).strict(),
17
+ ]);
18
+ export const tenantRuntimeDataSchema = z.object({ nodeId: projectKeySchema, kind: tenantRuntimeKindSchema, observedAt: isoDateTimeSchema, coverage: z.literal('OWN_TENANT_METADATA_SAMPLE'), metadataOnly: z.literal(true), pageState: z.enum(['READY', 'UNAVAILABLE']), items: z.array(z.discriminatedUnion('kind', [request, resources, projection, project])).max(20), nextAfter: cursor.nullable(), sampleCount: count.max(20), total: z.null(), budget, delivery: z.object({ headSeq: count, retainedThroughSeq: count, businessOutcome: z.literal('NOT_ASSERTED') }).strict() }).strict().superRefine((v, ctx) => { if (v.items.some(item => item.kind !== v.kind) || v.sampleCount !== v.items.length || v.pageState === 'UNAVAILABLE' && (v.items.length || v.nextAfter !== null))
19
+ ctx.addIssue({ code: 'custom', message: 'Metadata sample preserves kind and actual bounded row count' }); });
20
+ export const tenantRuntimeToolSchemas = { tenant_runtime_status: tenantRuntimeInputSchema };
21
+ export const tenantRuntimeWorkspaceToolSchemas = { ...tenantProjectWorkspaceToolSchemas, ...tenantRuntimeToolSchemas };
22
+ export const tenantRuntimeWorkspaceDataSchemas = { ...tenantProjectWorkspaceDataSchemas, tenant_runtime_status: tenantRuntimeDataSchema };
23
+ export function tenantRuntimeScopesForInput(name, raw) { if (name === 'tenant_runtime_status') {
24
+ tenantRuntimeInputSchema.parse(raw);
25
+ return ['knowledge.runtime.read'];
26
+ } return tenantProjectScopesForInput(name, raw); }
27
+ export function tenantRuntimeAuthorization(name) { return name === 'tenant_runtime_status' ? { selection: 'FIXED', scopeAlternatives: [['knowledge.runtime.read']] } : tenantProjectAuthorization(name); }
28
+ export const tenantRuntimeStatusEnvelopeSchema = z.object({ schemaVersion: z.literal(2), tenantId: materialTenantIdSchema, tool: z.literal('tenant_runtime_status'), data: tenantRuntimeDataSchema }).strict().superRefine((value, ctx) => {
29
+ const { data } = value, key = tenantStorageKey(value.tenantId), mine = (ref) => parseTenantResourceRef(ref)?.storageKey === key;
30
+ if (data.budget.state === 'READY' && data.budget.limits.tenantId !== value.tenantId || data.items.some(item => item.kind === 'REQUESTS' ? !(new RegExp('^tenant-collection-request://' + key + '/[a-f0-9]{64}$').test(item.requestRef)) || parseTenantCollectionBatchRef(item.batchRef)?.storageKey !== key || !mine(item.raw.ref) || parseTenantResourceRef(item.raw.ref)?.resourceType !== 'evidence' : item.kind === 'PROJECTS' ? false : !mine(item.ref)))
31
+ ctx.addIssue({ code: 'custom', message: 'Runtime metadata retains exact Tenant scope' });
32
+ });
33
+ export function tenantRuntimeEnvelopeSchema(tool) { return tool === 'tenant_runtime_status' ? tenantRuntimeStatusEnvelopeSchema : z.object({ schemaVersion: z.literal(2), tenantId: materialTenantIdSchema, tool: z.literal(tool), data: tenantRuntimeWorkspaceDataSchemas[tool] }).strict(); }
34
+ export const tenantRuntimeInputJsonSchemas = Object.fromEntries(Object.entries(tenantRuntimeWorkspaceToolSchemas).map(([name, schema]) => [name, z.toJSONSchema(schema, { target: 'draft-07' })]));
35
+ export const tenantRuntimeOutputJsonSchemas = Object.fromEntries(Object.keys(tenantRuntimeWorkspaceToolSchemas).map(name => [name, { type: 'object', oneOf: [z.toJSONSchema(tenantRuntimeEnvelopeSchema(name), { target: 'draft-07' }), z.toJSONSchema(tenantProjectErrorSchema, { target: 'draft-07' })] }]));
36
+ export const tenantRuntimeProviderSchema = z.object({ ...tenantProjectProviderSchema.shape, schemaVersion: z.literal(20), tools: z.array(z.string()).length(Object.keys(tenantRuntimeWorkspaceToolSchemas).length), capabilities: z.tuple([z.literal('TENANT_MANAGEMENT_V1'), z.literal('TENANT_WORKFLOW_V1'), z.literal('TENANT_CURRENTNESS_V2'), z.literal('TENANT_SOURCE_V1'), z.literal('TENANT_WORKSPACE_METADATA_V1'), z.literal('TENANT_PROJECT_CONTEXT_V1'), z.literal('TENANT_RUNTIME_STATUS_V1')]) }).strict().superRefine((value, ctx) => { if (new Set(value.tools).size !== Object.keys(tenantRuntimeWorkspaceToolSchemas).length || value.tools.some(name => !Object.hasOwn(tenantRuntimeWorkspaceToolSchemas, name)))
37
+ ctx.addIssue({ code: 'custom', message: 'Runtime tools must match exact version20 contract' }); });
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod';
2
+ const endpoint = z.string().url(), id = z.string().min(1).max(512), scopes = z.array(z.string().min(1).max(100)).max(32);
3
+ export const tenantSessionSchema = z.object({ schemaVersion: z.literal(1), issuer: endpoint, resource: endpoint, clientId: id, userId: id, tenantId: id, tenantRef: z.string().startsWith('knowledge-tenant://'), contextType: z.literal('TENANT'), authorityVersion: z.union([z.literal(1), z.literal(2)]), tokenScopes: scopes, effectiveScopes: scopes, expiresAt: z.string().datetime(), managementConfigured: z.boolean(), blockers: z.array(z.string()).max(16) }).strict();
4
+ export const tenantOperationStatusInputSchema = z.object({ requestId: z.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._:-]*$/) }).strict();
5
+ export const tenantOperationStatusSchema = z.object({ schemaVersion: z.literal(1), tenantId: id, requestId: z.string(), state: z.enum(['NOT_FOUND', 'INTENT_PERSISTED']), operationRef: z.string().nullable(), action: z.string().nullable(), receivedAt: z.string().datetime().nullable(), completion: z.literal('NOT_PROVEN') }).strict();
6
+ export const tenantClientProviderSchema = z.object({ schemaVersion: z.literal(26), provider: z.literal('knowledge-v2'), revision: z.string(), issuer: endpoint, resource: endpoint, authorizationServerMetadataUrl: endpoint, tenantSessionEndpoint: endpoint, tenantOperationStatusEndpoint: endpoint, resourceCallEndpoint: endpoint, resourceFileEndpoint: endpoint, registrationModes: z.array(z.enum(['PRE_REGISTERED_NATIVE', 'CIMD_READ_ONLY'])).max(2), callbackModes: z.array(z.literal('NATIVE_LOOPBACK_PORT_V1')).max(1), providers: z.array(z.object({ version: z.number().int().min(16).max(26), endpoint }).strict()).max(11), tools: z.array(z.object({ name: z.string(), endpoint, method: z.enum(['GET', 'POST']).default('POST'), inputSchema: z.json(), outputSchema: z.json(), scopeAlternatives: z.array(scopes).max(8) }).strict()).max(100), limits: z.object({ requestMaxBytes: z.literal(131072), resultMaxBytes: z.literal(524288) }).strict() }).strict();
7
+ export const tenantOperationStatusInputJsonSchema = z.toJSONSchema(tenantOperationStatusInputSchema, { target: 'draft-07' });
8
+ export const tenantOperationStatusOutputJsonSchema = z.toJSONSchema(tenantOperationStatusSchema, { target: 'draft-07' });
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+ import { tenantWebContentDocumentSchema, tenantWebContentInputSchema, tenantWebContentPlanSchema, tenantWebContentStatusSchema, tenantWebContentOutcomeSchema, tenantWebJobRefSchema, materialTenantIdSchema, tenantStorageKey, tenantWebContentRevision, tenantWebDynamicSpecRevision } from '../contracts/index.js';
3
+ import { tenantWebDynamicToolSchemas, tenantWebDynamicWorkspaceToolSchemas, tenantWebDynamicDataSchemas, tenantWebDynamicProviderSchema } from './tenant-web-dynamic.js';
4
+ import { tenantWebErrorSchema, tenantWebScopesForInput } from './tenant-web.js';
5
+ import { tenantRuntimeEnvelopeSchema } from './tenant-runtime.js';
6
+ const extraction = tenantWebContentInputSchema.default({ mode: 'NATURAL_LANGUAGE' });
7
+ export const tenantWebContentToolSchemas = { tenant_web_collect_preview: z.object({ ...tenantWebDynamicToolSchemas.tenant_web_collect_preview.shape, extraction }).strict(), tenant_web_collect_submit: z.object({ ...tenantWebDynamicToolSchemas.tenant_web_collect_submit.shape, extraction, retainedFrom: tenantWebJobRefSchema.nullable().default(null) }).strict(), tenant_web_collect_status: z.object({ ...tenantWebDynamicToolSchemas.tenant_web_collect_status.shape, resultIndex: z.number().int().min(0).max(21999).optional(), includeContent: z.boolean().default(false) }).strict().refine(v => !v.includeContent || v.resultIndex !== undefined) };
8
+ export const tenantWebContentWorkspaceToolSchemas = { ...tenantWebDynamicWorkspaceToolSchemas, ...tenantWebContentToolSchemas };
9
+ export const tenantWebContentErrorSchema = z.object({ ...tenantWebErrorSchema.shape, errorCode: z.enum([...tenantWebErrorSchema.shape.errorCode.options, 'TENANT_WEB_SEMANTIC_COMPILER_UNAVAILABLE', 'TENANT_WEB_CONTENT_FIELD_PLAN_REQUIRED', 'TENANT_WEB_RETAINED_SCOPE_FORBIDDEN', 'TENANT_WEB_RESULT_NOT_FOUND']) }).strict();
10
+ export const tenantWebContentDataSchemas = { tenant_web_collect_preview: z.object({ spec: tenantWebDynamicDataSchemas.tenant_web_collect_preview.shape.spec, specRevision: tenantWebDynamicDataSchemas.tenant_web_collect_preview.shape.specRevision, contentPlan: tenantWebContentPlanSchema, contentRevision: tenantWebContentStatusSchema.shape.contentRevision, networkValidated: z.literal(false), budgetReserved: z.literal(false), execution: z.literal('EXPLICIT_HOST_DISPATCH'), requirementsState: z.literal('PENDING') }).strict().refine(v => v.contentRevision === tenantWebContentRevision(v.contentPlan) && v.specRevision === tenantWebDynamicSpecRevision(v.spec)), tenant_web_collect_submit: z.object({ inserted: z.boolean(), job: tenantWebContentStatusSchema }).strict(), tenant_web_collect_status: z.object({ ...tenantWebContentStatusSchema.shape, result: tenantWebContentOutcomeSchema.nullable(), resultDocument: tenantWebContentDocumentSchema.nullable(), resultDelivery: z.enum(['NONE', 'INLINE', 'DOWNLOAD']) }).strict() };
11
+ export function tenantWebContentEnvelopeSchema(tool) { return z.object({ schemaVersion: z.literal(2), tenantId: materialTenantIdSchema, tool: z.literal(tool), data: tenantWebContentDataSchemas[tool] }).strict().superRefine((v, c) => { const data = v.data, key = tenantStorageKey(v.tenantId), ref = data.jobRef ?? data.job?.jobRef; if (data.resultDocument && (data.resultDocument.jobRef !== ref || !data.resultDocument.parentEvidenceRef.startsWith('tenant-resource://' + key + '/evidence/')))
12
+ c.addIssue({ code: 'custom', message: 'Exact result document required' }); if (ref && !ref.startsWith('tenant-web-collection://' + key + '/') || data.result?.documentRef && !data.result.documentRef.startsWith('tenant-resource://' + key + '/source_document/'))
13
+ c.addIssue({ code: 'custom', message: 'Exact Tenant content identity required' }); }); }
14
+ export function tenantWebContentScopesForInput(name, raw) { if (Object.hasOwn(tenantWebContentToolSchemas, name)) {
15
+ const input = tenantWebContentToolSchemas[name].parse(raw);
16
+ return name === 'tenant_web_collect_status' && 'includeContent' in input && input.includeContent ? ['knowledge.collect', 'knowledge.material.read'] : name === 'tenant_web_collect_status' ? ['knowledge.collect'] : ['knowledge.source.manage', 'knowledge.collect'];
17
+ } return tenantWebScopesForInput(name, raw); }
18
+ export const tenantWebContentInputJsonSchemas = Object.fromEntries(Object.entries(tenantWebContentWorkspaceToolSchemas).map(([name, schema]) => [name, z.toJSONSchema(schema, { target: 'draft-07' })]));
19
+ export const tenantWebContentOutputJsonSchemas = Object.fromEntries(Object.keys(tenantWebContentWorkspaceToolSchemas).map(name => [name, { type: 'object', oneOf: [z.toJSONSchema(Object.hasOwn(tenantWebContentToolSchemas, name) ? tenantWebContentEnvelopeSchema(name) : tenantRuntimeEnvelopeSchema(name), { target: 'draft-07' }), z.toJSONSchema(tenantWebContentErrorSchema, { target: 'draft-07' })] }]));
20
+ export const tenantWebContentProviderSchema = z.object({ ...tenantWebDynamicProviderSchema.shape, schemaVersion: z.literal(24), capabilities: z.tuple([z.literal('TENANT_MANAGEMENT_V1'), z.literal('TENANT_WORKFLOW_V1'), z.literal('TENANT_CURRENTNESS_V2'), z.literal('TENANT_SOURCE_V1'), z.literal('TENANT_WORKSPACE_METADATA_V1'), z.literal('TENANT_PROJECT_CONTEXT_V1'), z.literal('TENANT_RUNTIME_STATUS_V1'), z.literal('TENANT_WEB_COLLECTION_SPEC_V1'), z.literal('TENANT_WEB_CRAWL_V1'), z.literal('TENANT_WEB_DYNAMIC_V1'), z.literal('TENANT_WEB_CONTENT_V1')]) }).strict().refine(v => new Set(v.tools).size === Object.keys(tenantWebContentWorkspaceToolSchemas).length && v.tools.every(t => Object.hasOwn(tenantWebContentWorkspaceToolSchemas, t)));
@@ -0,0 +1,13 @@
1
+ /** Provider22 与 Provider21 共享输入名字,执行合同通过新版本显式选择。 */
2
+ import { z } from 'zod';
3
+ import { tenantWebCrawlStatusSchema, materialTenantIdSchema, tenantStorageKey, tenantWebSpecRevision, TENANT_WEB_CRAWL_CAPABILITY } from '../contracts/index.js';
4
+ import { tenantWebToolSchemas, tenantWebWorkspaceToolSchemas, tenantWebProviderSchema, tenantWebDataSchemas, tenantWebErrorSchema, tenantWebInputJsonSchemas } from './tenant-web.js';
5
+ import { tenantRuntimeEnvelopeSchema } from './tenant-runtime.js';
6
+ export const tenantWebCrawlDataSchemas = { tenant_web_collect_preview: z.object({ spec: tenantWebDataSchemas.tenant_web_collect_preview.shape.spec, specRevision: tenantWebDataSchemas.tenant_web_collect_preview.shape.specRevision, networkValidated: z.literal(false), budgetReserved: z.literal(false), execution: z.literal('EXPLICIT_HOST_DISPATCH'), requirementsState: z.literal('DECLARED_NOT_EVALUATED') }).strict().superRefine((v, ctx) => { if (v.specRevision !== tenantWebSpecRevision(v.spec))
7
+ ctx.addIssue({ code: 'custom', message: 'Preview specification mismatch' }); }), tenant_web_collect_submit: z.object({ inserted: z.boolean(), job: tenantWebCrawlStatusSchema }).strict(), tenant_web_collect_status: tenantWebCrawlStatusSchema };
8
+ export function tenantWebCrawlEnvelopeSchema(tool) { return z.object({ schemaVersion: z.literal(2), tenantId: materialTenantIdSchema, tool: z.literal(tool), data: tenantWebCrawlDataSchemas[tool] }).strict().superRefine((v, ctx) => { const row = v, ref = row.data.jobRef ?? row.data.job?.jobRef; if (ref && !ref.startsWith('tenant-web-collection://' + tenantStorageKey(row.tenantId) + '/'))
9
+ ctx.addIssue({ code: 'custom', message: 'Exact Tenant website job required' }); }); }
10
+ export const tenantWebCrawlInputJsonSchemas = tenantWebInputJsonSchemas;
11
+ export const tenantWebCrawlOutputJsonSchemas = Object.fromEntries(Object.keys(tenantWebWorkspaceToolSchemas).map(name => [name, { type: 'object', oneOf: [z.toJSONSchema(Object.hasOwn(tenantWebToolSchemas, name) ? tenantWebCrawlEnvelopeSchema(name) : tenantRuntimeEnvelopeSchema(name), { target: 'draft-07' }), z.toJSONSchema(tenantWebErrorSchema, { target: 'draft-07' })] }]));
12
+ export const tenantWebCrawlProviderSchema = z.object({ ...tenantWebProviderSchema.shape, schemaVersion: z.literal(22), capabilities: z.tuple([z.literal('TENANT_MANAGEMENT_V1'), z.literal('TENANT_WORKFLOW_V1'), z.literal('TENANT_CURRENTNESS_V2'), z.literal('TENANT_SOURCE_V1'), z.literal('TENANT_WORKSPACE_METADATA_V1'), z.literal('TENANT_PROJECT_CONTEXT_V1'), z.literal('TENANT_RUNTIME_STATUS_V1'), z.literal('TENANT_WEB_COLLECTION_SPEC_V1'), z.literal(TENANT_WEB_CRAWL_CAPABILITY)]) }).strict().superRefine((v, ctx) => { if (new Set(v.tools).size !== Object.keys(tenantWebWorkspaceToolSchemas).length || v.tools.some(name => !Object.hasOwn(tenantWebWorkspaceToolSchemas, name)))
13
+ ctx.addIssue({ code: 'custom', message: 'Provider22 exact registry required' }); });
@@ -0,0 +1,20 @@
1
+ /** Provider23 与 Provider21 共享输入名字,执行合同通过新版本显式选择。 */
2
+ import { z } from 'zod';
3
+ import { tenantWebDynamicSpecSchema, tenantWebDynamicStatusSchema, materialTenantIdSchema, tenantStorageKey, tenantWebDynamicSpecRevision, TENANT_WEB_DYNAMIC_CAPABILITY } from '../contracts/index.js';
4
+ import { tenantWebToolSchemas, tenantWebWorkspaceToolSchemas, tenantWebProviderSchema, tenantWebDataSchemas, tenantWebErrorSchema, tenantWebInputJsonSchemas, tenantWebScopesForInput } from './tenant-web.js';
5
+ import { tenantWebCrawlProviderSchema } from './tenant-web-crawl.js';
6
+ export const tenantWebDynamicToolSchemas = { ...tenantWebToolSchemas, tenant_web_collect_preview: z.object({ spec: tenantWebDynamicSpecSchema }).strict(), tenant_web_collect_submit: z.object({ ...tenantWebToolSchemas.tenant_web_collect_submit.shape, spec: tenantWebDynamicSpecSchema }).strict() };
7
+ export const tenantWebDynamicWorkspaceToolSchemas = { ...tenantWebWorkspaceToolSchemas, ...tenantWebDynamicToolSchemas };
8
+ export function tenantWebDynamicScopesForInput(name, raw) { if (Object.hasOwn(tenantWebDynamicToolSchemas, name)) {
9
+ tenantWebDynamicToolSchemas[name].parse(raw);
10
+ return name === 'tenant_web_collect_status' ? ['knowledge.collect'] : ['knowledge.source.manage', 'knowledge.collect'];
11
+ } return tenantWebScopesForInput(name, raw); }
12
+ import { tenantRuntimeEnvelopeSchema } from './tenant-runtime.js';
13
+ export const tenantWebDynamicDataSchemas = { tenant_web_collect_preview: z.object({ spec: tenantWebDynamicSpecSchema, specRevision: tenantWebDataSchemas.tenant_web_collect_preview.shape.specRevision, networkValidated: z.literal(false), budgetReserved: z.literal(false), execution: z.literal('EXPLICIT_HOST_DISPATCH'), requirementsState: z.literal('DECLARED_NOT_EVALUATED') }).strict().superRefine((v, ctx) => { if (v.specRevision !== tenantWebDynamicSpecRevision(v.spec))
14
+ ctx.addIssue({ code: 'custom', message: 'Preview specification mismatch' }); }), tenant_web_collect_submit: z.object({ inserted: z.boolean(), job: tenantWebDynamicStatusSchema }).strict(), tenant_web_collect_status: tenantWebDynamicStatusSchema };
15
+ export function tenantWebDynamicEnvelopeSchema(tool) { return z.object({ schemaVersion: z.literal(2), tenantId: materialTenantIdSchema, tool: z.literal(tool), data: tenantWebDynamicDataSchemas[tool] }).strict().superRefine((v, ctx) => { const row = v, ref = row.data.jobRef ?? row.data.job?.jobRef; if (ref && !ref.startsWith('tenant-web-collection://' + tenantStorageKey(row.tenantId) + '/'))
16
+ ctx.addIssue({ code: 'custom', message: 'Exact Tenant website job required' }); }); }
17
+ export const tenantWebDynamicInputJsonSchemas = Object.fromEntries(Object.entries(tenantWebDynamicWorkspaceToolSchemas).map(([name, schema]) => [name, z.toJSONSchema(schema, { target: 'draft-07' })]));
18
+ export const tenantWebDynamicOutputJsonSchemas = Object.fromEntries(Object.keys(tenantWebWorkspaceToolSchemas).map(name => [name, { type: 'object', oneOf: [z.toJSONSchema(Object.hasOwn(tenantWebToolSchemas, name) ? tenantWebDynamicEnvelopeSchema(name) : tenantRuntimeEnvelopeSchema(name), { target: 'draft-07' }), z.toJSONSchema(tenantWebErrorSchema, { target: 'draft-07' })] }]));
19
+ export const tenantWebDynamicProviderSchema = z.object({ ...tenantWebCrawlProviderSchema.shape, schemaVersion: z.literal(23), capabilities: z.tuple([z.literal('TENANT_MANAGEMENT_V1'), z.literal('TENANT_WORKFLOW_V1'), z.literal('TENANT_CURRENTNESS_V2'), z.literal('TENANT_SOURCE_V1'), z.literal('TENANT_WORKSPACE_METADATA_V1'), z.literal('TENANT_PROJECT_CONTEXT_V1'), z.literal('TENANT_RUNTIME_STATUS_V1'), z.literal('TENANT_WEB_COLLECTION_SPEC_V1'), z.literal('TENANT_WEB_CRAWL_V1'), z.literal(TENANT_WEB_DYNAMIC_CAPABILITY)]) }).strict().superRefine((v, ctx) => { if (new Set(v.tools).size !== Object.keys(tenantWebWorkspaceToolSchemas).length || v.tools.some(name => !Object.hasOwn(tenantWebWorkspaceToolSchemas, name)))
20
+ ctx.addIssue({ code: 'custom', message: 'Provider23 exact registry required' }); });
@@ -0,0 +1,36 @@
1
+ /** Explicit Provider25 operations; earlier registries remain frozen. */
2
+ import { z } from 'zod';
3
+ import { tenantWebWorkflowStatusSchema, tenantWebScheduleSchema, tenantWebControlInputSchema, tenantWebLifecycleReceiptSchema, tenantWebWorkflowJobSchema, tenantWebContentOutcomeSchema, tenantWebJobRefSchema, tenantCollectionCycleSchema, tenantResourceRefSchema, sha256Schema, isoDateTimeSchema, materialTenantIdSchema, tenantStorageKey, resourceDataSchemas } from '../contracts/index.js';
4
+ import { tenantWebContentToolSchemas, tenantWebContentDataSchemas, tenantWebContentWorkspaceToolSchemas, tenantWebContentProviderSchema, tenantWebContentErrorSchema } from './tenant-web-content.js';
5
+ import { tenantWebScopesForInput } from './tenant-web.js';
6
+ import { tenantRuntimeEnvelopeSchema } from './tenant-runtime.js';
7
+ const count = z.number().int().nonnegative().safe(), cursor = z.string().min(1).max(4096), job = z.object({ jobRef: tenantWebJobRefSchema }).strict(), page = job.extend({ after: cursor.optional(), limit: z.number().int().min(1).max(100).default(20) }), schedule = tenantWebScheduleSchema.default({ mode: 'ONCE' }), observation = z.object({ ref: tenantResourceRefSchema, contentHash: sha256Schema, sourceUrl: z.string().url(), observedAt: isoDateTimeSchema }).strict().nullable();
8
+ export const tenantWebWorkflowToolSchemas = {
9
+ tenant_web_collect_preview: tenantWebContentToolSchemas.tenant_web_collect_preview.extend({ schedule }),
10
+ tenant_web_collect_submit: tenantWebContentToolSchemas.tenant_web_collect_submit.extend({ schedule }),
11
+ tenant_web_collect_status: job, tenant_web_collect_results: page, tenant_web_collect_cycles: page,
12
+ tenant_web_collect_control: tenantWebControlInputSchema,
13
+ tenant_web_collect_refresh: job.extend({ requestId: tenantCollectionCycleSchema, expectedEpoch: count }),
14
+ tenant_web_collect_read: job.extend({ kind: z.enum(['ORIGINAL', 'DOM', 'RESULT']), index: count.max(21999), stateIndex: count.max(100).optional() }).refine(v => v.kind === 'DOM' ? v.stateIndex !== undefined : v.stateIndex === undefined),
15
+ tenant_web_collect_index_status: z.object({}).strict(),
16
+ };
17
+ export const tenantWebWorkflowWorkspaceToolSchemas = { ...tenantWebContentWorkspaceToolSchemas, ...tenantWebWorkflowToolSchemas };
18
+ export function tenantWebWorkflowScopesForInput(name, raw) { if (!Object.hasOwn(tenantWebWorkflowToolSchemas, name))
19
+ return tenantWebScopesForInput(name, raw); tenantWebWorkflowToolSchemas[name].parse(raw); return name === 'tenant_web_collect_read' || name === 'tenant_web_collect_index_status' ? ['knowledge.collect', 'knowledge.material.read'] : ['tenant_web_collect_status', 'tenant_web_collect_results', 'tenant_web_collect_cycles'].includes(name) ? ['knowledge.collect'] : ['knowledge.collect', 'knowledge.source.manage']; }
20
+ export const tenantWebWorkflowDataSchemas = {
21
+ tenant_web_collect_preview: tenantWebContentDataSchemas.tenant_web_collect_preview.safeExtend({ schedule: tenantWebScheduleSchema }),
22
+ tenant_web_collect_submit: z.object({ inserted: z.boolean(), job: tenantWebWorkflowStatusSchema }).strict(),
23
+ tenant_web_collect_status: tenantWebWorkflowStatusSchema,
24
+ tenant_web_collect_results: job.extend({ items: z.array(tenantWebContentOutcomeSchema.safeExtend({ original: observation, observation })).max(100), through: count, nextAfter: cursor.nullable(), available: count, terminal: z.boolean() }),
25
+ tenant_web_collect_cycles: job.extend({ rootJobRef: tenantWebJobRefSchema, items: z.array(z.object({ jobRef: tenantWebJobRefSchema, cycle: tenantWebWorkflowJobSchema.shape.cycle, submittedAt: isoDateTimeSchema }).strict()).max(100), through: count, nextAfter: cursor.nullable() }),
26
+ tenant_web_collect_control: z.object({ replayed: z.boolean(), receipt: tenantWebLifecycleReceiptSchema, job: tenantWebWorkflowStatusSchema }).strict(),
27
+ tenant_web_collect_refresh: z.object({ inserted: z.boolean(), job: tenantWebWorkflowStatusSchema }).strict(),
28
+ tenant_web_collect_read: job.extend({ ref: tenantResourceRefSchema, result: resourceDataSchemas.knowledge_resource_read }),
29
+ tenant_web_collect_index_status: resourceDataSchemas.knowledge_resource_index_status,
30
+ };
31
+ export const tenantWebWorkflowErrorSchema = tenantWebContentErrorSchema.extend({ completedPhase: z.enum([...tenantWebContentErrorSchema.shape.completedPhase.unwrap().options, 'WEB_CONTROL_COMMITTED']).optional(), errorCode: z.enum([...tenantWebContentErrorSchema.shape.errorCode.options, 'TENANT_WEB_CONTROL_CONFLICT', 'TENANT_WEB_CANCELLED', 'TENANT_WEB_PAUSED', 'TENANT_WEB_CYCLE_PENDING', 'TENANT_WEB_RUNTIME_OR_DELEGATION_UNAVAILABLE']) }).strict();
32
+ export function tenantWebWorkflowEnvelopeSchema(tool) { return z.object({ schemaVersion: z.literal(2), tenantId: materialTenantIdSchema, tool: z.literal(tool), data: tenantWebWorkflowDataSchemas[tool] }).strict().superRefine((v, c) => { const d = v.data, key = tenantStorageKey(v.tenantId); if ([d.jobRef, d.rootJobRef, d.job?.jobRef, ...(d.items ?? []).map(i => i.jobRef)].some(ref => ref && !ref.startsWith('tenant-web-collection://' + key + '/')) || [d.ref, ...(d.items ?? []).flatMap(i => [i.documentRef, i.original?.ref, i.observation?.ref])].some(ref => ref && !ref.startsWith('tenant-resource://' + key + '/')) || d.result?.item && (d.result.item.ownerTenantId !== v.tenantId || d.result.item.ref !== d.ref))
33
+ c.addIssue({ code: 'custom', message: 'Exact Tenant workflow/result identity required' }); }); }
34
+ export const tenantWebWorkflowInputJsonSchemas = Object.fromEntries(Object.entries(tenantWebWorkflowWorkspaceToolSchemas).map(([n, s]) => [n, z.toJSONSchema(s, { target: 'draft-07' })]));
35
+ export const tenantWebWorkflowOutputJsonSchemas = Object.fromEntries(Object.keys(tenantWebWorkflowWorkspaceToolSchemas).map(n => [n, { type: 'object', oneOf: [z.toJSONSchema(Object.hasOwn(tenantWebWorkflowToolSchemas, n) ? tenantWebWorkflowEnvelopeSchema(n) : tenantRuntimeEnvelopeSchema(n), { target: 'draft-07' }), z.toJSONSchema(tenantWebWorkflowErrorSchema, { target: 'draft-07' })] }]));
36
+ export const tenantWebWorkflowProviderSchema = z.object({ ...tenantWebContentProviderSchema.shape, schemaVersion: z.literal(25), collectionMode: z.literal('EXPLICIT_HOST_WITH_OPT_IN_DUE'), tools: z.array(z.string()).length(Object.keys(tenantWebWorkflowWorkspaceToolSchemas).length), capabilities: z.tuple([z.literal('TENANT_MANAGEMENT_V1'), z.literal('TENANT_WORKFLOW_V1'), z.literal('TENANT_CURRENTNESS_V2'), z.literal('TENANT_SOURCE_V1'), z.literal('TENANT_WORKSPACE_METADATA_V1'), z.literal('TENANT_PROJECT_CONTEXT_V1'), z.literal('TENANT_RUNTIME_STATUS_V1'), z.literal('TENANT_WEB_COLLECTION_SPEC_V1'), z.literal('TENANT_WEB_CRAWL_V1'), z.literal('TENANT_WEB_DYNAMIC_V1'), z.literal('TENANT_WEB_CONTENT_V1'), z.literal('TENANT_WEB_WORKFLOW_V1')]) }).strict().refine(v => new Set(v.tools).size === Object.keys(tenantWebWorkflowWorkspaceToolSchemas).length && v.tools.every(t => Object.hasOwn(tenantWebWorkflowWorkspaceToolSchemas, t)));
@@ -0,0 +1,53 @@
1
+ /** Provider21 增量能力;17–20 的注册表、默认版本和既有错误合同保持。 */
2
+ import { z } from 'zod';
3
+ import { tenantWebSpecSchema, tenantWebSummarySchema, tenantWebJobRefSchema, tenantWebSpecRevision, tenantCollectionCycleSchema, materialTenantIdSchema, tenantStorageKey, TENANT_WEB_SPEC_CAPABILITY } from '../contracts/index.js';
4
+ import { tenantRuntimeWorkspaceToolSchemas, tenantRuntimeWorkspaceDataSchemas, tenantRuntimeEnvelopeSchema, tenantRuntimeProviderSchema, tenantRuntimeScopesForInput, tenantRuntimeAuthorization } from './tenant-runtime.js';
5
+ import { tenantProjectErrorSchema } from './tenant-project.js';
6
+ import { tenantManagementSafeErrorRef } from './tenant-management.js';
7
+ export const tenantWebToolSchemas = {
8
+ tenant_web_collect_preview: z.object({ spec: tenantWebSpecSchema }).strict(),
9
+ tenant_web_collect_submit: z.object({ requestId: tenantCollectionCycleSchema, spec: tenantWebSpecSchema }).strict(),
10
+ tenant_web_collect_status: z.object({ jobRef: tenantWebJobRefSchema }).strict(),
11
+ };
12
+ export const tenantWebDataSchemas = {
13
+ tenant_web_collect_preview: z.object({ spec: tenantWebSpecSchema, specRevision: tenantWebSummarySchema.shape.specRevision, networkValidated: z.literal(false), budgetReserved: z.literal(false), execution: z.literal('UNAVAILABLE'), reason: z.literal('S2_NOT_IMPLEMENTED'), requirementsState: z.literal('DECLARED_NOT_EVALUATED') }).strict().superRefine((v, ctx) => { if (v.specRevision !== tenantWebSpecRevision(v.spec))
14
+ ctx.addIssue({ code: 'custom', message: 'Preview specification identity mismatch' }); }),
15
+ tenant_web_collect_submit: z.object({ inserted: z.boolean(), job: tenantWebSummarySchema }).strict(),
16
+ tenant_web_collect_status: tenantWebSummarySchema,
17
+ };
18
+ export const tenantWebWorkspaceToolSchemas = { ...tenantRuntimeWorkspaceToolSchemas, ...tenantWebToolSchemas };
19
+ export const tenantWebWorkspaceDataSchemas = { ...tenantRuntimeWorkspaceDataSchemas, ...tenantWebDataSchemas };
20
+ export const tenantWebErrorSchema = tenantProjectErrorSchema.extend({ completedPhase: z.enum([...tenantProjectErrorSchema.shape.completedPhase.unwrap().options, 'WEB_INTENT_PERSISTED']).optional() }).strict();
21
+ export function tenantWebSafeErrorRef(raw, tenantId) {
22
+ if (typeof raw === 'string' && new RegExp('^tenant-web-collection://' + tenantStorageKey(tenantId) + '/[a-f0-9]{64}$').test(raw))
23
+ return raw;
24
+ return tenantManagementSafeErrorRef(raw, tenantId);
25
+ }
26
+ export function tenantWebScopesForInput(name, raw) {
27
+ if (Object.hasOwn(tenantWebToolSchemas, name)) {
28
+ tenantWebToolSchemas[name].parse(raw);
29
+ return name === 'tenant_web_collect_status' ? ['knowledge.collect'] : ['knowledge.source.manage', 'knowledge.collect'];
30
+ }
31
+ return tenantRuntimeScopesForInput(name, raw);
32
+ }
33
+ export function tenantWebAuthorization(name) {
34
+ if (Object.hasOwn(tenantWebToolSchemas, name))
35
+ return { selection: 'FIXED', scopeAlternatives: [name === 'tenant_web_collect_status' ? ['knowledge.collect'] : ['knowledge.source.manage', 'knowledge.collect']] };
36
+ return tenantRuntimeAuthorization(name);
37
+ }
38
+ export function tenantWebEnvelopeSchema(tool) {
39
+ return z.object({ schemaVersion: z.literal(2), tenantId: materialTenantIdSchema, tool: z.literal(tool), data: tenantWebDataSchemas[tool] }).strict().superRefine((value, ctx) => {
40
+ const envelope = value, ref = envelope.data.jobRef ?? envelope.data.job?.jobRef;
41
+ if (ref && !ref.startsWith('tenant-web-collection://' + tenantStorageKey(envelope.tenantId) + '/'))
42
+ ctx.addIssue({ code: 'custom', message: 'Web intent must belong to the exact authenticated Tenant' });
43
+ });
44
+ }
45
+ export const tenantWebInputJsonSchemas = Object.fromEntries(Object.entries(tenantWebWorkspaceToolSchemas).map(([name, schema]) => [name, z.toJSONSchema(schema, { target: 'draft-07' })]));
46
+ export const tenantWebOutputJsonSchemas = Object.fromEntries(Object.keys(tenantWebWorkspaceToolSchemas).map(name => [name, { type: 'object', oneOf: [z.toJSONSchema(Object.hasOwn(tenantWebToolSchemas, name) ? tenantWebEnvelopeSchema(name) : tenantRuntimeEnvelopeSchema(name), { target: 'draft-07' }), z.toJSONSchema(tenantWebErrorSchema, { target: 'draft-07' })] }]));
47
+ export const tenantWebProviderSchema = z.object({ ...tenantRuntimeProviderSchema.shape,
48
+ schemaVersion: z.literal(21), tools: z.array(z.string()).length(Object.keys(tenantWebWorkspaceToolSchemas).length),
49
+ capabilities: z.tuple([z.literal('TENANT_MANAGEMENT_V1'), z.literal('TENANT_WORKFLOW_V1'), z.literal('TENANT_CURRENTNESS_V2'), z.literal('TENANT_SOURCE_V1'), z.literal('TENANT_WORKSPACE_METADATA_V1'), z.literal('TENANT_PROJECT_CONTEXT_V1'), z.literal('TENANT_RUNTIME_STATUS_V1'), z.literal(TENANT_WEB_SPEC_CAPABILITY)]),
50
+ }).strict().superRefine((value, ctx) => {
51
+ if (new Set(value.tools).size !== Object.keys(tenantWebWorkspaceToolSchemas).length || value.tools.some(name => !Object.hasOwn(tenantWebWorkspaceToolSchemas, name)))
52
+ ctx.addIssue({ code: 'custom', message: 'Provider21 tools must match the exact versioned registry' });
53
+ });
@@ -0,0 +1,28 @@
1
+ /** Provider18 adds explicit metadata reads; Provider17 remains the exact original twenty tools. */
2
+ import { z } from 'zod';
3
+ import { tenantResourceRefSchema, tenantSourceIdSchema, collectionRefreshSchema, stableUriSchema, isoDateTimeSchema, materialTenantIdSchema } from '../contracts/index.js';
4
+ import { tenantManagementToolSchemas, tenantManagementDataSchemas, tenantManagementScopesForInput, tenantManagementAuthorization, tenantManagementProviderBaseSchema, tenantManagementErrorSchema } from './tenant-management.js';
5
+ const page = { after: z.string().min(1).max(4096).optional(), limit: z.number().int().min(1).max(100).optional() };
6
+ export const tenantWorkStageSchema = z.enum(['ALL', 'RESEARCH', 'DRAFT', 'READY_FOR_REVIEW', 'REWORK_REQUIRED', 'APPROVED']);
7
+ export const tenantWorkspaceExtraToolSchemas = { tenant_source_inventory: z.object(page).strict(), tenant_work_queue: z.object({ ...page, stage: tenantWorkStageSchema.default('ALL') }).strict() };
8
+ const source = z.object({ sourceId: tenantSourceIdSchema, title: z.string().min(1).max(512).nullable(), revisionRef: stableUriSchema.nullable(), generation: z.number().int().positive().safe().nullable(), paused: z.boolean().nullable(), tenantEnabled: z.boolean().nullable(), refresh: collectionRefreshSchema.nullable(), canonicalState: z.enum(['READY', 'UNAVAILABLE', 'INTEGRITY_MISMATCH']) }).strict();
9
+ const artifact = z.object({ ref: tenantResourceRefSchema, title: z.string().max(512), kind: z.string().max(128).nullable(), status: z.string().max(128).nullable(), version: z.number().int().positive().safe().nullable(), recordedAt: isoDateTimeSchema.nullable(), availability: z.enum(['READY', 'UNAVAILABLE', 'INTEGRITY_MISMATCH']), succession: z.enum(['SUCCESSOR_VISIBLE', 'NO_VISIBLE_SUCCESSOR', 'UNCONFIRMED']) }).strict();
10
+ export const tenantWorkspaceExtraDataSchemas = {
11
+ tenant_source_inventory: z.object({ items: z.array(source).max(100), nextAfter: z.string().max(4096).nullable(), coverage: z.literal('REGISTERED_TENANT_SOURCES') }).strict(),
12
+ tenant_work_queue: z.object({ items: z.array(artifact).max(100), nextAfter: z.string().max(4096).nullable(), stage: tenantWorkStageSchema, candidateCount: z.number().int().min(0).max(100), coverage: z.literal('AUTHORIZED_NATIVE_ARTIFACT_METADATA'), total: z.null() }).strict(),
13
+ };
14
+ export const tenantWorkspaceToolSchemas = { ...tenantManagementToolSchemas, ...tenantWorkspaceExtraToolSchemas };
15
+ export const tenantWorkspaceDataSchemas = { ...tenantManagementDataSchemas, ...tenantWorkspaceExtraDataSchemas };
16
+ export function tenantWorkspaceScopesForInput(name, raw) { if (name === 'tenant_source_inventory') {
17
+ tenantWorkspaceExtraToolSchemas[name].parse(raw);
18
+ return ['knowledge.source.read'];
19
+ } if (name === 'tenant_work_queue') {
20
+ tenantWorkspaceExtraToolSchemas[name].parse(raw);
21
+ return ['knowledge.workflow.read'];
22
+ } return tenantManagementScopesForInput(name, raw); }
23
+ export function tenantWorkspaceAuthorization(name) { return name === 'tenant_source_inventory' || name === 'tenant_work_queue' ? { selection: 'FIXED', scopeAlternatives: [[name === 'tenant_source_inventory' ? 'knowledge.source.read' : 'knowledge.workflow.read']] } : tenantManagementAuthorization(name); }
24
+ export function tenantWorkspaceEnvelopeSchema(tool) { return z.object({ schemaVersion: z.literal(2), tenantId: materialTenantIdSchema, tool: z.literal(tool), data: tenantWorkspaceDataSchemas[tool] }).strict(); }
25
+ export const tenantWorkspaceInputJsonSchemas = Object.fromEntries(Object.entries(tenantWorkspaceToolSchemas).map(([name, schema]) => [name, z.toJSONSchema(schema, { target: 'draft-07' })]));
26
+ export const tenantWorkspaceOutputJsonSchemas = Object.fromEntries(Object.keys(tenantWorkspaceToolSchemas).map(name => [name, { type: 'object', oneOf: [z.toJSONSchema(tenantWorkspaceEnvelopeSchema(name), { target: 'draft-07' }), z.toJSONSchema(tenantManagementErrorSchema, { target: 'draft-07' })] }]));
27
+ export const tenantWorkspaceProviderSchema = tenantManagementProviderBaseSchema.extend({ schemaVersion: z.literal(18), tools: z.array(z.string()).length(Object.keys(tenantWorkspaceToolSchemas).length), capabilities: z.tuple([z.literal('TENANT_MANAGEMENT_V1'), z.literal('TENANT_WORKFLOW_V1'), z.literal('TENANT_CURRENTNESS_V2'), z.literal('TENANT_SOURCE_V1'), z.literal('TENANT_WORKSPACE_METADATA_V1')]) }).strict().superRefine((value, ctx) => { if (new Set(value.tools).size !== Object.keys(tenantWorkspaceToolSchemas).length || value.tools.some(name => !Object.hasOwn(tenantWorkspaceToolSchemas, name)))
28
+ ctx.addIssue({ code: 'custom', message: 'Workspace tools must match the exact version18 contract' }); });
@@ -0,0 +1,37 @@
1
+ /** Agent 的治理合同描述真实状态和下一步,不把写入权限解释为审核或正文权限。 */
2
+ import { z } from 'zod';
3
+ import { artifactStatusSchema, idSchema, isoDateTimeSchema, publicationReadinessReportSchema, sha256Schema, stableUriSchema } from '../contracts/index.js';
4
+ import { consumerProjectRefSchema } from './consumer.js';
5
+ import { managementToolInputSchemas } from './management.js';
6
+ const project = z.object({ projectRef: consumerProjectRefSchema }).strict();
7
+ export const workflowPlanInputSchema = project.extend({ ref: stableUriSchema }).strict();
8
+ export const workflowGuideInputSchema = project;
9
+ export const workflowActionSchema = z.enum(['PREPARE_SOURCE', 'SUBMIT_REVIEW', 'FINALIZE_REVIEW', 'REGISTER']);
10
+ export const workflowAdvanceInputSchema = workflowPlanInputSchema.extend({ action: workflowActionSchema, expectedVersion: z.number().int().nonnegative().optional(), actedAt: isoDateTimeSchema.optional() }).strict().superRefine((value, ctx) => {
11
+ if (['SUBMIT_REVIEW', 'FINALIZE_REVIEW'].includes(value.action) && (!value.expectedVersion || !value.actedAt))
12
+ ctx.addIssue({ code: 'custom', message: 'transition requires exact expectedVersion and actedAt' });
13
+ });
14
+ export const agentSubmitInputSchema = project.extend({ sourceId: idSchema, contentBase64: z.string().min(1).max(87384), mediaType: z.string().trim().min(1).max(256), access: z.enum(['PUBLIC', 'TENANT', 'INTERNAL', 'FDE_INTERNAL']).default('TENANT'), submittedAt: isoDateTimeSchema.optional(), freshnessSeconds: z.number().int().min(60).max(86400).optional() }).strict();
15
+ const argumentsSchema = z.record(z.string(), z.json());
16
+ export const workflowNextActionSchema = z.object({ id: z.string(), tool: z.string().nullable(), arguments: argumentsSchema, requiredScopes: z.array(z.string()), missingScopes: z.array(z.string()), missingFields: z.array(z.string()), canExecute: z.boolean(), automatic: z.boolean(), reasonCode: z.string(), cli: z.object({ command: z.string(), flags: argumentsSchema }).strict(), http: z.object({ method: z.literal('POST'), path: z.literal('/mcp/management'), tool: z.string().nullable() }).strict() }).strict();
17
+ const readDecision = z.object({ action: z.enum(['ALLOW', 'REVIEW_REQUIRED', 'DENY']), reasonCodes: z.array(z.string()), authority: z.enum(['AUTHENTICATED_READER', 'LOCAL_PROFILE_SIMULATION']) }).strict();
18
+ export const workflowPlanSchema = z.object({ schemaVersion: z.literal(1), projectRef: consumerProjectRefSchema, ref: stableUriSchema, contentHash: sha256Schema, kind: z.string(), version: z.number().int().positive().nullable(), status: artifactStatusSchema.or(z.enum(['RAW_EVIDENCE', 'RAW_MATERIAL'])), productionPhase: z.enum(['PERSISTED', 'CATALOG_PROJECTED', 'REGISTERED']), rawMaterialAvailable: z.boolean().nullable(), readiness: publicationReadinessReportSchema.nullable(), reviewRef: stableUriSchema.nullable(), reviewDecision: z.enum(['PASS', 'REWORK', 'REJECT']).nullable(), support: z.object({ action: z.enum(['ALLOW', 'REVIEW_REQUIRED', 'DENY']), reasonCodes: z.array(z.string()), missingEvidenceRefs: z.array(stableUriSchema) }).strict().nullable(), governedPolicyReady: z.boolean(), consumerReadDecision: readDecision.nullable(), externalReady: z.boolean(), successorRef: stableUriSchema.nullable(), blockers: z.array(z.string()), nextActions: z.array(workflowNextActionSchema).max(70) }).strict();
19
+ export const workflowAdvanceResultSchema = z.object({ schemaVersion: z.literal(1), action: workflowActionSchema, previousRef: stableUriSchema, inserted: z.boolean(), plan: workflowPlanSchema }).strict();
20
+ export const workflowErrorSchema = z.object({ errorCode: z.string(), completedPhase: z.enum(['VALIDATED', 'PERSISTED', 'CATALOG_PROJECTED', 'REGISTERED']).optional(), ref: stableUriSchema.optional() }).strict();
21
+ export const workflowToolInputSchemas = { knowledge_workflow_guide: z.toJSONSchema(workflowGuideInputSchema, { target: 'draft-07' }), knowledge_workflow_plan: z.toJSONSchema(workflowPlanInputSchema, { target: 'draft-07' }), knowledge_workflow_advance: z.toJSONSchema(workflowAdvanceInputSchema, { target: 'draft-07' }), knowledge_agent_submit: z.toJSONSchema(agentSubmitInputSchema, { target: 'draft-07' }) };
22
+ export const workflowToolScopes = { knowledge_workflow_guide: 'knowledge.workflow.read', knowledge_workflow_plan: 'knowledge.workflow.read', knowledge_workflow_advance: 'knowledge.workflow.read', knowledge_agent_submit: 'knowledge.material.write' };
23
+ export const workflowActionScopes = { PREPARE_SOURCE: 'knowledge.compose', SUBMIT_REVIEW: 'knowledge.compose', FINALIZE_REVIEW: 'knowledge.approve', REGISTER: 'knowledge.material.write' };
24
+ /** 网络成功和失败共享可发现 schema,阶段包含已经完成注册后的尾部失败。 */
25
+ export const agentSubmitResultSchema = z.object({ schemaVersion: z.literal(1), production: z.object({ phase: z.enum(['CATALOG_PROJECTED', 'REGISTERED']), ref: stableUriSchema, registered: z.boolean(), identity: z.enum(['CONFIGURED', 'NOT_CONFIGURED']) }).strict(), presentation: z.object({ documentRef: stableUriSchema, inserted: z.boolean(), contentHash: sha256Schema }).strict().nullable(), evidenceRef: stableUriSchema, projectRef: consumerProjectRefSchema, contentHash: sha256Schema, byteLength: z.number().int().min(1).max(65536), inserted: z.boolean(), lifecycle: z.literal('QUEUED'), contentClass: z.literal('RAW_EVIDENCE'), nextStep: z.object({ tool: z.literal('knowledge_workflow_plan'), arguments: workflowPlanInputSchema }).strict() }).strict();
26
+ const guideSchema = z.object({ schemaVersion: z.literal(1), model: z.record(z.string(), z.json()), rules: z.array(z.string()), tools: z.record(z.string(), z.object({ requiredScope: z.string(), inputSchema: z.json() }).strict()), advanceScopes: z.record(z.string(), z.string()), https: z.json() }).strict();
27
+ const output = (success) => ({ type: 'object', oneOf: [z.toJSONSchema(success, { target: 'draft-07' }), z.toJSONSchema(workflowErrorSchema, { target: 'draft-07' })] });
28
+ export const workflowToolOutputSchemas = { knowledge_workflow_guide: output(guideSchema), knowledge_workflow_plan: output(workflowPlanSchema), knowledge_workflow_advance: output(workflowAdvanceResultSchema), knowledge_agent_submit: output(agentSubmitResultSchema) };
29
+ /** 同一份模型与参数 schema 供 CLI、MCP guide 和文档示例使用;不给 review 默认 PASS。 */
30
+ export function workflowGuide() {
31
+ const tools = {};
32
+ for (const [name, schema] of Object.entries(workflowToolInputSchemas))
33
+ tools[name] = { requiredScope: workflowToolScopes[name], inputSchema: schema };
34
+ for (const [name, schema] of Object.entries(managementToolInputSchemas))
35
+ tools[name] = { requiredScope: name === 'knowledge_review' ? 'knowledge.review' : name === 'knowledge_finalize_review' ? 'knowledge.approve' : 'knowledge.compose', inputSchema: schema };
36
+ return { schemaVersion: 1, model: { raw: 'Evidence / Material 保留原字节和 provenance;原文可读不等于结论已审核。', reviewed: 'KNOWLEDGE / INSIGHT', lifecycle: ['DRAFT', 'READY_FOR_REVIEW', 'REVIEW(PASS|REWORK|REJECT)', 'APPROVED|REWORK_REQUIRED|REJECTED'], publication: ['PERSISTED', 'CATALOG_PROJECTED', 'REGISTERED', 'consumer read ALLOW'] }, rules: ['先调用 knowledge_workflow_plan,再执行 canExecute 动作;缺字段由 Agent 补齐并重新计划。', '读取原文、核对引用和适用范围后,获授权 reviewer 显式写 PASS / REWORK / REJECT;不根据写入成功推断 PASS。', 'RESEARCH 先正式合成为 KNOWLEDGE / INSIGHT;Claim Currentness proposal 使用专门审核链。', 'freshnessSeconds 仅为作者在系统内首次保存的精确快照时效,不证明外部网页已复核;同身份重放不延长时效。', 'externalReady 需要注册、治理门通过及当前已鉴权消费者实际 read ALLOW;CLI profile 是模拟。', 'Plan 不提供正文或 Review summary;审核时使用独立 read scope 读取 exact ref。'], tools, advanceScopes: workflowActionScopes, https: { method: 'POST', path: '/mcp/management', body: { tool: 'tool name', arguments: '对应 inputSchema' }, authorization: 'OAuth Bearer + client/project binding;API key 不授予管理权限' } };
37
+ }
@@ -0,0 +1,142 @@
1
+ /** 客户端只持久化私有配置与凭据,不包含资料或运行数据库。 */
2
+ import { open, mkdir, lstat, rename, unlink } from 'node:fs/promises';
3
+ import { constants } from 'node:fs';
4
+ import path from 'node:path';
5
+ import { randomBytes } from 'node:crypto';
6
+ import { AuthError } from '@native-knowledge/knowledge-sdk';
7
+ export class ProfileStore {
8
+ root;
9
+ constructor(root) {
10
+ this.root = root;
11
+ if (!path.isAbsolute(root))
12
+ throw new AuthError('AUTH_CONFIG_PATH_INVALID');
13
+ }
14
+ name(name) { if (!/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(name))
15
+ throw new AuthError('AUTH_PROFILE_INVALID'); return name; }
16
+ async directory(create = false) { if (create)
17
+ await mkdir(this.root, { recursive: true, mode: 0o700 }); let s; try {
18
+ s = await lstat(this.root);
19
+ }
20
+ catch (e) {
21
+ if (e.code === 'ENOENT' && !create)
22
+ return false;
23
+ throw e;
24
+ } if (!s.isDirectory() || s.isSymbolicLink() || s.uid !== process.getuid?.() || (s.mode & 0o077) !== 0)
25
+ throw new AuthError('AUTH_CONFIG_PERMISSIONS'); return true; }
26
+ async read(name) {
27
+ if (!await this.directory())
28
+ return null;
29
+ let h;
30
+ try {
31
+ h = await open(path.join(this.root, name), constants.O_RDONLY | constants.O_NOFOLLOW);
32
+ }
33
+ catch (e) {
34
+ if (e.code === 'ENOENT')
35
+ return null;
36
+ throw new AuthError('AUTH_CONFIG_PERMISSIONS');
37
+ }
38
+ try {
39
+ const s = await h.stat();
40
+ if (!s.isFile() || s.uid !== process.getuid?.() || (s.mode & 0o077) !== 0 || s.size > 65536)
41
+ throw new AuthError('AUTH_CONFIG_PERMISSIONS');
42
+ return JSON.parse(await h.readFile('utf8'));
43
+ }
44
+ catch (e) {
45
+ if (e instanceof AuthError)
46
+ throw e;
47
+ throw new AuthError('AUTH_CONFIG_INVALID');
48
+ }
49
+ finally {
50
+ await h.close();
51
+ }
52
+ }
53
+ async write(name, value) { await this.directory(true); const temp = path.join(this.root, '.write-' + randomBytes(16).toString('hex')), h = await open(temp, 'wx', 0o600); try {
54
+ await h.writeFile(JSON.stringify(value));
55
+ await h.sync();
56
+ await h.close();
57
+ await rename(temp, path.join(this.root, name));
58
+ const d = await open(this.root, 'r');
59
+ try {
60
+ await d.sync();
61
+ }
62
+ finally {
63
+ await d.close();
64
+ }
65
+ }
66
+ catch (e) {
67
+ await h.close().catch(() => { });
68
+ await unlink(temp).catch(() => { });
69
+ throw e;
70
+ } }
71
+ async config() { const c = await this.read('profiles.json') ?? { version: 1, selected: null, profiles: {} }; if (c.version !== 1 || !c.profiles || Array.isArray(c.profiles) || typeof c.profiles !== 'object' || c.selected !== null && typeof c.selected !== 'string')
72
+ throw new AuthError('AUTH_CONFIG_INVALID'); return c; }
73
+ async selected(explicit) { const c = await this.config(), name = explicit ?? c.selected; if (!name || !Object.hasOwn(c.profiles, this.name(name)))
74
+ throw new AuthError('AUTH_REQUIRED'); return { name, profile: c.profiles[name] }; }
75
+ async secret(name) { const s = await this.read(this.name(name) + '.secret.json'); if (s && (!Number.isSafeInteger(s.generation) || s.generation < 1 || !['READY', 'REFRESH_PENDING', 'REAUTH_REQUIRED'].includes(s.state) || typeof s.expiresAt !== 'string' || !Number.isFinite(Date.parse(s.expiresAt)) || !/^[-\w]{43}$/.test(s.accessToken) || !/^[-\w]{43}$/.test(s.refreshToken) || !Array.isArray(s.scopes)))
76
+ throw new AuthError('AUTH_CONFIG_INVALID'); return s; }
77
+ async putSecret(name, s) { await this.write(this.name(name) + '.secret.json', s); }
78
+ async lock(operation) {
79
+ await this.directory(true);
80
+ const file = path.join(this.root, 'operation.lock'), deadline = Date.now() + 20000;
81
+ let h;
82
+ while (!h) {
83
+ try {
84
+ h = await open(file, 'wx', 0o600);
85
+ await h.writeFile(JSON.stringify({ pid: process.pid, at: Date.now() }));
86
+ }
87
+ catch (e) {
88
+ if (h) {
89
+ await h.close();
90
+ h = undefined;
91
+ await unlink(file).catch(() => { });
92
+ throw e;
93
+ }
94
+ if (e.code !== 'EEXIST')
95
+ throw e;
96
+ let old;
97
+ try {
98
+ old = await this.read('operation.lock');
99
+ }
100
+ catch (e) {
101
+ if (!(e instanceof AuthError) || e.code !== 'AUTH_CONFIG_INVALID' || Date.now() >= deadline)
102
+ throw e;
103
+ await new Promise(r => setTimeout(r, 50));
104
+ continue;
105
+ }
106
+ if (old && Number.isSafeInteger(old.pid) && old.pid > 0 && Date.now() - old.at > 60000) {
107
+ let alive = true;
108
+ try {
109
+ process.kill(old.pid, 0);
110
+ }
111
+ catch (e) {
112
+ if (e.code === 'ESRCH')
113
+ alive = false;
114
+ }
115
+ if (!alive) {
116
+ await unlink(file).catch(() => { });
117
+ continue;
118
+ }
119
+ }
120
+ if (Date.now() >= deadline)
121
+ throw new AuthError('AUTH_CONFIG_BUSY');
122
+ await new Promise(r => setTimeout(r, 50));
123
+ }
124
+ }
125
+ try {
126
+ return await operation();
127
+ }
128
+ finally {
129
+ await h.close();
130
+ await unlink(file);
131
+ }
132
+ }
133
+ async save(name, p, t) { this.name(name); return this.lock(async () => { const c = await this.config(), old = c.profiles[name]; if (old && ['issuer', 'resource', 'clientId', 'userId', 'tenantId', 'authorityVersion'].some(k => old.session[k] !== p.session[k]))
134
+ throw new AuthError('AUTH_CONTEXT_MISMATCH'); const previous = await this.secret(name); await this.putSecret(name, { ...t, generation: (previous?.generation ?? 0) + 1, state: 'READY' }); c.profiles[name] = p; c.selected = name; await this.write('profiles.json', c); }); }
135
+ async clear(name) { await this.directory(); await unlink(path.join(this.root, this.name(name) + '.secret.json')).catch(e => { if (e.code !== 'ENOENT')
136
+ throw e; }); }
137
+ async use(name) { return this.lock(async () => { const c = await this.config(); if (!Object.hasOwn(c.profiles, this.name(name)))
138
+ throw new AuthError('AUTH_PROFILE_INVALID'); c.selected = name; await this.write('profiles.json', c); return { selected: name }; }); }
139
+ async remove(name) { return this.lock(async () => { const c = await this.config(); if (await this.secret(name))
140
+ throw new AuthError('AUTH_LOGOUT_REQUIRED'); delete c.profiles[this.name(name)]; if (c.selected === name)
141
+ c.selected = null; await this.write('profiles.json', c); return { removed: name }; }); }
142
+ }
package/package.json CHANGED
@@ -1,33 +1,23 @@
1
1
  {
2
- "version": "0.1.0-rc.1",
2
+ "name": "@native-knowledge/cli",
3
+ "version": "0.1.0-rc.3",
3
4
  "private": false,
4
5
  "type": "module",
5
- "license": "MIT",
6
6
  "engines": {
7
7
  "node": ">=24"
8
8
  },
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/SENLIN746/native-knowledge.git"
12
- },
13
- "publishConfig": {
14
- "access": "public",
15
- "tag": "next",
16
- "registry": "https://registry.npmjs.org/"
17
- },
9
+ "license": "Apache-2.0",
18
10
  "files": [
19
11
  "dist",
20
- "README.md",
21
- "LICENSE"
12
+ "LICENSE",
13
+ "NOTICE"
22
14
  ],
23
- "name": "@native-knowledge/cli",
24
- "description": "Network CLI for native-knowledge",
25
15
  "bin": {
26
16
  "native-knowledge": "./dist/cli.js",
27
17
  "knowledge-v2": "./dist/cli.js"
28
18
  },
29
19
  "dependencies": {
30
- "@native-knowledge/knowledge-sdk": "0.1.0-rc.1",
31
- "zod": "4.6.7"
20
+ "@native-knowledge/knowledge-sdk": "0.1.0-rc.3",
21
+ "zod": "^4.6.7"
32
22
  }
33
23
  }
package/README.md DELETED
@@ -1,28 +0,0 @@
1
- # native-knowledge CLI
2
-
3
- Node.js 24+ network client for native-knowledge. MIT licensed.
4
-
5
- ```sh
6
- npm install --global @native-knowledge/cli@next
7
- native-knowledge help
8
- native-knowledge agent find --query "saved materials" \
9
- --server https://knowledge.example.com --tenant-id your-tenant-id
10
- ```
11
-
12
- The `knowledge-v2` command is a supported alias. Read the access token from
13
- `KNOWLEDGE_V2_OAUTH_ACCESS_TOKEN` or `--token-file /path/to/private-token`.
14
- Keep token files accessible only to your operating-system account. Tokens are
15
- never accepted as command-line arguments or embedded in URLs.
16
-
17
- Commands: `agent find`, `agent tool`, `agent task`, `agent input`, `agent call`.
18
- Use `--input-file` for structured operation input. Calls execute only when
19
- explicitly requested. Guidance never automatically follows suggestions, approves
20
- reviews, schedules collection or retries writes. `--guided` preserves safe
21
- failure receipts. On `OUTCOME_UNKNOWN`, inspect the exact state/receipt before
22
- deciding whether any further action is appropriate.
23
-
24
- HTTPS and a 30-second request/body deadline apply by default. HTTP requires the
25
- explicit `--allow-insecure-http` opt-in for a trusted local test server.
26
- The public CLI contains no direct database access, local Host administration,
27
- collector runtime or install hooks. Existing private Host commands are maintained
28
- separately. Installation, help and discovery do not start collection.