agency-lang 0.0.4 → 0.0.6

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/README.md CHANGED
@@ -1,6 +1,33 @@
1
1
  # Agency
2
2
  Agent Definition Language
3
3
 
4
+ ## Usage
5
+
6
+ Add agency to a project:
7
+
8
+ ```bash
9
+ pnpm add agency-lang
10
+ ```
11
+
12
+ You can then start using the agency script on your files:
13
+
14
+ ```bash
15
+ # to compile
16
+ agency compile infile.agency outfile.ts
17
+
18
+ # to compile and run
19
+ agency run infile.agency
20
+
21
+ # or simply
22
+ agency infile.agency
23
+ ```
24
+
25
+ Note that the generated files use several other libraries that you will need to install as well:
26
+
27
+ ```bash
28
+ pnpm i nanoid openai egonSchiele/simplemachine statelog-client zod
29
+ ```
30
+
4
31
  ## troubleshooting
5
32
  ### Weird undefined error
6
33
 
@@ -0,0 +1,48 @@
1
+ import { AgencyComment, AgencyProgram, Assignment, Literal, PromptLiteral, TypeAlias, TypeHint } from "../types.js";
2
+ import { AccessExpression, DotFunctionCall, DotProperty, IndexAccess } from "../types/access.js";
3
+ import { AgencyArray, AgencyObject } from "../types/dataStructures.js";
4
+ import { FunctionCall, FunctionDefinition } from "../types/function.js";
5
+ import { GraphNodeDefinition } from "../types/graphNode.js";
6
+ import { ImportStatement } from "../types/importStatement.js";
7
+ import { MatchBlock } from "../types/matchBlock.js";
8
+ import { ReturnStatement } from "../types/returnStatement.js";
9
+ import { UsesTool } from "../types/tools.js";
10
+ import { WhileLoop } from "../types/whileLoop.js";
11
+ import { BaseGenerator } from "./baseGenerator.js";
12
+ export declare class AgencyGenerator extends BaseGenerator {
13
+ private indentLevel;
14
+ private indentSize;
15
+ constructor();
16
+ private indent;
17
+ private increaseIndent;
18
+ private decreaseIndent;
19
+ protected generateBuiltins(): string;
20
+ protected generateImports(): string;
21
+ protected preprocess(): string;
22
+ protected postprocess(): string;
23
+ protected processTypeAlias(node: TypeAlias): string;
24
+ protected processTypeHint(node: TypeHint): string;
25
+ protected processAssignment(node: Assignment): string;
26
+ protected generateLiteral(literal: Literal): string;
27
+ private generatePromptLiteral;
28
+ protected processPromptLiteral(variableName: string, node: PromptLiteral): string;
29
+ protected processFunctionDefinition(node: FunctionDefinition): string;
30
+ protected processFunctionCall(node: FunctionCall): string;
31
+ protected generateFunctionCallExpression(node: FunctionCall): string;
32
+ protected processAgencyArray(node: AgencyArray): string;
33
+ protected processAgencyObject(node: AgencyObject): string;
34
+ protected processAccessExpression(node: AccessExpression): string;
35
+ protected processDotProperty(node: DotProperty): string;
36
+ protected processIndexAccess(node: IndexAccess): string;
37
+ protected processDotFunctionCall(node: DotFunctionCall): string;
38
+ protected processMatchBlock(node: MatchBlock): string;
39
+ protected processWhileLoop(node: WhileLoop): string;
40
+ protected processReturnStatement(node: ReturnStatement): string;
41
+ protected processComment(node: AgencyComment): string;
42
+ protected processImportStatement(node: ImportStatement): string;
43
+ protected processGraphNode(node: GraphNodeDefinition): string;
44
+ protected processTool(node: FunctionDefinition): string;
45
+ protected processUsesTool(node: UsesTool): string;
46
+ private indentStr;
47
+ }
48
+ export declare function generateAgency(program: AgencyProgram): string;
@@ -0,0 +1,228 @@
1
+ import { BaseGenerator } from "./baseGenerator.js";
2
+ import { variableTypeToString } from "./typescriptGenerator/typeToString.js";
3
+ export class AgencyGenerator extends BaseGenerator {
4
+ indentLevel = 0;
5
+ indentSize = 2;
6
+ constructor() {
7
+ super();
8
+ }
9
+ indent() {
10
+ return " ".repeat(this.indentLevel * this.indentSize);
11
+ }
12
+ increaseIndent() {
13
+ this.indentLevel++;
14
+ }
15
+ decreaseIndent() {
16
+ this.indentLevel--;
17
+ }
18
+ // Lifecycle methods
19
+ generateBuiltins() {
20
+ return "";
21
+ }
22
+ generateImports() {
23
+ return "";
24
+ }
25
+ preprocess() {
26
+ return "";
27
+ }
28
+ postprocess() {
29
+ return "";
30
+ }
31
+ // Type system methods
32
+ processTypeAlias(node) {
33
+ this.typeAliases[node.aliasName] = node.aliasedType;
34
+ const aliasedTypeStr = variableTypeToString(node.aliasedType, this.typeAliases);
35
+ return this.indentStr(`type ${node.aliasName} = ${aliasedTypeStr}\n`);
36
+ }
37
+ processTypeHint(node) {
38
+ this.typeHints[node.variableName] = node.variableType;
39
+ const typeStr = variableTypeToString(node.variableType, this.typeAliases);
40
+ return this.indentStr(`${node.variableName} :: ${typeStr}\n`);
41
+ }
42
+ // Assignment and literals
43
+ processAssignment(node) {
44
+ const valueCode = this.processNode(node.value).trim();
45
+ return this.indentStr(`${node.variableName} = ${valueCode}\n\n`);
46
+ }
47
+ generateLiteral(literal) {
48
+ switch (literal.type) {
49
+ case "number":
50
+ return literal.value;
51
+ case "string":
52
+ // Escape backslashes and quotes
53
+ const escaped = literal.value
54
+ .replace(/\\/g, "\\\\")
55
+ .replace(/"/g, '\\"');
56
+ return `"${escaped}"`;
57
+ case "variableName":
58
+ return literal.value;
59
+ case "prompt":
60
+ return this.generatePromptLiteral(literal);
61
+ default:
62
+ return "";
63
+ }
64
+ }
65
+ generatePromptLiteral(node) {
66
+ let result = "`";
67
+ for (const segment of node.segments) {
68
+ if (segment.type === "text") {
69
+ result += segment.value;
70
+ }
71
+ else if (segment.type === "interpolation") {
72
+ result += `\${${segment.variableName}}`;
73
+ }
74
+ }
75
+ result += "`";
76
+ return result;
77
+ }
78
+ processPromptLiteral(variableName, node) {
79
+ // For agency code, prompts are just part of assignments
80
+ // This shouldn't be called directly, but return empty string
81
+ return "";
82
+ }
83
+ // Function methods
84
+ processFunctionDefinition(node) {
85
+ const { functionName, body, parameters } = node;
86
+ // Build parameter list
87
+ const params = parameters.join(", ");
88
+ // Start function definition
89
+ let result = this.indentStr(`def ${functionName}(${params}) {\n`);
90
+ // Process body with increased indentation
91
+ this.increaseIndent();
92
+ this.functionScopedVariables = [...parameters];
93
+ for (const stmt of body) {
94
+ result += this.processNode(stmt);
95
+ }
96
+ this.functionScopedVariables = [];
97
+ this.decreaseIndent();
98
+ // Close function
99
+ result += this.indentStr(`}\n\n`);
100
+ return result;
101
+ }
102
+ processFunctionCall(node) {
103
+ const expr = this.generateFunctionCallExpression(node);
104
+ return this.indentStr(`${expr}\n`);
105
+ }
106
+ generateFunctionCallExpression(node) {
107
+ const args = node.arguments.map((arg) => {
108
+ return this.processNode(arg).trim();
109
+ });
110
+ return `${node.functionName}(${args.join(", ")})`;
111
+ }
112
+ // Data structures
113
+ processAgencyArray(node) {
114
+ const items = node.items.map((item) => {
115
+ return this.processNode(item).trim();
116
+ });
117
+ return `[${items.join(", ")}]`;
118
+ }
119
+ processAgencyObject(node) {
120
+ const entries = node.entries.map((entry) => {
121
+ const valueCode = this.processNode(entry.value).trim();
122
+ return `${entry.key}: ${valueCode}`;
123
+ });
124
+ return `{${entries.join(", ")}}`;
125
+ }
126
+ // Access expressions
127
+ processAccessExpression(node) {
128
+ switch (node.expression.type) {
129
+ case "dotProperty":
130
+ return this.processDotProperty(node.expression);
131
+ case "indexAccess":
132
+ return this.processIndexAccess(node.expression);
133
+ case "dotFunctionCall":
134
+ return this.processDotFunctionCall(node.expression);
135
+ }
136
+ }
137
+ processDotProperty(node) {
138
+ const objectCode = this.processNode(node.object).trim();
139
+ return `${objectCode}.${node.propertyName}`;
140
+ }
141
+ processIndexAccess(node) {
142
+ const arrayCode = this.processNode(node.array).trim();
143
+ const indexCode = this.processNode(node.index).trim();
144
+ return `${arrayCode}[${indexCode}]`;
145
+ }
146
+ processDotFunctionCall(node) {
147
+ const objectCode = this.processNode(node.object).trim();
148
+ const functionCallCode = this.generateFunctionCallExpression(node.functionCall);
149
+ return `${objectCode}.${functionCallCode}`;
150
+ }
151
+ // Control flow
152
+ processMatchBlock(node) {
153
+ const exprCode = this.processNode(node.expression).trim();
154
+ let result = this.indentStr(`match(${exprCode}) {\n`);
155
+ this.increaseIndent();
156
+ for (const caseNode of node.cases) {
157
+ // Handle comments within cases
158
+ if (caseNode.type === "comment") {
159
+ result += this.processComment(caseNode);
160
+ continue;
161
+ }
162
+ // Format case value (pattern)
163
+ const pattern = caseNode.caseValue === "_"
164
+ ? "_"
165
+ : this.processNode(caseNode.caseValue).trim();
166
+ // Format body (action)
167
+ const bodyCode = this.processNode(caseNode.body).trim();
168
+ result += this.indentStr(`${pattern} => ${bodyCode}\n`);
169
+ }
170
+ this.decreaseIndent();
171
+ result += this.indentStr(`}\n`);
172
+ return result;
173
+ }
174
+ processWhileLoop(node) {
175
+ const conditionCode = this.processNode(node.condition).trim();
176
+ let result = this.indentStr(`while (${conditionCode}) {\n`);
177
+ this.increaseIndent();
178
+ for (const stmt of node.body) {
179
+ result += this.processNode(stmt);
180
+ }
181
+ this.decreaseIndent();
182
+ result += this.indentStr(`}\n`);
183
+ return result;
184
+ }
185
+ processReturnStatement(node) {
186
+ const valueCode = this.processNode(node.value).trim();
187
+ return this.indentStr(`return ${valueCode}\n`);
188
+ }
189
+ // Utility methods
190
+ processComment(node) {
191
+ return this.indentStr(`// ${node.content}\n`);
192
+ }
193
+ processImportStatement(node) {
194
+ return this.indentStr(`import {${node.importedNames}} from "${node.modulePath}"\n`);
195
+ }
196
+ processGraphNode(node) {
197
+ // Graph nodes use similar syntax to functions
198
+ const { nodeName, body, parameters } = node;
199
+ const params = parameters.join(", ");
200
+ let result = this.indentStr(`node ${nodeName}(${params}) {\n`);
201
+ this.increaseIndent();
202
+ this.functionScopedVariables = [...parameters];
203
+ for (const stmt of body) {
204
+ result += this.processNode(stmt);
205
+ }
206
+ this.functionScopedVariables = [];
207
+ this.decreaseIndent();
208
+ result += this.indentStr(`}\n`);
209
+ return result;
210
+ }
211
+ processTool(node) {
212
+ // For agency code, tools are just functions
213
+ // No special formatting needed
214
+ return "";
215
+ }
216
+ processUsesTool(node) {
217
+ // Track tool usage but don't generate code
218
+ this.toolsUsed.push(node.toolName);
219
+ return this.indentStr(`+${node.toolName}\n`);
220
+ }
221
+ indentStr(str) {
222
+ return `${this.indent()}${str}`;
223
+ }
224
+ }
225
+ export function generateAgency(program) {
226
+ const generator = new AgencyGenerator();
227
+ return generator.generate(program).output.trim();
228
+ }
@@ -4,4 +4,4 @@ export declare const agencyNode: Parser<AgencyNode[]>;
4
4
  export declare const agencyParser: Parser<AgencyProgram>;
5
5
  export declare const _multilineCommentParser: Parser<string[]>;
6
6
  export declare const multilineCommentParser: Parser<string[][]>;
7
- export declare function parseAgency(input: string): ParserResult<AgencyProgram>;
7
+ export declare function parseAgency(input: string, verbose?: boolean): ParserResult<AgencyProgram>;
@@ -9,6 +9,7 @@ import { importStatmentParser } from "./parsers/importStatement.js";
9
9
  import { matchBlockParser } from "./parsers/matchBlock.js";
10
10
  import { returnStatementParser } from "./parsers/returnStatement.js";
11
11
  import { usesToolParser } from "./parsers/tools.js";
12
+ import { EgonLog } from "egonlog";
12
13
  export const agencyNode = (input) => {
13
14
  const parser = sepBy(spaces, trace("agencyParser", or(usesToolParser, importStatmentParser, graphNodeParser, typeAliasParser, whileLoopParser, typeHintParser, matchBlockParser, functionParser, returnStatementParser, accessExpressionParser, assignmentParser, functionCallParser, commentParser)));
14
15
  return parser(input);
@@ -16,9 +17,15 @@ export const agencyNode = (input) => {
16
17
  export const agencyParser = seqC(set("type", "agencyProgram"), capture(agencyNode, "nodes"), eof);
17
18
  export const _multilineCommentParser = between(str("/*"), str("*/"), anyChar);
18
19
  export const multilineCommentParser = search(_multilineCommentParser);
19
- export function parseAgency(input) {
20
+ export function parseAgency(input, verbose = false) {
21
+ const logger = new EgonLog({ level: verbose ? "debug" : "warn" });
20
22
  let normalized = input;
23
+ logger.debug("Starting to parse agency program");
24
+ logger.debug(`Input: ${input}`);
25
+ logger.debug("================================");
21
26
  const comments = multilineCommentParser(normalized);
27
+ logger.debug(`Multiline comments: ${JSON.stringify(comments)}`);
28
+ logger.debug("================================");
22
29
  // get rid of all multiline comments
23
30
  normalized = comments.rest
24
31
  .split("\n")
@@ -33,6 +40,8 @@ export function parseAgency(input) {
33
40
  nodes: [],
34
41
  }, "");
35
42
  }
43
+ logger.debug(`Normalized input: ${normalized}`);
44
+ logger.debug("================================");
36
45
  const result = agencyParser(normalized);
37
46
  return result;
38
47
  }
@@ -44,7 +44,7 @@ describe("importStatmentParser", () => {
44
44
  result: {
45
45
  type: "importStatement",
46
46
  importedNames: "foo ",
47
- modulePath: '"./local/path"',
47
+ modulePath: '"./local/path.js"',
48
48
  },
49
49
  },
50
50
  },
@@ -55,7 +55,7 @@ describe("importStatmentParser", () => {
55
55
  result: {
56
56
  type: "importStatement",
57
57
  importedNames: "bar ",
58
- modulePath: '"@/utils/helper"',
58
+ modulePath: '"../utils/helper.js"',
59
59
  },
60
60
  },
61
61
  },
@@ -89,7 +89,7 @@ describe("importStatmentParser", () => {
89
89
  result: {
90
90
  type: "importStatement",
91
91
  importedNames: "test ",
92
- modulePath: "'./module'",
92
+ modulePath: "'./module.js'",
93
93
  },
94
94
  },
95
95
  },
@@ -240,7 +240,7 @@ describe("importStatmentParser", () => {
240
240
  result: {
241
241
  type: "importStatement",
242
242
  importedNames: "foo ",
243
- modulePath: '"../../../utils/helpers"',
243
+ modulePath: '"../../../utils/helpers.js"',
244
244
  },
245
245
  },
246
246
  },
@@ -7,7 +7,7 @@ export declare const angleBracketsArrayTypeParser: Parser<ArrayType>;
7
7
  export declare const stringLiteralTypeParser: Parser<StringLiteralType>;
8
8
  export declare const numberLiteralTypeParser: Parser<NumberLiteralType>;
9
9
  export declare const booleanLiteralTypeParser: Parser<BooleanLiteralType>;
10
- export declare const objectPropertyDelimiter: Parser<(string[] | ";")[]>;
10
+ export declare const objectPropertyDelimiter: Parser<"\n" | (string | string[])[]>;
11
11
  export declare const objectPropertyParser: Parser<ObjectProperty>;
12
12
  export declare const objectPropertyDescriptionParser: Parser<{
13
13
  description: string;
@@ -1,5 +1,5 @@
1
1
  import { optionalSpaces, varNameChar } from "./utils.js";
2
- import { capture, captureCaptures, char, count, digit, many1Till, many1WithJoin, or, sepBy, seqC, seqR, set, space, spaces, str, trace, } from "tarsec";
2
+ import { capture, captureCaptures, char, count, digit, many1Till, many1WithJoin, oneOf, or, sepBy, seqC, seqR, set, space, spaces, str, trace, } from "tarsec";
3
3
  import { optionalSemicolon } from "./parserUtils.js";
4
4
  export const primitiveTypeParser = trace("primitiveTypeParser", seqC(set("type", "primitiveType"), capture(or(str("number"), str("string"), str("boolean")), "value")));
5
5
  export const typeAliasVariableParser = trace("typeAliasVariableParser", seqC(set("type", "typeAliasVariable"), capture(many1WithJoin(varNameChar), "aliasName")));
@@ -27,12 +27,12 @@ export const angleBracketsArrayTypeParser = trace("angleBracketsArrayTypeParser"
27
27
  export const stringLiteralTypeParser = trace("stringLiteralTypeParser", seqC(set("type", "stringLiteralType"), char('"'), capture(many1Till(char('"')), "value"), char('"')));
28
28
  export const numberLiteralTypeParser = trace("numberLiteralTypeParser", seqC(set("type", "numberLiteralType"), capture(many1WithJoin(or(char("-"), char("."), digit)), "value")));
29
29
  export const booleanLiteralTypeParser = trace("booleanLiteralTypeParser", seqC(set("type", "booleanLiteralType"), capture(or(str("true"), str("false")), "value")));
30
- export const objectPropertyDelimiter = seqR(optionalSpaces, char(";"), optionalSpaces);
30
+ export const objectPropertyDelimiter = or(char("\n"), seqR(optionalSpaces, oneOf(",;"), optionalSpaces));
31
31
  export const objectPropertyParser = trace("objectPropertyParser", (input) => {
32
32
  const parser = seqC(capture(many1WithJoin(varNameChar), "key"), optionalSpaces, char(":"), optionalSpaces, capture(variableTypeParser, "value"));
33
33
  return parser(input);
34
34
  });
35
- export const objectPropertyDescriptionParser = seqC(char("#"), optionalSpaces, capture(many1Till(char(";")), "description"));
35
+ export const objectPropertyDescriptionParser = seqC(char("#"), optionalSpaces, capture(many1Till(oneOf(",;\n")), "description"));
36
36
  export const objectPropertyWithDescriptionParser = trace("objectPropertyWithDescriptionParser", seqC(captureCaptures(objectPropertyParser), spaces, captureCaptures(objectPropertyDescriptionParser)));
37
37
  export const objectTypeParser = trace("objectTypeParser", (input) => {
38
38
  const parser = seqC(set("type", "objectType"), char("{"), optionalSpaces, capture(sepBy(objectPropertyDelimiter, or(objectPropertyWithDescriptionParser, objectPropertyParser)), "properties"), optionalSpaces, char("}"));
@@ -1012,6 +1012,24 @@ describe("objectPropertyDescriptionParser", () => {
1012
1012
  },
1013
1013
  },
1014
1014
  },
1015
+ {
1016
+ input: "# comma,",
1017
+ expected: {
1018
+ success: true,
1019
+ result: {
1020
+ description: "comma",
1021
+ },
1022
+ },
1023
+ },
1024
+ {
1025
+ input: "# newline",
1026
+ expected: {
1027
+ success: true,
1028
+ result: {
1029
+ description: "newline",
1030
+ },
1031
+ },
1032
+ },
1015
1033
  {
1016
1034
  input: "# with extra spaces ;",
1017
1035
  expected: {
@@ -1022,11 +1040,11 @@ describe("objectPropertyDescriptionParser", () => {
1022
1040
  },
1023
1041
  },
1024
1042
  {
1025
- input: "# description with, punctuation!;",
1043
+ input: "# description with punctuation!;",
1026
1044
  expected: {
1027
1045
  success: true,
1028
1046
  result: {
1029
- description: "description with, punctuation!",
1047
+ description: "description with punctuation!",
1030
1048
  },
1031
1049
  },
1032
1050
  },
@@ -3,6 +3,7 @@ import { spawn } from "child_process";
3
3
  import * as fs from "fs";
4
4
  import { parseAgency } from "../lib/parser.js";
5
5
  import { generateGraph } from "../lib/index.js";
6
+ import { generateAgency } from "../lib/backends/agencyGenerator.js";
6
7
  function help() {
7
8
  console.log(`
8
9
  Agency Language CLI
@@ -11,6 +12,8 @@ Usage:
11
12
  agency help Show this help message
12
13
  agency compile <input> [output] Compile .agency file to TypeScript
13
14
  agency run <input> [output] Compile and run .agency file
15
+ agency format <input> Format .agency file in place
16
+ agency parse <input> Parse .agency file and show AST
14
17
  agency <input> Compile and run .agency file (shorthand)
15
18
 
16
19
  Arguments:
@@ -18,32 +21,39 @@ Arguments:
18
21
  output Path to output .ts file (optional)
19
22
  Default: <input-name>.ts
20
23
 
24
+ Flags:
25
+ -v, --verbose Enable verbose logging during parsing
26
+
21
27
  Examples:
22
28
  agency help Show help
23
29
  agency compile script.agency Compile to script.ts
24
30
  agency compile script.agency out.ts Compile to out.ts
25
31
  agency run script.agency Compile and run script.agency
32
+ agency -v parse script.agency Parse with verbose logging
26
33
  agency script.agency Compile and run (shorthand)
27
34
  `);
28
35
  }
29
- function compile(inputFile, outputFile) {
36
+ function parse(inputFile, verbose = false) {
30
37
  // Validate input file
31
38
  if (!fs.existsSync(inputFile)) {
32
39
  console.error(`Error: Input file '${inputFile}' not found`);
33
40
  process.exit(1);
34
41
  }
35
- // Determine output file name
36
- const output = outputFile || inputFile.replace(".agency", ".ts");
37
42
  // Read and parse the Agency file
38
43
  const contents = fs.readFileSync(inputFile, "utf-8");
39
- const parseResult = parseAgency(contents);
44
+ const parseResult = parseAgency(contents, verbose);
40
45
  // Check if parsing was successful
41
46
  if (!parseResult.success) {
42
47
  console.error("Parse error:");
43
48
  console.error(parseResult);
44
49
  process.exit(1);
45
50
  }
46
- const parsedProgram = parseResult.result;
51
+ return parseResult.result;
52
+ }
53
+ function compile(inputFile, outputFile, verbose = false) {
54
+ // Determine output file name
55
+ const output = outputFile || inputFile.replace(".agency", ".ts");
56
+ const parsedProgram = parse(inputFile, verbose);
47
57
  // Generate TypeScript code
48
58
  const generatedCode = generateGraph(parsedProgram);
49
59
  // Write to output file
@@ -51,9 +61,9 @@ function compile(inputFile, outputFile) {
51
61
  console.log(`Generated ${output} from ${inputFile}`);
52
62
  return output;
53
63
  }
54
- function run(inputFile, outputFile) {
64
+ function run(inputFile, outputFile, verbose = false) {
55
65
  // Compile the file
56
- const output = compile(inputFile, outputFile);
66
+ const output = compile(inputFile, outputFile, verbose);
57
67
  // Run the generated TypeScript file with Node.js
58
68
  console.log(`Running ${output}...`);
59
69
  console.log("---");
@@ -71,6 +81,16 @@ function run(inputFile, outputFile) {
71
81
  }
72
82
  });
73
83
  }
84
+ function format(inputFile, verbose = false) {
85
+ const parsedProgram = parse(inputFile, verbose);
86
+ // Generate TypeScript code
87
+ const generatedCode = generateAgency(parsedProgram);
88
+ // Write to output file
89
+ //fs.writeFileSync(inputFile, generatedCode, "utf-8");
90
+ // console.log(`Generated ${output} from ${inputFile}`);
91
+ console.log(generatedCode);
92
+ return generatedCode;
93
+ }
74
94
  // Main CLI logic
75
95
  function main() {
76
96
  const args = process.argv.slice(2);
@@ -79,7 +99,12 @@ function main() {
79
99
  help();
80
100
  return;
81
101
  }
82
- const command = args[0];
102
+ // Extract verbose flag
103
+ const verboseIndex = args.findIndex((arg) => arg === "-v" || arg === "--verbose");
104
+ const verbose = verboseIndex !== -1;
105
+ // Remove verbose flag from args
106
+ const filteredArgs = args.filter((arg) => arg !== "-v" && arg !== "--verbose");
107
+ const command = filteredArgs[0];
83
108
  switch (command) {
84
109
  case "help":
85
110
  case "--help":
@@ -87,25 +112,43 @@ function main() {
87
112
  help();
88
113
  break;
89
114
  case "compile":
90
- if (args.length < 2) {
115
+ if (filteredArgs.length < 2) {
91
116
  console.error("Error: 'compile' command requires an input file");
92
117
  console.error("Usage: agency compile <input> [output]");
93
118
  process.exit(1);
94
119
  }
95
- compile(args[1], args[2]);
120
+ compile(filteredArgs[1], filteredArgs[2], verbose);
96
121
  break;
97
122
  case "run":
98
- if (args.length < 2) {
123
+ if (filteredArgs.length < 2) {
99
124
  console.error("Error: 'run' command requires an input file");
100
125
  console.error("Usage: agency run <input> [output]");
101
126
  process.exit(1);
102
127
  }
103
- run(args[1], args[2]);
128
+ run(filteredArgs[1], filteredArgs[2], verbose);
129
+ break;
130
+ case "fmt":
131
+ case "format":
132
+ if (filteredArgs.length < 1) {
133
+ console.error("Error: 'format' command requires an input file");
134
+ console.error("Usage: agency format <input>");
135
+ process.exit(1);
136
+ }
137
+ format(filteredArgs[1], verbose);
138
+ break;
139
+ case "parse":
140
+ if (filteredArgs.length < 1) {
141
+ console.error("Error: 'parse' command requires an input file");
142
+ console.error("Usage: agency parse <input>");
143
+ process.exit(1);
144
+ }
145
+ const result = parse(filteredArgs[1], verbose);
146
+ console.log(JSON.stringify(result, null, 2));
104
147
  break;
105
148
  default:
106
149
  // If first arg is not a recognized command, treat it as a file to run
107
150
  if (command.endsWith(".agency") || fs.existsSync(command)) {
108
- run(command, args[1]);
151
+ run(command, filteredArgs[1], verbose);
109
152
  }
110
153
  else {
111
154
  console.error(`Error: Unknown command '${command}'`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agency-lang",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "The Agency language",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -9,7 +9,8 @@
9
9
  "build": "rm -rf dist/ && tsc && tsc-alias",
10
10
  "start": "node dist/lib/index.js",
11
11
  "templates": "typestache ./lib/templates",
12
- "typecheck": "tsc --noEmit"
12
+ "typecheck": "tsc --noEmit",
13
+ "agency": "node ./dist/scripts/agency.js"
13
14
  },
14
15
  "bin": {
15
16
  "agency": "./dist/scripts/agency.js"
@@ -38,6 +39,7 @@
38
39
  },
39
40
  "homepage": "https://github.com/egonSchiele/agency-lang#readme",
40
41
  "dependencies": {
42
+ "egonlog": "^0.0.2",
41
43
  "nanoid": "^5.1.6",
42
44
  "openai": "^6.15.0",
43
45
  "simplemachine": "github:egonSchiele/simplemachine",