@cleocode/cant 2026.3.76
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/LICENSE +21 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +18 -0
- package/dist/migrate/converter.d.ts +21 -0
- package/dist/migrate/converter.js +390 -0
- package/dist/migrate/diff.d.ts +30 -0
- package/dist/migrate/diff.js +107 -0
- package/dist/migrate/index.d.ts +22 -0
- package/dist/migrate/index.js +28 -0
- package/dist/migrate/markdown-parser.d.ts +79 -0
- package/dist/migrate/markdown-parser.js +307 -0
- package/dist/migrate/serializer.d.ts +81 -0
- package/dist/migrate/serializer.js +155 -0
- package/dist/migrate/types.d.ts +90 -0
- package/dist/migrate/types.js +8 -0
- package/dist/native-loader.d.ts +22 -0
- package/dist/native-loader.js +73 -0
- package/dist/parse.d.ts +36 -0
- package/dist/parse.js +95 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.js +2 -0
- package/dist/wasm-loader.d.ts +31 -0
- package/dist/wasm-loader.js +100 -0
- package/package.json +33 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration types for markdown-to-CANT conversion.
|
|
3
|
+
*
|
|
4
|
+
* Defines the input/output contracts for the `cant migrate` command
|
|
5
|
+
* and the underlying conversion engine.
|
|
6
|
+
*/
|
|
7
|
+
/** Options controlling migration behavior. */
|
|
8
|
+
export interface MigrationOptions {
|
|
9
|
+
/** Write .cant files to disk (false = dry-run preview). */
|
|
10
|
+
write: boolean;
|
|
11
|
+
/** Show detailed conversion log during migration. */
|
|
12
|
+
verbose: boolean;
|
|
13
|
+
/** Where to write .cant files (default: .cleo/agents/). */
|
|
14
|
+
outputDir?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Result of migrating a single markdown file. */
|
|
17
|
+
export interface MigrationResult {
|
|
18
|
+
/** Absolute path to the input markdown file. */
|
|
19
|
+
inputFile: string;
|
|
20
|
+
/** Array of .cant files produced (or that would be produced in dry-run). */
|
|
21
|
+
outputFiles: ConvertedFile[];
|
|
22
|
+
/** Sections that could not be automatically converted. */
|
|
23
|
+
unconverted: UnconvertedSection[];
|
|
24
|
+
/** Human-readable summary string. */
|
|
25
|
+
summary: string;
|
|
26
|
+
}
|
|
27
|
+
/** A single converted .cant output file. */
|
|
28
|
+
export interface ConvertedFile {
|
|
29
|
+
/** Relative path for the output file (e.g. ".cleo/agents/code-reviewer.cant"). */
|
|
30
|
+
path: string;
|
|
31
|
+
/** Document kind: agent, skill, hook, or workflow. */
|
|
32
|
+
kind: string;
|
|
33
|
+
/** The full .cant file content including frontmatter. */
|
|
34
|
+
content: string;
|
|
35
|
+
}
|
|
36
|
+
/** A section of markdown that was not converted. */
|
|
37
|
+
export interface UnconvertedSection {
|
|
38
|
+
/** 1-based line number where the section starts. */
|
|
39
|
+
lineStart: number;
|
|
40
|
+
/** 1-based line number where the section ends. */
|
|
41
|
+
lineEnd: number;
|
|
42
|
+
/** Human-readable reason why conversion was skipped. */
|
|
43
|
+
reason: string;
|
|
44
|
+
/** The raw markdown content of the section. */
|
|
45
|
+
content: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A parsed markdown section identified by heading.
|
|
49
|
+
*
|
|
50
|
+
* Used internally by the markdown parser to structure
|
|
51
|
+
* the input before classification and conversion.
|
|
52
|
+
*/
|
|
53
|
+
export interface MarkdownSection {
|
|
54
|
+
/** The heading text (without the `#` prefix). */
|
|
55
|
+
heading: string;
|
|
56
|
+
/** The heading level (2 for ##, 3 for ###, etc.). */
|
|
57
|
+
level: number;
|
|
58
|
+
/** 1-based line number where the section starts. */
|
|
59
|
+
lineStart: number;
|
|
60
|
+
/** 1-based line number where the section ends (inclusive). */
|
|
61
|
+
lineEnd: number;
|
|
62
|
+
/** Lines of content below the heading (excluding the heading line). */
|
|
63
|
+
bodyLines: string[];
|
|
64
|
+
/** Classified type of this section, determined by heuristic matching. */
|
|
65
|
+
classification: SectionClassification;
|
|
66
|
+
}
|
|
67
|
+
/** Classification of a markdown section for conversion purposes. */
|
|
68
|
+
export type SectionClassification = 'agent' | 'permissions' | 'hook' | 'skill' | 'workflow' | 'unknown';
|
|
69
|
+
/**
|
|
70
|
+
* A key-value property extracted from a markdown bullet list.
|
|
71
|
+
*
|
|
72
|
+
* Matches patterns like `- **Key**: value` or `- Key: value`.
|
|
73
|
+
*/
|
|
74
|
+
export interface ExtractedProperty {
|
|
75
|
+
/** Property key (lowercased, normalized). */
|
|
76
|
+
key: string;
|
|
77
|
+
/** Property value (trimmed). */
|
|
78
|
+
value: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* A permission entry extracted from markdown.
|
|
82
|
+
*
|
|
83
|
+
* Matches patterns like `- Tasks: read, write` or `- Read and write tasks`.
|
|
84
|
+
*/
|
|
85
|
+
export interface ExtractedPermission {
|
|
86
|
+
/** The domain (e.g. "tasks", "session", "memory"). */
|
|
87
|
+
domain: string;
|
|
88
|
+
/** Permission values (e.g. ["read", "write"]). */
|
|
89
|
+
values: string[];
|
|
90
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native addon loader for cant-core via napi-rs
|
|
3
|
+
*
|
|
4
|
+
* Loads the napi-rs native addon synchronously. Falls back gracefully
|
|
5
|
+
* if the native addon is not available (e.g., unsupported platform).
|
|
6
|
+
*
|
|
7
|
+
* Replaces the previous wasm-loader.ts which used async WASM initialization.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Check if the native addon is available
|
|
11
|
+
*/
|
|
12
|
+
export declare function isNativeAvailable(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Parse a CANT message using the native addon
|
|
15
|
+
*/
|
|
16
|
+
export declare function cantParseNative(content: string): unknown;
|
|
17
|
+
/**
|
|
18
|
+
* Classify a directive using the native addon
|
|
19
|
+
*/
|
|
20
|
+
export declare function cantClassifyDirectiveNative(verb: string): string;
|
|
21
|
+
export declare const isWasmAvailable: typeof isNativeAvailable;
|
|
22
|
+
export declare const initWasm: () => Promise<void>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Native addon loader for cant-core via napi-rs
|
|
4
|
+
*
|
|
5
|
+
* Loads the napi-rs native addon synchronously. Falls back gracefully
|
|
6
|
+
* if the native addon is not available (e.g., unsupported platform).
|
|
7
|
+
*
|
|
8
|
+
* Replaces the previous wasm-loader.ts which used async WASM initialization.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.initWasm = exports.isWasmAvailable = void 0;
|
|
12
|
+
exports.isNativeAvailable = isNativeAvailable;
|
|
13
|
+
exports.cantParseNative = cantParseNative;
|
|
14
|
+
exports.cantClassifyDirectiveNative = cantClassifyDirectiveNative;
|
|
15
|
+
let nativeModule = null;
|
|
16
|
+
let loadAttempted = false;
|
|
17
|
+
/**
|
|
18
|
+
* Attempt to load the native addon. Called lazily on first use.
|
|
19
|
+
* Native addons load synchronously via require() — no async init needed.
|
|
20
|
+
*/
|
|
21
|
+
function ensureLoaded() {
|
|
22
|
+
if (loadAttempted)
|
|
23
|
+
return;
|
|
24
|
+
loadAttempted = true;
|
|
25
|
+
try {
|
|
26
|
+
// Try loading the napi-rs native addon
|
|
27
|
+
// The package name will be @cleocode/cant-native once published
|
|
28
|
+
nativeModule = require('@cleocode/cant-native');
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
try {
|
|
32
|
+
// Development fallback: try loading from the crate build output
|
|
33
|
+
nativeModule = require('../../crates/cant-napi');
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Native addon not available — JS fallback will be used
|
|
37
|
+
nativeModule = null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Check if the native addon is available
|
|
43
|
+
*/
|
|
44
|
+
function isNativeAvailable() {
|
|
45
|
+
ensureLoaded();
|
|
46
|
+
return nativeModule !== null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse a CANT message using the native addon
|
|
50
|
+
*/
|
|
51
|
+
function cantParseNative(content) {
|
|
52
|
+
ensureLoaded();
|
|
53
|
+
if (!nativeModule) {
|
|
54
|
+
throw new Error('Native addon not available.');
|
|
55
|
+
}
|
|
56
|
+
return nativeModule.cantParse(content);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Classify a directive using the native addon
|
|
60
|
+
*/
|
|
61
|
+
function cantClassifyDirectiveNative(verb) {
|
|
62
|
+
ensureLoaded();
|
|
63
|
+
if (!nativeModule) {
|
|
64
|
+
throw new Error('Native addon not available.');
|
|
65
|
+
}
|
|
66
|
+
return nativeModule.cantClassifyDirective(verb);
|
|
67
|
+
}
|
|
68
|
+
// Backward compatibility aliases
|
|
69
|
+
exports.isWasmAvailable = isNativeAvailable;
|
|
70
|
+
const initWasm = async () => {
|
|
71
|
+
ensureLoaded();
|
|
72
|
+
};
|
|
73
|
+
exports.initWasm = initWasm;
|
package/dist/parse.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ParsedCANTMessage } from './types';
|
|
2
|
+
export type { ParsedCANTMessage };
|
|
3
|
+
/**
|
|
4
|
+
* Initialize the CANT parser
|
|
5
|
+
*
|
|
6
|
+
* With napi-rs native addons, this is a no-op (native modules load synchronously).
|
|
7
|
+
* Kept for backward compatibility with code that previously called this for WASM init.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { initCantParser, parseCANTMessage } from '@cleocode/cant';
|
|
12
|
+
*
|
|
13
|
+
* await initCantParser(); // no-op, kept for compat
|
|
14
|
+
* const result = parseCANTMessage('/done @all T1234');
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function initCantParser(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Parse a CANT message
|
|
20
|
+
*
|
|
21
|
+
* If the native addon is available, uses the Rust cant-core parser via napi-rs.
|
|
22
|
+
* Falls back to a basic JavaScript implementation if the native addon is not loaded.
|
|
23
|
+
*
|
|
24
|
+
* @param content - The CANT message content to parse
|
|
25
|
+
* @returns ParsedCANTMessage with directive, addresses, task_refs, tags
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const result = parseCANTMessage('/done @all T1234 #shipped');
|
|
30
|
+
* console.log(result.directive); // 'done'
|
|
31
|
+
* console.log(result.addresses); // ['all']
|
|
32
|
+
* console.log(result.task_refs); // ['T1234']
|
|
33
|
+
* console.log(result.tags); // ['shipped']
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseCANTMessage(content: string): ParsedCANTMessage;
|
package/dist/parse.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initCantParser = initCantParser;
|
|
4
|
+
exports.parseCANTMessage = parseCANTMessage;
|
|
5
|
+
const native_loader_1 = require("./native-loader");
|
|
6
|
+
/**
|
|
7
|
+
* Initialize the CANT parser
|
|
8
|
+
*
|
|
9
|
+
* With napi-rs native addons, this is a no-op (native modules load synchronously).
|
|
10
|
+
* Kept for backward compatibility with code that previously called this for WASM init.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { initCantParser, parseCANTMessage } from '@cleocode/cant';
|
|
15
|
+
*
|
|
16
|
+
* await initCantParser(); // no-op, kept for compat
|
|
17
|
+
* const result = parseCANTMessage('/done @all T1234');
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
async function initCantParser() {
|
|
21
|
+
// No-op: napi-rs native addons load synchronously via require().
|
|
22
|
+
// Kept for backward compatibility.
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a CANT message
|
|
26
|
+
*
|
|
27
|
+
* If the native addon is available, uses the Rust cant-core parser via napi-rs.
|
|
28
|
+
* Falls back to a basic JavaScript implementation if the native addon is not loaded.
|
|
29
|
+
*
|
|
30
|
+
* @param content - The CANT message content to parse
|
|
31
|
+
* @returns ParsedCANTMessage with directive, addresses, task_refs, tags
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const result = parseCANTMessage('/done @all T1234 #shipped');
|
|
36
|
+
* console.log(result.directive); // 'done'
|
|
37
|
+
* console.log(result.addresses); // ['all']
|
|
38
|
+
* console.log(result.task_refs); // ['T1234']
|
|
39
|
+
* console.log(result.tags); // ['shipped']
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
function parseCANTMessage(content) {
|
|
43
|
+
// If native addon is available, use it
|
|
44
|
+
if ((0, native_loader_1.isNativeAvailable)()) {
|
|
45
|
+
try {
|
|
46
|
+
const nativeResult = (0, native_loader_1.cantParseNative)(content);
|
|
47
|
+
return {
|
|
48
|
+
directive: nativeResult.directive ?? undefined,
|
|
49
|
+
directive_type: (nativeResult.directiveType?.toLowerCase() ??
|
|
50
|
+
'informational'),
|
|
51
|
+
addresses: nativeResult.addresses ?? [],
|
|
52
|
+
task_refs: nativeResult.taskRefs ?? [],
|
|
53
|
+
tags: nativeResult.tags ?? [],
|
|
54
|
+
header_raw: nativeResult.headerRaw ?? '',
|
|
55
|
+
body: nativeResult.body ?? '',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.warn('Native parsing failed, falling back to JS:', error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Fallback: basic JS implementation (header/body split)
|
|
63
|
+
const lines = content.split('\n');
|
|
64
|
+
const header = lines[0] || '';
|
|
65
|
+
const body = lines.slice(1).join('\n');
|
|
66
|
+
// Basic regex extraction (not as robust as WASM parser)
|
|
67
|
+
const directiveMatch = header.match(/^\/([a-z][a-z0-9-]*)/);
|
|
68
|
+
const addresses = [...header.matchAll(/@([a-zA-Z][a-zA-Z0-9_-]*)/g)].map((m) => m[1]);
|
|
69
|
+
const taskRefs = [...content.matchAll(/T(\d+)/g)].map((m) => `T${m[1]}`);
|
|
70
|
+
const tags = [...content.matchAll(/#([a-zA-Z][a-zA-Z0-9_-]*)/g)].map((m) => m[1]);
|
|
71
|
+
return {
|
|
72
|
+
directive: directiveMatch ? directiveMatch[1] : undefined,
|
|
73
|
+
directive_type: directiveMatch ? classifyDirective(directiveMatch[1]) : 'informational',
|
|
74
|
+
addresses,
|
|
75
|
+
task_refs: taskRefs,
|
|
76
|
+
tags,
|
|
77
|
+
header_raw: header,
|
|
78
|
+
body,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Classify a directive verb into its type
|
|
83
|
+
*
|
|
84
|
+
* @param verb - The directive verb (e.g., 'done', 'action', 'info')
|
|
85
|
+
* @returns 'actionable', 'routing', or 'informational'
|
|
86
|
+
*/
|
|
87
|
+
function classifyDirective(verb) {
|
|
88
|
+
const actionable = ['claim', 'done', 'blocked', 'approve', 'decision', 'checkin'];
|
|
89
|
+
const routing = ['action', 'review', 'proposal'];
|
|
90
|
+
if (actionable.includes(verb))
|
|
91
|
+
return 'actionable';
|
|
92
|
+
if (routing.includes(verb))
|
|
93
|
+
return 'routing';
|
|
94
|
+
return 'informational';
|
|
95
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type DirectiveType = 'actionable' | 'routing' | 'informational';
|
|
2
|
+
export interface ParsedCANTMessage {
|
|
3
|
+
directive?: string;
|
|
4
|
+
directive_type: DirectiveType;
|
|
5
|
+
addresses: string[];
|
|
6
|
+
task_refs: string[];
|
|
7
|
+
tags: string[];
|
|
8
|
+
header_raw: string;
|
|
9
|
+
body: string;
|
|
10
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WASM loader for cant-core
|
|
3
|
+
*
|
|
4
|
+
* Loads the WASM module and provides access to CANT parsing functions
|
|
5
|
+
*/
|
|
6
|
+
/** Shape of the CANT WASM module exports. */
|
|
7
|
+
interface CantWasmModule {
|
|
8
|
+
default(): Promise<void>;
|
|
9
|
+
cant_parse(content: string): unknown;
|
|
10
|
+
cant_classify_directive(verb: string): string;
|
|
11
|
+
}
|
|
12
|
+
declare let wasmModule: CantWasmModule | null;
|
|
13
|
+
/**
|
|
14
|
+
* Initialize the WASM module
|
|
15
|
+
* Must be called before using any WASM functions
|
|
16
|
+
*/
|
|
17
|
+
export declare function initWasm(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Check if WASM is available
|
|
20
|
+
*/
|
|
21
|
+
export declare function isWasmAvailable(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Parse a CANT message using WASM
|
|
24
|
+
*/
|
|
25
|
+
export declare function cantParseWASM(content: string): unknown;
|
|
26
|
+
/**
|
|
27
|
+
* Classify a directive using WASM
|
|
28
|
+
*/
|
|
29
|
+
export declare function cantClassifyDirectiveWASM(verb: string): string;
|
|
30
|
+
export type { CantWasmModule };
|
|
31
|
+
export { wasmModule };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WASM loader for cant-core
|
|
4
|
+
*
|
|
5
|
+
* Loads the WASM module and provides access to CANT parsing functions
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.wasmModule = void 0;
|
|
42
|
+
exports.initWasm = initWasm;
|
|
43
|
+
exports.isWasmAvailable = isWasmAvailable;
|
|
44
|
+
exports.cantParseWASM = cantParseWASM;
|
|
45
|
+
exports.cantClassifyDirectiveWASM = cantClassifyDirectiveWASM;
|
|
46
|
+
// Dynamic import of the WASM module
|
|
47
|
+
let wasmModule = null;
|
|
48
|
+
exports.wasmModule = wasmModule;
|
|
49
|
+
let isInitializing = false;
|
|
50
|
+
let initPromise = null;
|
|
51
|
+
/**
|
|
52
|
+
* Initialize the WASM module
|
|
53
|
+
* Must be called before using any WASM functions
|
|
54
|
+
*/
|
|
55
|
+
async function initWasm() {
|
|
56
|
+
if (wasmModule)
|
|
57
|
+
return;
|
|
58
|
+
if (isInitializing) {
|
|
59
|
+
return initPromise;
|
|
60
|
+
}
|
|
61
|
+
isInitializing = true;
|
|
62
|
+
initPromise = (async () => {
|
|
63
|
+
try {
|
|
64
|
+
// Try to load the WASM module
|
|
65
|
+
const wasm = (await Promise.resolve().then(() => __importStar(require('../wasm/cant_core'))));
|
|
66
|
+
await wasm.default();
|
|
67
|
+
exports.wasmModule = wasmModule = wasm;
|
|
68
|
+
}
|
|
69
|
+
catch (_error) {
|
|
70
|
+
console.warn('WASM module not available, falling back to stub implementation');
|
|
71
|
+
exports.wasmModule = wasmModule = null;
|
|
72
|
+
}
|
|
73
|
+
})();
|
|
74
|
+
await initPromise;
|
|
75
|
+
isInitializing = false;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Check if WASM is available
|
|
79
|
+
*/
|
|
80
|
+
function isWasmAvailable() {
|
|
81
|
+
return wasmModule !== null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Parse a CANT message using WASM
|
|
85
|
+
*/
|
|
86
|
+
function cantParseWASM(content) {
|
|
87
|
+
if (!wasmModule) {
|
|
88
|
+
throw new Error('WASM not initialized. Call initWasm() first.');
|
|
89
|
+
}
|
|
90
|
+
return wasmModule.cant_parse(content);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Classify a directive using WASM
|
|
94
|
+
*/
|
|
95
|
+
function cantClassifyDirectiveWASM(verb) {
|
|
96
|
+
if (!wasmModule) {
|
|
97
|
+
throw new Error('WASM not initialized. Call initWasm() first.');
|
|
98
|
+
}
|
|
99
|
+
return wasmModule.cant_classify_directive(verb);
|
|
100
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cleocode/cant",
|
|
3
|
+
"version": "2026.3.76",
|
|
4
|
+
"description": "CANT protocol parser and interpreter for CLEO - wraps cant-core WASM",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/",
|
|
9
|
+
"wasm/"
|
|
10
|
+
],
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@cleocode/contracts": "2026.4.0",
|
|
13
|
+
"@cleocode/lafs": "2026.4.0"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"typescript": "^5.0.0",
|
|
17
|
+
"vitest": "^1.0.0"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"cleo",
|
|
21
|
+
"cant",
|
|
22
|
+
"agent",
|
|
23
|
+
"parser",
|
|
24
|
+
"wasm"
|
|
25
|
+
],
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc",
|
|
29
|
+
"build:wasm": "cd ../../crates/cant-core && wasm-pack build --target web --features wasm --out-dir ../../packages/cant/wasm",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:watch": "vitest"
|
|
32
|
+
}
|
|
33
|
+
}
|