@agentproto/corpus 0.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,205 @@
1
+ /**
2
+ * ClockPort — abstracted time source.
3
+ *
4
+ * Tests need deterministic timestamps; production wants Date.now().
5
+ * Every component that emits `*_at` fields or temporal scores takes
6
+ * a ClockPort so the same code is testable + real.
7
+ */
8
+ interface ClockPort {
9
+ /** Wall-clock now. */
10
+ now(): Date;
11
+ /** Current ms since epoch. Equivalent to `now().getTime()`. */
12
+ nowMs(): number;
13
+ }
14
+ /** Real-time implementation. The local CLI host wires this in. */
15
+ declare const systemClock: ClockPort;
16
+
17
+ /**
18
+ * FsPort — filesystem boundary the corpus kit consumes.
19
+ *
20
+ * Structural interface, NOT a nominal one — any object exposing this
21
+ * shape satisfies it. Matches the existing Guilde `WorkspaceFsLike`
22
+ * convention (projects/guilde/packages/core/src/services/role-source/
23
+ * workspace.ts:38-47) so cloud and local topologies share the same
24
+ * minimal contract.
25
+ *
26
+ * Paths are relative to the workspace root (no leading slash). The
27
+ * concrete implementation (MastraFilesystem in cloud, local-fs in CLI,
28
+ * mcp-filesystem for hybrid topologies) does the resolution.
29
+ */
30
+ interface FsStat {
31
+ readonly kind: "file" | "directory";
32
+ readonly bytes?: number;
33
+ readonly modifiedAt?: Date;
34
+ }
35
+ interface FsPort {
36
+ /** True if a file or directory exists at `path`. */
37
+ exists(path: string): Promise<boolean>;
38
+ /** Read a file as UTF-8 text. Throws on missing path. */
39
+ readFile(path: string): Promise<string>;
40
+ /**
41
+ * Write a file atomically — caller assumes content is persisted on
42
+ * resolve. Implementations are expected to write to a temp file +
43
+ * rename so partial writes never become visible.
44
+ */
45
+ writeFile(path: string, content: string): Promise<void>;
46
+ /**
47
+ * Append to a file. MUST be atomic against concurrent appends to the
48
+ * same path — used by the event emitter for _log.md. If the file
49
+ * does not exist, create it.
50
+ */
51
+ appendFile(path: string, content: string): Promise<void>;
52
+ /**
53
+ * List immediate children of a directory. Returns names only (NOT
54
+ * full paths). Throws if `path` is not a directory.
55
+ */
56
+ readdir(path: string): Promise<readonly string[]>;
57
+ /**
58
+ * Recursive directory listing — returns workspace-relative paths of
59
+ * every file under `path`. Skips directories starting with `.`.
60
+ */
61
+ walk(path: string): Promise<readonly string[]>;
62
+ /** File metadata. Returns null if the path doesn't exist. */
63
+ stat(path: string): Promise<FsStat | null>;
64
+ /**
65
+ * Acquire a cross-process advisory lock on `path`. Used by the
66
+ * writer for atomic multi-file transactions (entry write + _index
67
+ * regen + _log append). Implementations MAY no-op for single-process
68
+ * topologies (local CLI), but cloud hosts MUST enforce real locking.
69
+ */
70
+ lock(path: string): Promise<FsLockHandle>;
71
+ }
72
+ interface FsLockHandle {
73
+ release(): Promise<void>;
74
+ }
75
+
76
+ /**
77
+ * IdentityPort — resolves who is currently acting on the corpus.
78
+ *
79
+ * Used by the event emitter (attestations) and the access/scope policy
80
+ * layers (which use the identityTree to match `appliesTo`). Production
81
+ * Guilde resolves from session; the local CLI resolves from OS user.
82
+ */
83
+ interface CallerIdentity {
84
+ /** Stable identity slug. Examples: "operators/sarah", "users/jeremy". */
85
+ readonly principal: string;
86
+ /**
87
+ * Identity tree, most-specific → least-specific. Used by the corpus
88
+ * scope-policy middleware to match against `appliesTo`. Examples:
89
+ *
90
+ * [
91
+ * "ws://operators/sarah",
92
+ * "ws://roles/senior-rep",
93
+ * "ws://workspaces/sales-na",
94
+ * "ws://guilds/acme-sales",
95
+ * "ws://orgs/acme-corp",
96
+ * ]
97
+ *
98
+ * Role hierarchy is resolved here (IdentityPort), not in scope matching.
99
+ */
100
+ readonly identityTree: readonly string[];
101
+ /** Optional display name for `_log.md` attestations. */
102
+ readonly displayName?: string;
103
+ }
104
+ interface IdentityPort {
105
+ /** Resolve the current caller. Throws if no identity is in context. */
106
+ resolve(): Promise<CallerIdentity>;
107
+ }
108
+
109
+ /**
110
+ * FetcherPort — the "URL → readable text" boundary the WebImporter
111
+ * consumes. Keeps the importer PURE and testable: the importer decides
112
+ * *what* to import (slugging, dedup, candidate shape); the port supplies
113
+ * the one capability that is environment-bound — fetching and reducing a
114
+ * URL to text.
115
+ *
116
+ * Structural interface, NOT nominal — any object of this shape satisfies
117
+ * it. Concrete implementations live where the capability lives:
118
+ *
119
+ * - `plugin-local-browser` (agentproto daemon / PTY): tier-1 YouTube
120
+ * captions via InnerTube + tier-2 article readability, using the
121
+ * user's authenticated browser. This is the rich path.
122
+ * - a server-side headless fetcher (Guilde corpus-host): public
123
+ * captions + readability only, no user session.
124
+ * - a fake (tests): canned { title, text } per URL.
125
+ *
126
+ * The port is deliberately strategy-agnostic. A tier-3 Whisper impl
127
+ * (yt-dlp → ffmpeg → STT) is just a fatter `fetch()` for caption-less
128
+ * videos — the importer never changes.
129
+ */
130
+ type FetchedSourceKind = "video" | "article" | "page" | "unknown";
131
+ interface FetchedSource {
132
+ /** Human-readable title (video/page title or article headline). */
133
+ readonly title: string;
134
+ /** Extracted text — a transcript for video, readable body for articles. */
135
+ readonly text: string;
136
+ /** What the fetcher determined the URL to be. */
137
+ readonly kind: FetchedSourceKind;
138
+ /** BCP-47 language code, when the fetcher can detect it. */
139
+ readonly language?: string;
140
+ /** How the text was obtained — for provenance / dedup auditing. */
141
+ readonly via?: "captions" | "readability" | "transcription" | string;
142
+ }
143
+ interface FetcherPort {
144
+ /**
145
+ * Fetch a URL and reduce it to text. Resolves with the extracted
146
+ * source, or `null` when the URL cannot be reduced to text (e.g. a
147
+ * caption-less video on a tier that does not transcribe). Returning
148
+ * `null` lets the importer skip-with-warning rather than abort the
149
+ * batch; throwing is reserved for hard failures (auth, network).
150
+ */
151
+ fetch(url: string): Promise<FetchedSource | null>;
152
+ }
153
+
154
+ /**
155
+ * EvaluatorPort — minimal evaluator contract the corpus kit consumes.
156
+ *
157
+ * The kit never imports IEvaluator from @agstudio/integration-evaluator
158
+ * (that's an agstudio type, would break the purity invariant). Instead
159
+ * it consumes this minimal port; the agstudio side's
160
+ * `RubricStringEvaluatorAdapter` / `LLMJudgeEvaluatorAdapter` /
161
+ * `EnsembleEvaluatorAdapter` all satisfy it structurally.
162
+ *
163
+ * Matches @agstudio/integration-evaluator IEvaluator shape so cloud
164
+ * adapters drop in as `EvaluatorPort` instances without conversion.
165
+ */
166
+ interface EvalRubricPort {
167
+ readonly slug: string;
168
+ readonly title: string;
169
+ readonly version: string;
170
+ readonly dimensions: readonly {
171
+ readonly id: string;
172
+ readonly weight: number;
173
+ readonly description: string;
174
+ }[];
175
+ readonly scoringScale: "0..1" | "0..5";
176
+ readonly passingThreshold: number;
177
+ readonly guidance?: string;
178
+ readonly metadata?: Readonly<Record<string, unknown>>;
179
+ }
180
+ interface EvalContextPort {
181
+ readonly operatorRef?: string;
182
+ readonly conversationId?: string;
183
+ readonly appliedPlaybooks?: readonly string[];
184
+ readonly arm?: "shadow" | "baseline" | string;
185
+ readonly metadata?: Readonly<Record<string, unknown>>;
186
+ }
187
+ interface EvalInputPort {
188
+ readonly rubric: EvalRubricPort;
189
+ readonly prompt: string;
190
+ readonly response: string;
191
+ readonly context?: EvalContextPort;
192
+ }
193
+ interface EvalResultPort {
194
+ readonly score: number;
195
+ readonly dimensions: Readonly<Record<string, number>>;
196
+ readonly rationale?: string;
197
+ readonly evaluatorEngineId: string;
198
+ readonly evaluatorVersion: string;
199
+ readonly evaluatedAt: string;
200
+ }
201
+ interface EvaluatorPort {
202
+ evaluate(input: EvalInputPort): Promise<EvalResultPort>;
203
+ }
204
+
205
+ export { type CallerIdentity, type ClockPort, type EvalContextPort, type EvalInputPort, type EvalResultPort, type EvalRubricPort, type EvaluatorPort, type FetchedSource, type FetchedSourceKind, type FetcherPort, type FsLockHandle, type FsPort, type FsStat, type IdentityPort, systemClock };
@@ -0,0 +1,3 @@
1
+ export { systemClock } from '../chunk-KYX2DTEH.mjs';
2
+ //# sourceMappingURL=index.mjs.map
3
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
@@ -0,0 +1,3 @@
1
+ export { CandidatesSidecar, SidecarDuplicateError, SidecarNotFoundError } from './chunk-UPX26MYH.mjs';
2
+ //# sourceMappingURL=sidecar-TTWQD5R3.mjs.map
3
+ //# sourceMappingURL=sidecar-TTWQD5R3.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"sidecar-TTWQD5R3.mjs"}
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@agentproto/corpus",
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "@agentproto/corpus — canonical composition of AIP-10 KNOWLEDGE, AIP-12 PLAYBOOK, AIP-18 COLLECTION, AIP-9 OPERATOR, AIP-15 WORKFLOW, AIP-41 ROUTINE into an autonomous knowledge-improvement system. Pure: zero runtime, zero filesystem, zero HTTP — all I/O via injected ports.",
5
+ "keywords": [
6
+ "agentproto",
7
+ "corpus",
8
+ "aip-10",
9
+ "aip-12",
10
+ "aip-18",
11
+ "knowledge-base",
12
+ "open-standard",
13
+ "agentic"
14
+ ],
15
+ "homepage": "https://agentproto.sh/docs/corpus",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/agentproto/ts",
19
+ "directory": "packages/corpus"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/agentproto/ts/issues"
23
+ },
24
+ "license": "MIT",
25
+ "type": "module",
26
+ "main": "dist/index.mjs",
27
+ "module": "dist/index.mjs",
28
+ "types": "dist/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.mjs",
33
+ "default": "./dist/index.mjs"
34
+ },
35
+ "./ports": {
36
+ "types": "./dist/ports/index.d.ts",
37
+ "import": "./dist/ports/index.mjs",
38
+ "default": "./dist/ports/index.mjs"
39
+ },
40
+ "./package.json": "./package.json"
41
+ },
42
+ "files": [
43
+ "dist",
44
+ "README.md",
45
+ "LICENSE"
46
+ ],
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
50
+ "sideEffects": false,
51
+ "dependencies": {
52
+ "ajv": "^8.17.1",
53
+ "ajv-formats": "^3.0.1",
54
+ "gray-matter": "^4.0.3",
55
+ "yaml": "^2.7.0",
56
+ "zod": "^4.4.3",
57
+ "@agentproto/collection": "0.1.0-alpha.1",
58
+ "@agentproto/playbook": "0.1.0-alpha.1",
59
+ "@agentproto/knowledge": "0.1.0-alpha.1",
60
+ "@agentproto/operator": "0.1.0-alpha.1",
61
+ "@agentproto/routine": "0.1.0-alpha.1",
62
+ "@agentproto/registry": "0.1.0-alpha.1",
63
+ "@agentproto/workflow": "0.1.0-alpha.1"
64
+ },
65
+ "devDependencies": {
66
+ "@types/node": "^25.6.2",
67
+ "tsup": "^8.5.1",
68
+ "typescript": "^5.9.3",
69
+ "vitest": "^3.2.4",
70
+ "@agentproto/tooling": "0.1.0-alpha.0"
71
+ },
72
+ "scripts": {
73
+ "dev": "tsup --watch",
74
+ "build": "tsup",
75
+ "clean": "rm -rf dist",
76
+ "check-types": "tsc --noEmit",
77
+ "test": "vitest run --passWithNoTests",
78
+ "test:watch": "vitest"
79
+ }
80
+ }