@dot-agent/compiler 0.10.1 → 0.12.0-alpha.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 +202 -0
- package/README.md +1 -1
- package/dist/core.cjs +15 -12
- package/dist/core.d.cts +2 -2
- package/dist/core.d.mts +2 -2
- package/dist/core.mjs +2 -2
- package/dist/index.cjs +117 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -25
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +25 -25
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +93 -29
- package/dist/index.mjs.map +1 -1
- package/dist/{zip-core-Dw_OgIjV.mjs → namespace-B8prujsD.mjs} +12 -3
- package/dist/namespace-B8prujsD.mjs.map +1 -0
- package/dist/{zip-core-BjnIQMRA.cjs → namespace-BbxHHnOo.cjs} +30 -3
- package/dist/namespace-BbxHHnOo.cjs.map +1 -0
- package/dist/{zip-core-BCiH0sUt.d.cts → namespace-DsoVSANe.d.cts} +8 -2
- package/dist/namespace-DsoVSANe.d.cts.map +1 -0
- package/dist/{zip-core-BCiH0sUt.d.mts → namespace-DsoVSANe.d.mts} +8 -2
- package/dist/namespace-DsoVSANe.d.mts.map +1 -0
- package/package.json +5 -5
- package/dist/zip-core-BCiH0sUt.d.cts.map +0 -1
- package/dist/zip-core-BCiH0sUt.d.mts.map +0 -1
- package/dist/zip-core-BjnIQMRA.cjs.map +0 -1
- package/dist/zip-core-Dw_OgIjV.mjs.map +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as PackOptions, C as Capability, D as LangId, E as Integrity, F as StateDef, I as Statement, L as TriggerDecl, M as ParseDiagnostic, N as PropertyDecl, O as LintMessage, P as PropertyType, R as TypeDefinition, S as BuildAboutmeOptions, T as IdParts, _ as AgentBundle, a as createZip, b as AnnotatedRef, d as extractName, f as parseId, g as AboutMe, h as parseAboutme, i as isInContentNamespace, j as PackResult, k as OntologyRef, l as buildId, m as buildAboutme, n as ContentNamespace, o as extractFiles, p as aboutmeToJson, r as classifyContentPath, t as CONTENT_NAMESPACES, u as extractDigest, v as AgentDecl, w as DescriptionFile, x as BehaviorFile, y as AgentFiles } from "./namespace-DsoVSANe.mjs";
|
|
2
2
|
import { Node, Tree } from "web-tree-sitter";
|
|
3
3
|
import JSZip from "jszip";
|
|
4
4
|
//#region src/parser.d.ts
|
|
5
|
-
declare function initBehaviorParser(): Promise<void>;
|
|
5
|
+
export declare function initBehaviorParser(): Promise<void>;
|
|
6
6
|
interface ParseResult<T> {
|
|
7
7
|
ok: T | null;
|
|
8
8
|
diagnostics: ParseDiagnostic[];
|
|
9
9
|
}
|
|
10
|
-
declare function parseBehaviorFile(text: string): ParseResult<BehaviorFile>;
|
|
11
|
-
declare function parseDescriptionFile(text: string): ParseResult<DescriptionFile>;
|
|
12
|
-
declare function getBehaviorScxml(text: string): string;
|
|
13
|
-
declare function initParsers(): Promise<void>;
|
|
10
|
+
export declare function parseBehaviorFile(text: string): ParseResult<BehaviorFile>;
|
|
11
|
+
export declare function parseDescriptionFile(text: string): ParseResult<DescriptionFile>;
|
|
12
|
+
export declare function getBehaviorScxml(text: string): string;
|
|
13
|
+
export declare function initParsers(): Promise<void>;
|
|
14
14
|
/**
|
|
15
15
|
* Parse source text and return a tree-sitter Tree.
|
|
16
16
|
*
|
|
@@ -18,12 +18,12 @@ declare function initParsers(): Promise<void>;
|
|
|
18
18
|
* @param text - source text to parse
|
|
19
19
|
* @param previousTree - optional previous tree for incremental parsing (LSP use)
|
|
20
20
|
*/
|
|
21
|
-
declare function parse(langId: LangId, text: string, previousTree?: Tree): Promise<Tree>;
|
|
21
|
+
export declare function parse(langId: LangId, text: string, previousTree?: Tree): Promise<Tree>;
|
|
22
22
|
/** Parse without initializing if parsers are already ready. Returns null if not initialized. */
|
|
23
|
-
declare function parseSync(langId: LangId, text: string, previousTree?: Tree): Tree | null;
|
|
24
|
-
declare function nodesOfType(tree: Tree, type: string): Node[];
|
|
25
|
-
declare function nodeAtOffset(tree: Tree, offset: number): Node | null;
|
|
26
|
-
declare function nodeToRange(node: Node): {
|
|
23
|
+
export declare function parseSync(langId: LangId, text: string, previousTree?: Tree): Tree | null;
|
|
24
|
+
export declare function nodesOfType(tree: Tree, type: string): Node[];
|
|
25
|
+
export declare function nodeAtOffset(tree: Tree, offset: number): Node | null;
|
|
26
|
+
export declare function nodeToRange(node: Node): {
|
|
27
27
|
start: {
|
|
28
28
|
line: number;
|
|
29
29
|
character: number;
|
|
@@ -33,34 +33,34 @@ declare function nodeToRange(node: Node): {
|
|
|
33
33
|
character: number;
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
|
-
declare function positionToOffset(text: string, line: number, character: number): number;
|
|
37
|
-
declare function getContextNode(tree: Tree, offset: number): Node;
|
|
36
|
+
export declare function positionToOffset(text: string, line: number, character: number): number;
|
|
37
|
+
export declare function getContextNode(tree: Tree, offset: number): Node;
|
|
38
38
|
//#endregion
|
|
39
39
|
//#region src/linter.d.ts
|
|
40
|
-
declare function lintDescription(text: string, file?: string): Promise<LintMessage[]>;
|
|
41
|
-
declare function lintBehavior(text: string, file?: string, docPath?: string, consolidated?: boolean, externalStates?: Set<string>, mergedText?: string): Promise<LintMessage[]>;
|
|
42
|
-
declare function createLinter(): Promise<{
|
|
40
|
+
export declare function lintDescription(text: string, file?: string): Promise<LintMessage[]>;
|
|
41
|
+
export declare function lintBehavior(text: string, file?: string, docPath?: string, consolidated?: boolean, externalStates?: Set<string>, mergedText?: string): Promise<LintMessage[]>;
|
|
42
|
+
export declare function createLinter(): Promise<{
|
|
43
43
|
lintDescription: typeof lintDescription;
|
|
44
44
|
lintBehavior: typeof lintBehavior;
|
|
45
45
|
}>;
|
|
46
46
|
//#endregion
|
|
47
47
|
//#region src/zip.d.ts
|
|
48
|
-
declare function readZip(filePath: string): Promise<JSZip>;
|
|
49
|
-
declare function validateZipBomb(filePath: string): Promise<boolean>;
|
|
50
|
-
declare function validateMagicBytes(filePath: string): Promise<boolean>;
|
|
51
|
-
declare function writeZip(zip: JSZip, outPath: string): Promise<void>;
|
|
48
|
+
export declare function readZip(filePath: string): Promise<JSZip>;
|
|
49
|
+
export declare function validateZipBomb(filePath: string): Promise<boolean>;
|
|
50
|
+
export declare function validateMagicBytes(filePath: string): Promise<boolean>;
|
|
51
|
+
export declare function writeZip(zip: JSZip, outPath: string): Promise<void>;
|
|
52
52
|
//#endregion
|
|
53
53
|
//#region src/pack.d.ts
|
|
54
54
|
interface ConsolidateResult {
|
|
55
55
|
mergedText: string;
|
|
56
56
|
mergeSources: string[];
|
|
57
57
|
}
|
|
58
|
-
declare function consolidate(agentRoot: string, entryFile: string): Promise<ConsolidateResult>;
|
|
59
|
-
declare function collectFiles(dir: string, descriptionFile: string, mergedBehaviorText: string, mergeSources: string[], personaFile?: string): Promise<Map<string, string>>;
|
|
60
|
-
declare function pack(options?: PackOptions): Promise<PackResult>;
|
|
58
|
+
export declare function consolidate(agentRoot: string, entryFile: string): Promise<ConsolidateResult>;
|
|
59
|
+
export declare function collectFiles(dir: string, descriptionFile: string, mergedBehaviorText: string, mergeSources: string[], personaFile?: string): Promise<Map<string, string>>;
|
|
60
|
+
export declare function pack(options?: PackOptions): Promise<PackResult>;
|
|
61
61
|
//#endregion
|
|
62
62
|
//#region src/bundle.d.ts
|
|
63
|
-
declare function bundleFromDir(dir: string): Promise<AgentBundle>;
|
|
63
|
+
export declare function bundleFromDir(dir: string): Promise<AgentBundle>;
|
|
64
64
|
//#endregion
|
|
65
|
-
export { type AboutMe, type AgentBundle, type AgentDecl, type AgentFiles, type AnnotatedRef, type BehaviorFile, type BuildAboutmeOptions, type Capability, type DescriptionFile, type IdParts, type Integrity, type LangId, type LintMessage, type OntologyRef, type PackOptions, type PackResult, type PropertyDecl, type PropertyType, type StateDef, type Statement, type TriggerDecl, type TypeDefinition, aboutmeToJson, buildAboutme, buildId,
|
|
65
|
+
export { type AboutMe, type AgentBundle, type AgentDecl, type AgentFiles, type AnnotatedRef, type BehaviorFile, type BuildAboutmeOptions, CONTENT_NAMESPACES, type Capability, type ContentNamespace, type DescriptionFile, type IdParts, type Integrity, type LangId, type LintMessage, type OntologyRef, type PackOptions, type PackResult, type PropertyDecl, type PropertyType, type StateDef, type Statement, type TriggerDecl, type TypeDefinition, aboutmeToJson, buildAboutme, buildId, classifyContentPath, createZip, extractDigest, extractFiles, extractName, isInContentNamespace, parseAboutme, parseId };
|
|
66
66
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/parser.ts","../src/linter.ts","../src/zip.ts","../src/pack.ts","../src/bundle.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/parser.ts","../src/linter.ts","../src/zip.ts","../src/pack.ts","../src/bundle.ts"],"mappings":";;;;wBAmBsB,sBAAsB;UAM3B,YAAY;EAC3B,IAAI;EACJ,aAAa;;wBAGC,kBAAkB,eAAe,YAAY;wBAI7C,qBAAqB,eAAe,YAAY;wBAIhD,iBAAiB;wBAIX,eAAe;;;;;;;;wBAmBf,MACpB,QAAQ,QACR,cACA,eAAe,OACd,QAAQ;;wBAOK,UAAU,QAAQ,QAAQ,cAAc,eAAe,OAAO;wBAQ9D,YAAY,MAAM,MAAM,eAAe;wBAKvC,aAAa,MAAM,MAAM,iBAAiB;wBAK1C,YAAY,MAAM;EAChC;IAAS;IAAc;;EACvB;IAAO;IAAc;;;wBAQP,iBAAiB,cAAc,cAAc;wBAS7C,eAAe,MAAM,MAAM,iBAAiB;;;wBCxCtC,gBAAgB,cAAc,gBAA6B,QAAQ;wBAqKnE,aACpB,cACA,eACA,kBACA,wBACA,iBAAiB,aACjB,sBACC,QAAQ;wBAuXW,gBAAY;;;;;;wBC9lBZ,QAAQ,mBAAmB,QAAQ;wBAKnC,gBAAgB,mBAAmB;wBAOnC,mBAAmB,mBAAmB;wBAMtC,SAAS,KAAK,OAAO,kBAAkB;;;UCmInD;EACR;EACA;;wBAGoB,YAAY,mBAAmB,oBAAoB,QAAQ;wBAqN3D,aACpB,aACA,yBACA,4BACA,wBACA,uBACC,QAAQ;wBAkFW,KAAK,UAAS,cAAmB,QAAQ;;;wBCnczC,cAAc,cAAc,QAAQ"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { _ as COMPILER_VERSION, a as extractFiles, c as buildId, d as isValidVersion, f as parseId, g as parseAboutme, h as buildAboutme, i as createZip, l as extractDigest, m as aboutmeToJson, n as classifyContentPath, o as validateMagicBytes$1, p as slugify, r as isInContentNamespace, s as validateZipBomb$1, t as CONTENT_NAMESPACES, u as extractName } from "./namespace-B8prujsD.mjs";
|
|
2
2
|
import { createRequire } from "module";
|
|
3
3
|
import { Language, Parser } from "web-tree-sitter";
|
|
4
4
|
import { get_graph, init, parse_behavior, parse_description } from "@dot-agent/parser-dsl";
|
|
@@ -257,7 +257,8 @@ function collectMergedStates(tree, docDir, states, visited = /* @__PURE__ */ new
|
|
|
257
257
|
for (const mergeNode of nodesOfType(tree, "merge_decl")) {
|
|
258
258
|
const pathNode = mergeNode.childForFieldName("path");
|
|
259
259
|
if (!pathNode) continue;
|
|
260
|
-
const
|
|
260
|
+
const filename = pathNode.text.replace(/^"|"$/g, "");
|
|
261
|
+
const absPath = resolve(docDir, filename);
|
|
261
262
|
if (visited.has(absPath)) continue;
|
|
262
263
|
visited.add(absPath);
|
|
263
264
|
let mergedText;
|
|
@@ -287,6 +288,8 @@ async function lintBehavior(text, file = "agent.behavior", docPath, consolidated
|
|
|
287
288
|
const stateName = nameNode?.text ?? "?";
|
|
288
289
|
const hasInteract = stateNode.descendantsOfType("interact_stmt").length > 0;
|
|
289
290
|
const hasGoal = stateNode.descendantsOfType("goal_stmt").length > 0;
|
|
291
|
+
const hasGuide = stateNode.descendantsOfType("guide_stmt").length > 0;
|
|
292
|
+
const hasTeach = stateNode.descendantsOfType("teach_stmt").length > 0;
|
|
290
293
|
const intentHandlers = stateNode.descendantsOfType("intent_handler");
|
|
291
294
|
if (hasInteract && !hasGoal) {
|
|
292
295
|
const { line, col } = nodePosition(nameNode ?? stateNode);
|
|
@@ -299,17 +302,54 @@ async function lintBehavior(text, file = "agent.behavior", docPath, consolidated
|
|
|
299
302
|
message: `'interact' without 'goal'. Add 'goal "..."' before 'interact'.`
|
|
300
303
|
});
|
|
301
304
|
}
|
|
302
|
-
|
|
305
|
+
const presentOrientationNames = [
|
|
306
|
+
hasGoal && "goal",
|
|
307
|
+
hasGuide && "guide",
|
|
308
|
+
hasTeach && "teach"
|
|
309
|
+
].filter((n) => n !== false);
|
|
310
|
+
if (presentOrientationNames.length > 0 && !hasInteract) {
|
|
303
311
|
const { line, col } = nodePosition(nameNode ?? stateNode);
|
|
312
|
+
const list = presentOrientationNames.map((n) => `'${n}'`).join(", ");
|
|
313
|
+
const isPlural = presentOrientationNames.length > 1;
|
|
304
314
|
messages.push({
|
|
305
315
|
file,
|
|
306
316
|
line,
|
|
307
317
|
col,
|
|
308
318
|
severity: "warning",
|
|
309
319
|
code: "W012",
|
|
310
|
-
message:
|
|
320
|
+
message: `${list} ${isPlural ? "are" : "is"} only valid in an oriented state. Add 'interact' or remove ${isPlural ? "them" : "it"}.`
|
|
311
321
|
});
|
|
312
322
|
}
|
|
323
|
+
const bodyStmts = (stateNode.childForFieldName("body")?.children ?? []).filter((n) => n !== null);
|
|
324
|
+
const firstTransitionIndex = bodyStmts.findIndex((n) => n.type === "transition_stmt");
|
|
325
|
+
const interactsBeforeFirstTransition = bodyStmts.filter((n, i) => n.type === "interact_stmt" && (firstTransitionIndex === -1 || i < firstTransitionIndex));
|
|
326
|
+
if (interactsBeforeFirstTransition.length > 1) for (const dup of interactsBeforeFirstTransition.slice(1)) {
|
|
327
|
+
const { line, col } = nodePosition(dup);
|
|
328
|
+
messages.push({
|
|
329
|
+
file,
|
|
330
|
+
line,
|
|
331
|
+
col,
|
|
332
|
+
severity: "warning",
|
|
333
|
+
code: "W017",
|
|
334
|
+
message: `Duplicate 'interact' in state '${stateName}' before any transition. Only one 'interact' is allowed per state before a 'transition to' — a second one, still reachable in the same entry batch, emits a second 'request_interact' effect with no dedupe at the host layer.`
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
const leavingIndex = bodyStmts.findIndex((n) => n.type === "transition_stmt" && n.childForFieldName("state")?.text !== stateName);
|
|
338
|
+
if (leavingIndex !== -1) {
|
|
339
|
+
const target = bodyStmts[leavingIndex].childForFieldName("state")?.text ?? "?";
|
|
340
|
+
for (const stmt of bodyStmts.slice(leavingIndex + 1)) {
|
|
341
|
+
if (stmt.type === "intent_handler" || stmt.type === "offtopic_handler" || stmt.type === "comment") continue;
|
|
342
|
+
const { line, col } = nodePosition(stmt);
|
|
343
|
+
messages.push({
|
|
344
|
+
file,
|
|
345
|
+
line,
|
|
346
|
+
col,
|
|
347
|
+
severity: "warning",
|
|
348
|
+
code: "W018",
|
|
349
|
+
message: `Unreachable: state '${stateName}' leaves for '${target}' on entry before this statement runs. Everything after a state-level 'transition to' is skipped, like code after a return — move it before the transition or remove it.`
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
}
|
|
313
353
|
if (hasInteract && intentHandlers.length === 0) {
|
|
314
354
|
const { line, col } = nodePosition(nameNode ?? stateNode);
|
|
315
355
|
messages.push({
|
|
@@ -585,11 +625,13 @@ async function readZip(filePath) {
|
|
|
585
625
|
}
|
|
586
626
|
async function validateZipBomb(filePath) {
|
|
587
627
|
const data = await readFile(filePath);
|
|
588
|
-
|
|
628
|
+
const zip = await JSZip.loadAsync(data);
|
|
629
|
+
validateZipBomb$1(zip, data.length);
|
|
589
630
|
return true;
|
|
590
631
|
}
|
|
591
632
|
async function validateMagicBytes(filePath) {
|
|
592
|
-
|
|
633
|
+
const data = await readFile(filePath);
|
|
634
|
+
validateMagicBytes$1(data);
|
|
593
635
|
return true;
|
|
594
636
|
}
|
|
595
637
|
async function writeZip(zip, outPath) {
|
|
@@ -731,7 +773,8 @@ async function resolveVersionInteractive(explicit) {
|
|
|
731
773
|
function isExternalPath(agentRoot, declaredPath) {
|
|
732
774
|
if (isAbsolute(declaredPath)) return true;
|
|
733
775
|
const normRoot = normalize(resolve(agentRoot));
|
|
734
|
-
|
|
776
|
+
const resolved = resolve(normRoot, declaredPath);
|
|
777
|
+
return relative(normRoot, resolved).startsWith("..");
|
|
735
778
|
}
|
|
736
779
|
async function discoverDescriptionFile(dir, explicit) {
|
|
737
780
|
if (explicit) try {
|
|
@@ -813,11 +856,10 @@ function collectFileRefs(stmts, out) {
|
|
|
813
856
|
case "conditional_stmt":
|
|
814
857
|
collectFileRefs(s.then, out);
|
|
815
858
|
if (s.else) collectFileRefs(s.else, out);
|
|
816
|
-
break;
|
|
817
859
|
}
|
|
818
860
|
}
|
|
819
|
-
function
|
|
820
|
-
return
|
|
861
|
+
function normalizeRefPath(text) {
|
|
862
|
+
return text.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
821
863
|
}
|
|
822
864
|
async function collectBehaviorFileRefs(mergedBehaviorText) {
|
|
823
865
|
await initBehaviorParser();
|
|
@@ -851,15 +893,33 @@ async function listContentFiles(dir, ns) {
|
|
|
851
893
|
async function findOrphanContentFiles(dir, mergedBehaviorText) {
|
|
852
894
|
const refs = await collectBehaviorFileRefs(mergedBehaviorText);
|
|
853
895
|
const referenced = /* @__PURE__ */ new Set();
|
|
854
|
-
|
|
855
|
-
|
|
896
|
+
const messages = [];
|
|
897
|
+
for (const { kind, text } of refs.values()) {
|
|
898
|
+
const bundlePath = normalizeRefPath(text);
|
|
899
|
+
referenced.add(bundlePath);
|
|
900
|
+
if (isExternalPath(dir, bundlePath) || isInContentNamespace(bundlePath)) continue;
|
|
901
|
+
try {
|
|
902
|
+
await stat(join(dir, bundlePath));
|
|
903
|
+
} catch {
|
|
904
|
+
continue;
|
|
905
|
+
}
|
|
906
|
+
messages.push({
|
|
907
|
+
file: bundlePath,
|
|
908
|
+
line: 1,
|
|
909
|
+
col: 1,
|
|
910
|
+
severity: "error",
|
|
911
|
+
code: "E022",
|
|
912
|
+
message: `'${kind}' reference '${text}' resolves to '${bundlePath}', which is outside guides/ and knowledge/ — those are the only two directories the runtime can serve content from; move '${bundlePath}' under guides/ or knowledge/ and update the '${kind}' statement to reference it there`
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
return [...[...await listContentFiles(dir, "guides"), ...await listContentFiles(dir, "knowledge")].filter((path) => !referenced.has(path)).map((path) => ({
|
|
856
916
|
file: path,
|
|
857
917
|
line: 1,
|
|
858
918
|
col: 1,
|
|
859
919
|
severity: "warning",
|
|
860
920
|
code: "W015",
|
|
861
921
|
message: `'${path}' is not referenced by any guide or teach statement — it will not be included in the bundle`
|
|
862
|
-
}));
|
|
922
|
+
})), ...messages];
|
|
863
923
|
}
|
|
864
924
|
async function collectFiles(dir, descriptionFile, mergedBehaviorText, mergeSources, personaFile) {
|
|
865
925
|
const files = /* @__PURE__ */ new Map();
|
|
@@ -879,16 +939,16 @@ async function collectFiles(dir, descriptionFile, mergedBehaviorText, mergeSourc
|
|
|
879
939
|
}
|
|
880
940
|
const refs = await collectBehaviorFileRefs(mergedBehaviorText);
|
|
881
941
|
for (const { kind, text } of refs.values()) {
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
const nsPath = `${ns}/${text}`;
|
|
942
|
+
const bundlePath = normalizeRefPath(text);
|
|
943
|
+
if (isExternalPath(dir, bundlePath)) throw new Error(`E014: '${kind}' path '${text}' is absolute or escapes the agent root`);
|
|
885
944
|
let content;
|
|
886
|
-
|
|
887
|
-
content = await readFile(
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
files.
|
|
945
|
+
try {
|
|
946
|
+
content = await readFile(join(dir, bundlePath), "utf-8");
|
|
947
|
+
} catch {
|
|
948
|
+
throw new Error(`E018: '${kind}' file '${text}' referenced in agent.behavior not found in ${dir} — looked for '${bundlePath}' relative to the agent root`);
|
|
949
|
+
}
|
|
950
|
+
if (files.has(bundlePath)) throw new Error(`E020: '${kind}' reference '${text}' resolves to '${bundlePath}', which collides with a reserved bundle path (the description file, agent.behavior, a merged behaviors/ file, or the persona) — reference a different path`);
|
|
951
|
+
files.set(bundlePath, content);
|
|
892
952
|
}
|
|
893
953
|
return files;
|
|
894
954
|
}
|
|
@@ -921,11 +981,15 @@ async function pack(options = {}) {
|
|
|
921
981
|
const version = await resolveVersionInteractive(options.version);
|
|
922
982
|
const commit = await resolveCommit(options.commit);
|
|
923
983
|
const allFiles = await collectFiles(dir, descriptionFileName, mergedText, mergeSources, df.persona ?? void 0);
|
|
924
|
-
const
|
|
984
|
+
const contentMessages = await findOrphanContentFiles(dir, mergedText);
|
|
985
|
+
const contentErrors = contentMessages.filter((m) => m.severity === "error");
|
|
986
|
+
if (contentErrors.length > 0) throw new Error(`Lint failed:\n${contentErrors.map((e) => ` ${e.file}:${e.line}:${e.col} ${e.code} ${e.message}`).join("\n")}`);
|
|
987
|
+
const warnings = [...lintWarnings, ...contentMessages.filter((m) => m.severity === "warning")];
|
|
925
988
|
const contentForHash = Array.from(allFiles.values()).join("");
|
|
926
989
|
const sha256 = createHash("sha256").update(contentForHash).digest("hex");
|
|
990
|
+
const namespace = df.agent.domain ?? "unknown";
|
|
927
991
|
const id = buildId({
|
|
928
|
-
namespace
|
|
992
|
+
namespace,
|
|
929
993
|
name: slugify(df.agent.name),
|
|
930
994
|
version,
|
|
931
995
|
digest: version ? commit : void 0
|
|
@@ -963,8 +1027,8 @@ async function pack(options = {}) {
|
|
|
963
1027
|
behavior: "agent.behavior",
|
|
964
1028
|
...df.persona ? { persona: df.persona } : {},
|
|
965
1029
|
behaviors: Array.from(allFiles.keys()).filter((f) => f.startsWith("behaviors/")),
|
|
966
|
-
guides: Array.from(allFiles.keys()).filter((f) => f
|
|
967
|
-
knowledge: Array.from(allFiles.keys()).filter((f) => f
|
|
1030
|
+
guides: Array.from(allFiles.keys()).filter((f) => classifyContentPath(f) === "guides"),
|
|
1031
|
+
knowledge: Array.from(allFiles.keys()).filter((f) => classifyContentPath(f) === "knowledge")
|
|
968
1032
|
};
|
|
969
1033
|
agentFolder.file("files.json", JSON.stringify(filesJson, null, 2));
|
|
970
1034
|
for (const [path, content] of allFiles) zip.file(path, content);
|
|
@@ -1036,11 +1100,11 @@ async function bundleFromDir(dir) {
|
|
|
1036
1100
|
description: descriptionText,
|
|
1037
1101
|
behavior: allFiles.get("agent.behavior") ?? mergedText,
|
|
1038
1102
|
persona: df.persona ? allFiles.get(df.persona) : void 0,
|
|
1039
|
-
guides: Array.from(allFiles.entries()).filter(([p]) => p
|
|
1103
|
+
guides: Array.from(allFiles.entries()).filter(([p]) => classifyContentPath(p) === "guides").map(([path, content]) => ({
|
|
1040
1104
|
path,
|
|
1041
1105
|
content
|
|
1042
1106
|
})),
|
|
1043
|
-
knowledge: Array.from(allFiles.entries()).filter(([p]) => p
|
|
1107
|
+
knowledge: Array.from(allFiles.entries()).filter(([p]) => classifyContentPath(p) === "knowledge").map(([path, content]) => ({
|
|
1044
1108
|
path,
|
|
1045
1109
|
content
|
|
1046
1110
|
})),
|
|
@@ -1052,6 +1116,6 @@ async function bundleFromDir(dir) {
|
|
|
1052
1116
|
};
|
|
1053
1117
|
}
|
|
1054
1118
|
//#endregion
|
|
1055
|
-
export { aboutmeToJson, buildAboutme, buildId, bundleFromDir, collectFiles, consolidate, createLinter, createZip, extractDigest, extractFiles, extractName, getBehaviorScxml, getContextNode, initBehaviorParser, initParsers, lintBehavior, lintDescription, nodeAtOffset, nodeToRange, nodesOfType, pack, parse, parseAboutme, parseBehaviorFile, parseDescriptionFile, parseId, parseSync, positionToOffset, readZip, validateMagicBytes, validateZipBomb, writeZip };
|
|
1119
|
+
export { CONTENT_NAMESPACES, aboutmeToJson, buildAboutme, buildId, bundleFromDir, classifyContentPath, collectFiles, consolidate, createLinter, createZip, extractDigest, extractFiles, extractName, getBehaviorScxml, getContextNode, initBehaviorParser, initParsers, isInContentNamespace, lintBehavior, lintDescription, nodeAtOffset, nodeToRange, nodesOfType, pack, parse, parseAboutme, parseBehaviorFile, parseDescriptionFile, parseId, parseSync, positionToOffset, readZip, validateMagicBytes, validateZipBomb, writeZip };
|
|
1056
1120
|
|
|
1057
1121
|
//# sourceMappingURL=index.mjs.map
|