@jsleekr/graft 5.7.0
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/README.md +235 -0
- package/dist/analyzer/estimator.d.ts +33 -0
- package/dist/analyzer/estimator.js +273 -0
- package/dist/analyzer/graph-checker.d.ts +13 -0
- package/dist/analyzer/graph-checker.js +153 -0
- package/dist/analyzer/scope.d.ts +21 -0
- package/dist/analyzer/scope.js +324 -0
- package/dist/analyzer/types.d.ts +17 -0
- package/dist/analyzer/types.js +323 -0
- package/dist/codegen/agents.d.ts +2 -0
- package/dist/codegen/agents.js +109 -0
- package/dist/codegen/backend.d.ts +16 -0
- package/dist/codegen/backend.js +1 -0
- package/dist/codegen/claude-backend.d.ts +9 -0
- package/dist/codegen/claude-backend.js +47 -0
- package/dist/codegen/codegen.d.ts +10 -0
- package/dist/codegen/codegen.js +57 -0
- package/dist/codegen/hooks.d.ts +2 -0
- package/dist/codegen/hooks.js +165 -0
- package/dist/codegen/orchestration.d.ts +3 -0
- package/dist/codegen/orchestration.js +250 -0
- package/dist/codegen/settings.d.ts +36 -0
- package/dist/codegen/settings.js +87 -0
- package/dist/compiler.d.ts +21 -0
- package/dist/compiler.js +101 -0
- package/dist/constants.d.ts +9 -0
- package/dist/constants.js +13 -0
- package/dist/errors/diagnostics.d.ts +21 -0
- package/dist/errors/diagnostics.js +25 -0
- package/dist/format.d.ts +12 -0
- package/dist/format.js +46 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +181 -0
- package/dist/lexer/lexer.d.ts +23 -0
- package/dist/lexer/lexer.js +268 -0
- package/dist/lexer/tokens.d.ts +96 -0
- package/dist/lexer/tokens.js +150 -0
- package/dist/lsp/features/code-actions.d.ts +7 -0
- package/dist/lsp/features/code-actions.js +58 -0
- package/dist/lsp/features/completions.d.ts +7 -0
- package/dist/lsp/features/completions.js +271 -0
- package/dist/lsp/features/definition.d.ts +3 -0
- package/dist/lsp/features/definition.js +32 -0
- package/dist/lsp/features/diagnostics.d.ts +4 -0
- package/dist/lsp/features/diagnostics.js +33 -0
- package/dist/lsp/features/hover.d.ts +7 -0
- package/dist/lsp/features/hover.js +88 -0
- package/dist/lsp/features/index.d.ts +9 -0
- package/dist/lsp/features/index.js +9 -0
- package/dist/lsp/features/references.d.ts +7 -0
- package/dist/lsp/features/references.js +53 -0
- package/dist/lsp/features/rename.d.ts +17 -0
- package/dist/lsp/features/rename.js +198 -0
- package/dist/lsp/features/symbols.d.ts +7 -0
- package/dist/lsp/features/symbols.js +74 -0
- package/dist/lsp/features/utils.d.ts +3 -0
- package/dist/lsp/features/utils.js +65 -0
- package/dist/lsp/features.d.ts +20 -0
- package/dist/lsp/features.js +513 -0
- package/dist/lsp/server.d.ts +2 -0
- package/dist/lsp/server.js +327 -0
- package/dist/parser/ast.d.ts +244 -0
- package/dist/parser/ast.js +10 -0
- package/dist/parser/parser.d.ts +95 -0
- package/dist/parser/parser.js +1175 -0
- package/dist/program-index.d.ts +21 -0
- package/dist/program-index.js +74 -0
- package/dist/resolver/resolver.d.ts +9 -0
- package/dist/resolver/resolver.js +136 -0
- package/dist/runner.d.ts +13 -0
- package/dist/runner.js +41 -0
- package/dist/runtime/executor.d.ts +56 -0
- package/dist/runtime/executor.js +285 -0
- package/dist/runtime/expr-eval.d.ts +3 -0
- package/dist/runtime/expr-eval.js +138 -0
- package/dist/runtime/flow-runner.d.ts +21 -0
- package/dist/runtime/flow-runner.js +230 -0
- package/dist/runtime/memory.d.ts +5 -0
- package/dist/runtime/memory.js +41 -0
- package/dist/runtime/prompt-builder.d.ts +12 -0
- package/dist/runtime/prompt-builder.js +66 -0
- package/dist/runtime/subprocess.d.ts +20 -0
- package/dist/runtime/subprocess.js +99 -0
- package/dist/runtime/token-tracker.d.ts +36 -0
- package/dist/runtime/token-tracker.js +56 -0
- package/dist/runtime/transforms.d.ts +2 -0
- package/dist/runtime/transforms.js +104 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +35 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +11 -0
- package/package.json +70 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import { BUDGET_WARNING_THRESHOLD, BUDGET_CRITICAL_THRESHOLD } from '../constants.js';
|
|
3
|
+
export class TokenTracker {
|
|
4
|
+
budget;
|
|
5
|
+
consumed = 0;
|
|
6
|
+
entries = [];
|
|
7
|
+
logPath;
|
|
8
|
+
constructor(budget, logPath = null) {
|
|
9
|
+
this.budget = budget;
|
|
10
|
+
this.logPath = logPath;
|
|
11
|
+
}
|
|
12
|
+
record(nodeName, usage, estimated) {
|
|
13
|
+
const actual = usage ? usage.inputTokens + usage.outputTokens : undefined;
|
|
14
|
+
const est = estimated.in + estimated.out;
|
|
15
|
+
this.consumed += actual ?? est;
|
|
16
|
+
const timestamp = new Date().toISOString();
|
|
17
|
+
const entry = { nodeName, estimated: est, actual, cumulative: this.consumed, timestamp };
|
|
18
|
+
this.entries.push(entry);
|
|
19
|
+
if (this.logPath) {
|
|
20
|
+
const actualStr = actual !== undefined ? String(actual) : 'N/A';
|
|
21
|
+
const pct = this.budget > 0 ? Math.round((this.consumed / this.budget) * 100) : 0;
|
|
22
|
+
const line = `[${timestamp}] Node ${nodeName} | estimated: ${est} | actual: ${actualStr} | cumulative: ${this.consumed}/${this.budget} (${pct}%)\n`;
|
|
23
|
+
try {
|
|
24
|
+
fs.appendFileSync(this.logPath, line);
|
|
25
|
+
}
|
|
26
|
+
catch { /* silent */ }
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
get fraction() {
|
|
30
|
+
return this.budget > 0 ? this.consumed / this.budget : 0;
|
|
31
|
+
}
|
|
32
|
+
get isWarning() {
|
|
33
|
+
return this.fraction >= BUDGET_WARNING_THRESHOLD;
|
|
34
|
+
}
|
|
35
|
+
get isCritical() {
|
|
36
|
+
return this.fraction >= BUDGET_CRITICAL_THRESHOLD;
|
|
37
|
+
}
|
|
38
|
+
get totalConsumed() {
|
|
39
|
+
return this.consumed;
|
|
40
|
+
}
|
|
41
|
+
getEntries() {
|
|
42
|
+
return [...this.entries];
|
|
43
|
+
}
|
|
44
|
+
getSummary() {
|
|
45
|
+
return {
|
|
46
|
+
budget: this.budget,
|
|
47
|
+
consumed: this.consumed,
|
|
48
|
+
fraction: this.fraction,
|
|
49
|
+
perNode: this.entries.map(e => ({
|
|
50
|
+
node: e.nodeName,
|
|
51
|
+
actual: e.actual,
|
|
52
|
+
estimated: e.estimated,
|
|
53
|
+
})),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { evaluateExpr } from './expr-eval.js';
|
|
2
|
+
export function applyTransforms(data, transforms) {
|
|
3
|
+
let result = data;
|
|
4
|
+
for (const t of transforms) {
|
|
5
|
+
result = applyOne(result, t);
|
|
6
|
+
}
|
|
7
|
+
return result;
|
|
8
|
+
}
|
|
9
|
+
function applyOne(data, transform) {
|
|
10
|
+
if (data === null || data === undefined || typeof data !== 'object')
|
|
11
|
+
return data;
|
|
12
|
+
switch (transform.type) {
|
|
13
|
+
case 'select': return applySelect(data, transform.fields);
|
|
14
|
+
case 'filter': return applyFilter(data, transform.field, transform.condition);
|
|
15
|
+
case 'drop': return applyDrop(data, transform.field);
|
|
16
|
+
case 'compact': return applyCompact(data);
|
|
17
|
+
case 'truncate': return applyTruncate(data, transform.tokens);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function applySelect(obj, fields) {
|
|
21
|
+
const result = {};
|
|
22
|
+
for (const f of fields) {
|
|
23
|
+
if (f in obj)
|
|
24
|
+
result[f] = obj[f];
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
function applyFilter(obj, field, condition) {
|
|
29
|
+
const arr = obj[field];
|
|
30
|
+
if (!Array.isArray(arr))
|
|
31
|
+
return obj;
|
|
32
|
+
const filtered = arr.filter(item => {
|
|
33
|
+
if (typeof item !== 'object' || item === null)
|
|
34
|
+
return false;
|
|
35
|
+
const itemMap = new Map(Object.entries(item));
|
|
36
|
+
return !!evaluateExpr(condition, itemMap);
|
|
37
|
+
});
|
|
38
|
+
return { ...obj, [field]: filtered };
|
|
39
|
+
}
|
|
40
|
+
function applyDrop(obj, field) {
|
|
41
|
+
const result = { ...obj };
|
|
42
|
+
delete result[field];
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
function applyCompact(data) {
|
|
46
|
+
if (data === null || data === undefined)
|
|
47
|
+
return undefined;
|
|
48
|
+
if (typeof data !== 'object')
|
|
49
|
+
return data;
|
|
50
|
+
if (Array.isArray(data)) {
|
|
51
|
+
return data.map(item => applyCompact(item)).filter(item => !isEmpty(item));
|
|
52
|
+
}
|
|
53
|
+
const obj = data;
|
|
54
|
+
const result = {};
|
|
55
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
56
|
+
const compacted = applyCompact(val);
|
|
57
|
+
if (!isEmpty(compacted))
|
|
58
|
+
result[key] = compacted;
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
function isEmpty(value) {
|
|
63
|
+
if (value === null || value === undefined)
|
|
64
|
+
return true;
|
|
65
|
+
if (value === '')
|
|
66
|
+
return true;
|
|
67
|
+
if (Array.isArray(value) && value.length === 0)
|
|
68
|
+
return true;
|
|
69
|
+
if (typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0)
|
|
70
|
+
return true;
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
function applyTruncate(data, maxTokens) {
|
|
74
|
+
const maxChars = maxTokens * 4; // ~1 token per 4 chars
|
|
75
|
+
const json = JSON.stringify(data);
|
|
76
|
+
if (json.length <= maxChars)
|
|
77
|
+
return data;
|
|
78
|
+
if (typeof data === 'string' && data.length > maxChars)
|
|
79
|
+
return data.slice(0, maxChars) + '...';
|
|
80
|
+
if (typeof data !== 'object' || data === null)
|
|
81
|
+
return data;
|
|
82
|
+
const ratio = maxChars / json.length;
|
|
83
|
+
return truncateDeep(data, ratio);
|
|
84
|
+
}
|
|
85
|
+
function truncateDeep(data, ratio) {
|
|
86
|
+
if (data === null || data === undefined)
|
|
87
|
+
return data;
|
|
88
|
+
if (typeof data === 'string') {
|
|
89
|
+
const maxLen = Math.max(10, Math.floor(data.length * ratio));
|
|
90
|
+
return data.length > maxLen ? data.slice(0, maxLen) + '...' : data;
|
|
91
|
+
}
|
|
92
|
+
if (Array.isArray(data)) {
|
|
93
|
+
const maxItems = Math.max(1, Math.floor(data.length * ratio));
|
|
94
|
+
return data.slice(0, maxItems).map(item => truncateDeep(item, ratio));
|
|
95
|
+
}
|
|
96
|
+
if (typeof data === 'object') {
|
|
97
|
+
const obj = data;
|
|
98
|
+
const result = {};
|
|
99
|
+
for (const [key, val] of Object.entries(obj))
|
|
100
|
+
result[key] = truncateDeep(val, ratio);
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
return data;
|
|
104
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { Program, ContextDecl, NodeDecl, MemoryDecl, EdgeDecl, GraphDecl } from './parser/ast.js';
|
|
2
|
+
export type { ProgramIndex } from './program-index.js';
|
|
3
|
+
export { GraftError } from './errors/diagnostics.js';
|
|
4
|
+
export type { GraftErrorCode, SourceLocation } from './errors/diagnostics.js';
|
|
5
|
+
export type { CodegenBackend, CodegenContext } from './codegen/backend.js';
|
|
6
|
+
export type { GeneratedFile } from './codegen/codegen.js';
|
|
7
|
+
export type { TokenReport } from './analyzer/estimator.js';
|
|
8
|
+
export type { ProgramResult, CompileResult } from './compiler.js';
|
|
9
|
+
export type { RunResult, RunOptions, NodeResult } from './runtime/executor.js';
|
|
10
|
+
export type { TokenUsage } from './runtime/subprocess.js';
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GraftError } from './errors/diagnostics.js';
|
package/dist/utils.d.ts
ADDED
package/dist/utils.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function fieldsToJsonExample(fields) {
|
|
2
|
+
const obj = {};
|
|
3
|
+
for (const field of fields) {
|
|
4
|
+
obj[field.name] = typeToExample(field.type);
|
|
5
|
+
}
|
|
6
|
+
return obj;
|
|
7
|
+
}
|
|
8
|
+
export function typeToExample(type) {
|
|
9
|
+
switch (type.kind) {
|
|
10
|
+
case 'primitive':
|
|
11
|
+
switch (type.name) {
|
|
12
|
+
case 'String': return '<string>';
|
|
13
|
+
case 'Int': return 0;
|
|
14
|
+
case 'Float': return 0.0;
|
|
15
|
+
case 'Bool': return false;
|
|
16
|
+
default: return '<unknown>';
|
|
17
|
+
}
|
|
18
|
+
case 'primitive_range':
|
|
19
|
+
return type.min;
|
|
20
|
+
case 'list':
|
|
21
|
+
return [typeToExample(type.element)];
|
|
22
|
+
case 'map':
|
|
23
|
+
return {};
|
|
24
|
+
case 'optional':
|
|
25
|
+
return typeToExample(type.inner);
|
|
26
|
+
case 'token_bounded':
|
|
27
|
+
return typeToExample(type.inner);
|
|
28
|
+
case 'enum':
|
|
29
|
+
return type.values.join('|');
|
|
30
|
+
case 'struct':
|
|
31
|
+
return fieldsToJsonExample(type.fields);
|
|
32
|
+
case 'domain':
|
|
33
|
+
return `<${type.name}>`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const VERSION: string;
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
let version;
|
|
3
|
+
try {
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
5
|
+
const pkg = require('../package.json');
|
|
6
|
+
version = pkg.version;
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
version = '0.0.0-unknown';
|
|
10
|
+
}
|
|
11
|
+
export const VERSION = version;
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jsleekr/graft",
|
|
3
|
+
"version": "5.7.0",
|
|
4
|
+
"description": "Graft compiler — compile .gft graph DSL to Claude Code harness structures",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "JSLEEKR",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/JSLEEKR/graft.git"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["graft", "compiler", "dsl", "llm", "claude", "graph"],
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"import": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"./ast": {
|
|
21
|
+
"import": "./dist/parser/ast.js",
|
|
22
|
+
"types": "./dist/parser/ast.d.ts"
|
|
23
|
+
},
|
|
24
|
+
"./compiler": {
|
|
25
|
+
"import": "./dist/compiler.js",
|
|
26
|
+
"types": "./dist/compiler.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./runtime": {
|
|
29
|
+
"import": "./dist/runtime/executor.js",
|
|
30
|
+
"types": "./dist/runtime/executor.d.ts"
|
|
31
|
+
},
|
|
32
|
+
"./types": {
|
|
33
|
+
"import": "./dist/types.js",
|
|
34
|
+
"types": "./dist/types.d.ts"
|
|
35
|
+
},
|
|
36
|
+
"./format": {
|
|
37
|
+
"import": "./dist/format.js",
|
|
38
|
+
"types": "./dist/format.d.ts"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist/",
|
|
43
|
+
"README.md",
|
|
44
|
+
"LICENSE"
|
|
45
|
+
],
|
|
46
|
+
"bin": {
|
|
47
|
+
"graft": "./dist/index.js",
|
|
48
|
+
"graft-lsp": "./dist/lsp/server.js"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsc",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"check": "tsc --noEmit",
|
|
55
|
+
"prepublishOnly": "npm run build && npm test"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=20"
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"commander": "^14.0.0",
|
|
62
|
+
"vscode-languageserver": "^9.0.1",
|
|
63
|
+
"vscode-languageserver-textdocument": "^1.0.12"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@types/node": "^22.0.0",
|
|
67
|
+
"typescript": "^5.8.0",
|
|
68
|
+
"vitest": "^3.1.0"
|
|
69
|
+
}
|
|
70
|
+
}
|