@cleocode/cant 2026.4.109 → 2026.4.111

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/dist/index.d.ts CHANGED
@@ -12,8 +12,8 @@ export type { ConsolidateOptions, MentalModel, MentalModelObservation, MentalMod
12
12
  export { consolidate, createEmptyModel, harvestObservations, renderMentalModel, } from './mental-model.js';
13
13
  export type { ConvertedFile, MigrationOptions, MigrationResult, UnconvertedSection, } from './migrate/index';
14
14
  export { migrateMarkdown, serializeCantDocument, showDiff, showSummary } from './migrate/index';
15
- export type { NativeDiagnostic, NativeParseDocumentResult, NativeParseError, NativeParseResult, NativePipelineResult, NativePipelineStep, NativeValidateResult, } from './native-loader';
16
- export { cantClassifyDirectiveNative, cantExecutePipelineNative, cantExtractAgentProfilesNative, cantParseDocumentNative, cantParseNative, cantValidateDocumentNative, initWasm, isNativeAvailable, isWasmAvailable, } from './native-loader';
15
+ export type { AgentProfile, NativeDiagnostic, NativeParseDocumentResult, NativeParseError, NativeParseResult, NativePipelineResult, NativePipelineStep, NativeValidateResult, } from './native-loader';
16
+ export { cantClassifyDirectiveNative, cantExecutePipelineNative, cantExtractAgentProfilesNative, cantParseDocumentNative, cantParseNative, cantValidateDocumentNative, extractAgentProfilesTyped, extractAgentSkills, initWasm, isNativeAvailable, isWasmAvailable, validateAgentCantPath, } from './native-loader';
17
17
  export type { ParsedCANTMessage } from './parse';
18
18
  export { initCantParser, parseCANTMessage } from './parse';
19
19
  export type { CantAgentV3, CantContextSourceDef, CantContractBlock, CantContractClause, CantMentalModelRef, CantOverflowStrategy, CantPathPermissions, CantTier, DirectiveType, } from './types';
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // JIT Agent Composer (ULTRAPLAN Wave 5)
3
3
  // Wave 7a: BRAIN-backed ContextProvider (T432)
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.resolveWorktreeRoot = exports.mergeWorktree = exports.listWorktrees = exports.createWorktree = exports.isCantAgentV3 = exports.parseCANTMessage = exports.initCantParser = exports.isWasmAvailable = exports.isNativeAvailable = exports.initWasm = exports.cantValidateDocumentNative = exports.cantParseNative = exports.cantParseDocumentNative = exports.cantExtractAgentProfilesNative = exports.cantExecutePipelineNative = exports.cantClassifyDirectiveNative = exports.showSummary = exports.showDiff = exports.serializeCantDocument = exports.migrateMarkdown = exports.renderMentalModel = exports.harvestObservations = exports.createEmptyModel = exports.consolidate = exports.WORKER_FORBIDDEN_SPAWN_TOOLS = exports.validateSpawnRequest = exports.THIN_AGENT_TOOLS_STRIPPED = exports.stripSpawnToolsForWorker = exports.ORCHESTRATOR_FORBIDDEN_TOOLS = exports.LEAD_FORBIDDEN_TOOLS = exports.filterToolsForRole = exports.validateDocument = exports.parseDocument = exports.listSections = exports.executePipeline = exports.brainContextProvider = exports.TIER_CAPS = exports.estimateTokens = exports.escalateTier = exports.composeSpawnPayload = exports.toCantAgentV3 = exports.compileBundle = void 0;
5
+ exports.resolveWorktreeRoot = exports.mergeWorktree = exports.listWorktrees = exports.createWorktree = exports.isCantAgentV3 = exports.parseCANTMessage = exports.initCantParser = exports.validateAgentCantPath = exports.isWasmAvailable = exports.isNativeAvailable = exports.initWasm = exports.extractAgentSkills = exports.extractAgentProfilesTyped = exports.cantValidateDocumentNative = exports.cantParseNative = exports.cantParseDocumentNative = exports.cantExtractAgentProfilesNative = exports.cantExecutePipelineNative = exports.cantClassifyDirectiveNative = exports.showSummary = exports.showDiff = exports.serializeCantDocument = exports.migrateMarkdown = exports.renderMentalModel = exports.harvestObservations = exports.createEmptyModel = exports.consolidate = exports.WORKER_FORBIDDEN_SPAWN_TOOLS = exports.validateSpawnRequest = exports.THIN_AGENT_TOOLS_STRIPPED = exports.stripSpawnToolsForWorker = exports.ORCHESTRATOR_FORBIDDEN_TOOLS = exports.LEAD_FORBIDDEN_TOOLS = exports.filterToolsForRole = exports.validateDocument = exports.parseDocument = exports.listSections = exports.executePipeline = exports.brainContextProvider = exports.TIER_CAPS = exports.estimateTokens = exports.escalateTier = exports.composeSpawnPayload = exports.toCantAgentV3 = exports.compileBundle = void 0;
6
6
  // Bundle compiler
7
7
  var bundle_1 = require("./bundle");
8
8
  Object.defineProperty(exports, "compileBundle", { enumerable: true, get: function () { return bundle_1.compileBundle; } });
@@ -49,9 +49,12 @@ Object.defineProperty(exports, "cantExtractAgentProfilesNative", { enumerable: t
49
49
  Object.defineProperty(exports, "cantParseDocumentNative", { enumerable: true, get: function () { return native_loader_1.cantParseDocumentNative; } });
50
50
  Object.defineProperty(exports, "cantParseNative", { enumerable: true, get: function () { return native_loader_1.cantParseNative; } });
51
51
  Object.defineProperty(exports, "cantValidateDocumentNative", { enumerable: true, get: function () { return native_loader_1.cantValidateDocumentNative; } });
52
+ Object.defineProperty(exports, "extractAgentProfilesTyped", { enumerable: true, get: function () { return native_loader_1.extractAgentProfilesTyped; } });
53
+ Object.defineProperty(exports, "extractAgentSkills", { enumerable: true, get: function () { return native_loader_1.extractAgentSkills; } });
52
54
  Object.defineProperty(exports, "initWasm", { enumerable: true, get: function () { return native_loader_1.initWasm; } });
53
55
  Object.defineProperty(exports, "isNativeAvailable", { enumerable: true, get: function () { return native_loader_1.isNativeAvailable; } });
54
56
  Object.defineProperty(exports, "isWasmAvailable", { enumerable: true, get: function () { return native_loader_1.isWasmAvailable; } });
57
+ Object.defineProperty(exports, "validateAgentCantPath", { enumerable: true, get: function () { return native_loader_1.validateAgentCantPath; } });
55
58
  // Parser
56
59
  var parse_1 = require("./parse");
57
60
  Object.defineProperty(exports, "initCantParser", { enumerable: true, get: function () { return parse_1.initCantParser; } });
@@ -135,12 +135,93 @@ export declare function cantParseDocumentNative(content: string): NativeParseDoc
135
135
  * @param content - The raw `.cant` file content to parse and validate.
136
136
  */
137
137
  export declare function cantValidateDocumentNative(content: string): NativeValidateResult;
138
+ /**
139
+ * A single agent profile extracted from a `.cant` document.
140
+ *
141
+ * @remarks
142
+ * Mirrors the subset of fields the Rust-side `cant_extract_agent_profiles`
143
+ * function emits (see R1-AGENT-ARCHITECTURE-AUDIT.md §1.7). Fields are
144
+ * optional because older `.cant` documents may omit them; resolver code
145
+ * MUST handle `undefined` per-field.
146
+ */
147
+ export interface AgentProfile {
148
+ /** Agent business id (kebab-case), e.g. `"cleo-prime"`. */
149
+ agentId?: string;
150
+ /** Declared role, e.g. `"orchestrator"`, `"lead"`, `"worker"`. */
151
+ role?: string;
152
+ /** Declared parent agent id, if any. */
153
+ parent?: string;
154
+ /** Skill slugs declared on the agent (cached here; SSoT is `agent_skills`). */
155
+ skills?: string[];
156
+ /** Free-form fields the native binding did not typify. */
157
+ [extra: string]: unknown;
158
+ }
138
159
  /**
139
160
  * Extract agent profiles from a `.cant` document via the native addon.
140
161
  *
141
162
  * @param content - The raw `.cant` file content.
163
+ *
164
+ * @remarks
165
+ * The native binding returns a loose `unknown[]`. Callers that need typed
166
+ * access should prefer {@link extractAgentProfilesTyped}, which validates
167
+ * the shape and returns `AgentProfile[]`.
142
168
  */
143
169
  export declare function cantExtractAgentProfilesNative(content: string): unknown[];
170
+ /**
171
+ * Typed wrapper around {@link cantExtractAgentProfilesNative}. Returns a
172
+ * best-effort `AgentProfile[]` by shallow-validating each entry.
173
+ *
174
+ * @param content - The raw `.cant` file content.
175
+ *
176
+ * @remarks
177
+ * Implements R1-AGENT-ARCHITECTURE-AUDIT Recommendation 3 by consolidating
178
+ * agent-profile / skill extraction into a single well-typed surface so
179
+ * downstream packages (`agent-install.ts`, `agent-doctor.ts`) do not have
180
+ * to re-implement `.cant` field parsing.
181
+ */
182
+ export declare function extractAgentProfilesTyped(content: string): AgentProfile[];
183
+ /**
184
+ * Extract the `skills: [...]` list from a `.cant` agent document.
185
+ *
186
+ * @param content - The raw `.cant` file content.
187
+ *
188
+ * @returns Deduplicated, trimmed skill slug list (empty array if none).
189
+ *
190
+ * @remarks
191
+ * Consolidates skill-parsing logic previously duplicated in
192
+ * `packages/core/src/store/agent-install.ts` and
193
+ * `packages/core/src/store/agent-doctor.ts` (R1 Recommendation 3). Both
194
+ * modules now delegate to this helper so they stay in lock-step.
195
+ */
196
+ export declare function extractAgentSkills(content: string): string[];
197
+ /**
198
+ * Validate that a `.cant` file path stays within a declared root directory.
199
+ *
200
+ * @param cantPath - Absolute path to the `.cant` file from the registry row.
201
+ * @param rootDir - Absolute root directory that the path MUST live inside
202
+ * (typically the project root or the global CANT agents dir).
203
+ *
204
+ * @returns `true` when `cantPath` is a descendant of `rootDir`; `false`
205
+ * otherwise. Also returns `false` for relative paths.
206
+ *
207
+ * @remarks
208
+ * Implements R1-AGENT-ARCHITECTURE-AUDIT Recommendation 4. A malicious or
209
+ * corrupted `agents.cant_path` row could point to `../../../etc/passwd`
210
+ * or a symlink outside the project. Callers (agent resolver, doctor)
211
+ * MUST gate any `readFileSync(cantPath)` on a successful
212
+ * `validateAgentCantPath()` check.
213
+ *
214
+ * @example
215
+ * ```ts
216
+ * import { validateAgentCantPath } from '@cleocode/cant';
217
+ *
218
+ * const cantPath = row.cant_path;
219
+ * if (!validateAgentCantPath(cantPath, projectRoot)) {
220
+ * throw new Error(`cant_path outside project root: ${cantPath}`);
221
+ * }
222
+ * ```
223
+ */
224
+ export declare function validateAgentCantPath(cantPath: string, rootDir: string): boolean;
144
225
  /**
145
226
  * Execute a deterministic pipeline from a `.cant` file via the native addon.
146
227
  *
@@ -19,6 +19,9 @@ exports.cantClassifyDirectiveNative = cantClassifyDirectiveNative;
19
19
  exports.cantParseDocumentNative = cantParseDocumentNative;
20
20
  exports.cantValidateDocumentNative = cantValidateDocumentNative;
21
21
  exports.cantExtractAgentProfilesNative = cantExtractAgentProfilesNative;
22
+ exports.extractAgentProfilesTyped = extractAgentProfilesTyped;
23
+ exports.extractAgentSkills = extractAgentSkills;
24
+ exports.validateAgentCantPath = validateAgentCantPath;
22
25
  exports.cantExecutePipelineNative = cantExecutePipelineNative;
23
26
  /* eslint-disable @typescript-eslint/no-require-imports */
24
27
  const node_path_1 = require("node:path");
@@ -109,10 +112,112 @@ function cantValidateDocumentNative(content) {
109
112
  * Extract agent profiles from a `.cant` document via the native addon.
110
113
  *
111
114
  * @param content - The raw `.cant` file content.
115
+ *
116
+ * @remarks
117
+ * The native binding returns a loose `unknown[]`. Callers that need typed
118
+ * access should prefer {@link extractAgentProfilesTyped}, which validates
119
+ * the shape and returns `AgentProfile[]`.
112
120
  */
113
121
  function cantExtractAgentProfilesNative(content) {
114
122
  return requireNative().cantExtractAgentProfiles(content);
115
123
  }
124
+ /**
125
+ * Typed wrapper around {@link cantExtractAgentProfilesNative}. Returns a
126
+ * best-effort `AgentProfile[]` by shallow-validating each entry.
127
+ *
128
+ * @param content - The raw `.cant` file content.
129
+ *
130
+ * @remarks
131
+ * Implements R1-AGENT-ARCHITECTURE-AUDIT Recommendation 3 by consolidating
132
+ * agent-profile / skill extraction into a single well-typed surface so
133
+ * downstream packages (`agent-install.ts`, `agent-doctor.ts`) do not have
134
+ * to re-implement `.cant` field parsing.
135
+ */
136
+ function extractAgentProfilesTyped(content) {
137
+ const raw = cantExtractAgentProfilesNative(content);
138
+ if (!Array.isArray(raw))
139
+ return [];
140
+ return raw.filter((entry) => {
141
+ return typeof entry === 'object' && entry !== null;
142
+ });
143
+ }
144
+ /**
145
+ * Extract the `skills: [...]` list from a `.cant` agent document.
146
+ *
147
+ * @param content - The raw `.cant` file content.
148
+ *
149
+ * @returns Deduplicated, trimmed skill slug list (empty array if none).
150
+ *
151
+ * @remarks
152
+ * Consolidates skill-parsing logic previously duplicated in
153
+ * `packages/core/src/store/agent-install.ts` and
154
+ * `packages/core/src/store/agent-doctor.ts` (R1 Recommendation 3). Both
155
+ * modules now delegate to this helper so they stay in lock-step.
156
+ */
157
+ function extractAgentSkills(content) {
158
+ const profiles = extractAgentProfilesTyped(content);
159
+ const skills = new Set();
160
+ for (const profile of profiles) {
161
+ if (Array.isArray(profile.skills)) {
162
+ for (const skill of profile.skills) {
163
+ if (typeof skill === 'string') {
164
+ const trimmed = skill.trim();
165
+ if (trimmed.length > 0)
166
+ skills.add(trimmed);
167
+ }
168
+ }
169
+ }
170
+ }
171
+ return [...skills];
172
+ }
173
+ /**
174
+ * Validate that a `.cant` file path stays within a declared root directory.
175
+ *
176
+ * @param cantPath - Absolute path to the `.cant` file from the registry row.
177
+ * @param rootDir - Absolute root directory that the path MUST live inside
178
+ * (typically the project root or the global CANT agents dir).
179
+ *
180
+ * @returns `true` when `cantPath` is a descendant of `rootDir`; `false`
181
+ * otherwise. Also returns `false` for relative paths.
182
+ *
183
+ * @remarks
184
+ * Implements R1-AGENT-ARCHITECTURE-AUDIT Recommendation 4. A malicious or
185
+ * corrupted `agents.cant_path` row could point to `../../../etc/passwd`
186
+ * or a symlink outside the project. Callers (agent resolver, doctor)
187
+ * MUST gate any `readFileSync(cantPath)` on a successful
188
+ * `validateAgentCantPath()` check.
189
+ *
190
+ * @example
191
+ * ```ts
192
+ * import { validateAgentCantPath } from '@cleocode/cant';
193
+ *
194
+ * const cantPath = row.cant_path;
195
+ * if (!validateAgentCantPath(cantPath, projectRoot)) {
196
+ * throw new Error(`cant_path outside project root: ${cantPath}`);
197
+ * }
198
+ * ```
199
+ */
200
+ function validateAgentCantPath(cantPath, rootDir) {
201
+ if (typeof cantPath !== 'string' || cantPath.length === 0)
202
+ return false;
203
+ if (typeof rootDir !== 'string' || rootDir.length === 0)
204
+ return false;
205
+ if (!(0, node_path_1.isAbsolute)(cantPath) || !(0, node_path_1.isAbsolute)(rootDir))
206
+ return false;
207
+ const resolvedRoot = (0, node_path_1.resolve)(rootDir);
208
+ const resolvedPath = (0, node_path_1.resolve)(cantPath);
209
+ const rel = (0, node_path_1.relative)(resolvedRoot, resolvedPath);
210
+ // `relative()` returns a path that starts with `..` when the target is
211
+ // outside the root. An absolute return value (Windows drive change) is
212
+ // also outside. Empty string means the path IS the root — reject that.
213
+ if (rel.length === 0)
214
+ return false;
215
+ if (rel.startsWith('..'))
216
+ return false;
217
+ if ((0, node_path_1.isAbsolute)(rel))
218
+ return false;
219
+ return true;
220
+ }
116
221
  /**
117
222
  * Execute a deterministic pipeline from a `.cant` file via the native addon.
118
223
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/cant",
3
- "version": "2026.4.109",
3
+ "version": "2026.4.111",
4
4
  "description": "CANT protocol parser and runtime for CLEO — wraps cant-core via napi-rs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,9 +9,9 @@
9
9
  "napi/"
10
10
  ],
11
11
  "dependencies": {
12
- "@cleocode/contracts": "2026.4.109",
13
- "@cleocode/lafs": "2026.4.109",
14
- "@cleocode/core": "2026.4.109"
12
+ "@cleocode/contracts": "2026.4.111",
13
+ "@cleocode/core": "2026.4.111",
14
+ "@cleocode/lafs": "2026.4.111"
15
15
  },
16
16
  "devDependencies": {
17
17
  "typescript": "^6.0.2",