@aigne/ash 0.0.1

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.
Files changed (146) hide show
  1. package/DESIGN.md +41 -0
  2. package/dist/ai-dev-loop/ash-run-result.cjs +12 -0
  3. package/dist/ai-dev-loop/ash-run-result.d.cts +28 -0
  4. package/dist/ai-dev-loop/ash-run-result.d.cts.map +1 -0
  5. package/dist/ai-dev-loop/ash-run-result.d.mts +28 -0
  6. package/dist/ai-dev-loop/ash-run-result.d.mts.map +1 -0
  7. package/dist/ai-dev-loop/ash-run-result.mjs +11 -0
  8. package/dist/ai-dev-loop/ash-run-result.mjs.map +1 -0
  9. package/dist/ai-dev-loop/ash-typed-error.cjs +51 -0
  10. package/dist/ai-dev-loop/ash-typed-error.d.cts +54 -0
  11. package/dist/ai-dev-loop/ash-typed-error.d.cts.map +1 -0
  12. package/dist/ai-dev-loop/ash-typed-error.d.mts +54 -0
  13. package/dist/ai-dev-loop/ash-typed-error.d.mts.map +1 -0
  14. package/dist/ai-dev-loop/ash-typed-error.mjs +50 -0
  15. package/dist/ai-dev-loop/ash-typed-error.mjs.map +1 -0
  16. package/dist/ai-dev-loop/ash-validate.cjs +27 -0
  17. package/dist/ai-dev-loop/ash-validate.d.cts +7 -0
  18. package/dist/ai-dev-loop/ash-validate.d.cts.map +1 -0
  19. package/dist/ai-dev-loop/ash-validate.d.mts +7 -0
  20. package/dist/ai-dev-loop/ash-validate.d.mts.map +1 -0
  21. package/dist/ai-dev-loop/ash-validate.mjs +28 -0
  22. package/dist/ai-dev-loop/ash-validate.mjs.map +1 -0
  23. package/dist/ai-dev-loop/dev-loop.cjs +134 -0
  24. package/dist/ai-dev-loop/dev-loop.d.cts +28 -0
  25. package/dist/ai-dev-loop/dev-loop.d.cts.map +1 -0
  26. package/dist/ai-dev-loop/dev-loop.d.mts +28 -0
  27. package/dist/ai-dev-loop/dev-loop.d.mts.map +1 -0
  28. package/dist/ai-dev-loop/dev-loop.mjs +135 -0
  29. package/dist/ai-dev-loop/dev-loop.mjs.map +1 -0
  30. package/dist/ai-dev-loop/index.cjs +24 -0
  31. package/dist/ai-dev-loop/index.d.cts +9 -0
  32. package/dist/ai-dev-loop/index.d.mts +9 -0
  33. package/dist/ai-dev-loop/index.mjs +10 -0
  34. package/dist/ai-dev-loop/live-mode.cjs +17 -0
  35. package/dist/ai-dev-loop/live-mode.d.cts +24 -0
  36. package/dist/ai-dev-loop/live-mode.d.cts.map +1 -0
  37. package/dist/ai-dev-loop/live-mode.d.mts +24 -0
  38. package/dist/ai-dev-loop/live-mode.d.mts.map +1 -0
  39. package/dist/ai-dev-loop/live-mode.mjs +17 -0
  40. package/dist/ai-dev-loop/live-mode.mjs.map +1 -0
  41. package/dist/ai-dev-loop/meta-tools.cjs +123 -0
  42. package/dist/ai-dev-loop/meta-tools.d.cts +24 -0
  43. package/dist/ai-dev-loop/meta-tools.d.cts.map +1 -0
  44. package/dist/ai-dev-loop/meta-tools.d.mts +24 -0
  45. package/dist/ai-dev-loop/meta-tools.d.mts.map +1 -0
  46. package/dist/ai-dev-loop/meta-tools.mjs +120 -0
  47. package/dist/ai-dev-loop/meta-tools.mjs.map +1 -0
  48. package/dist/ai-dev-loop/structured-runner.cjs +154 -0
  49. package/dist/ai-dev-loop/structured-runner.d.cts +12 -0
  50. package/dist/ai-dev-loop/structured-runner.d.cts.map +1 -0
  51. package/dist/ai-dev-loop/structured-runner.d.mts +12 -0
  52. package/dist/ai-dev-loop/structured-runner.d.mts.map +1 -0
  53. package/dist/ai-dev-loop/structured-runner.mjs +155 -0
  54. package/dist/ai-dev-loop/structured-runner.mjs.map +1 -0
  55. package/dist/ai-dev-loop/system-prompt.cjs +55 -0
  56. package/dist/ai-dev-loop/system-prompt.d.cts +20 -0
  57. package/dist/ai-dev-loop/system-prompt.d.cts.map +1 -0
  58. package/dist/ai-dev-loop/system-prompt.d.mts +20 -0
  59. package/dist/ai-dev-loop/system-prompt.d.mts.map +1 -0
  60. package/dist/ai-dev-loop/system-prompt.mjs +54 -0
  61. package/dist/ai-dev-loop/system-prompt.mjs.map +1 -0
  62. package/dist/ast.d.cts +140 -0
  63. package/dist/ast.d.cts.map +1 -0
  64. package/dist/ast.d.mts +140 -0
  65. package/dist/ast.d.mts.map +1 -0
  66. package/dist/compiler.cjs +802 -0
  67. package/dist/compiler.d.cts +103 -0
  68. package/dist/compiler.d.cts.map +1 -0
  69. package/dist/compiler.d.mts +103 -0
  70. package/dist/compiler.d.mts.map +1 -0
  71. package/dist/compiler.mjs +802 -0
  72. package/dist/compiler.mjs.map +1 -0
  73. package/dist/index.cjs +14 -0
  74. package/dist/index.d.cts +7 -0
  75. package/dist/index.d.mts +7 -0
  76. package/dist/index.mjs +7 -0
  77. package/dist/lexer.cjs +451 -0
  78. package/dist/lexer.d.cts +14 -0
  79. package/dist/lexer.d.cts.map +1 -0
  80. package/dist/lexer.d.mts +14 -0
  81. package/dist/lexer.d.mts.map +1 -0
  82. package/dist/lexer.mjs +451 -0
  83. package/dist/lexer.mjs.map +1 -0
  84. package/dist/parser.cjs +734 -0
  85. package/dist/parser.d.cts +40 -0
  86. package/dist/parser.d.cts.map +1 -0
  87. package/dist/parser.d.mts +40 -0
  88. package/dist/parser.d.mts.map +1 -0
  89. package/dist/parser.mjs +734 -0
  90. package/dist/parser.mjs.map +1 -0
  91. package/dist/reference.cjs +130 -0
  92. package/dist/reference.d.cts +11 -0
  93. package/dist/reference.d.cts.map +1 -0
  94. package/dist/reference.d.mts +11 -0
  95. package/dist/reference.d.mts.map +1 -0
  96. package/dist/reference.mjs +130 -0
  97. package/dist/reference.mjs.map +1 -0
  98. package/dist/template.cjs +85 -0
  99. package/dist/template.mjs +84 -0
  100. package/dist/template.mjs.map +1 -0
  101. package/dist/type-checker.cjs +582 -0
  102. package/dist/type-checker.d.cts +31 -0
  103. package/dist/type-checker.d.cts.map +1 -0
  104. package/dist/type-checker.d.mts +31 -0
  105. package/dist/type-checker.d.mts.map +1 -0
  106. package/dist/type-checker.mjs +573 -0
  107. package/dist/type-checker.mjs.map +1 -0
  108. package/package.json +29 -0
  109. package/src/ai-dev-loop/ash-run-result.test.ts +113 -0
  110. package/src/ai-dev-loop/ash-run-result.ts +46 -0
  111. package/src/ai-dev-loop/ash-typed-error.test.ts +136 -0
  112. package/src/ai-dev-loop/ash-typed-error.ts +50 -0
  113. package/src/ai-dev-loop/ash-validate.test.ts +54 -0
  114. package/src/ai-dev-loop/ash-validate.ts +34 -0
  115. package/src/ai-dev-loop/dev-loop.test.ts +364 -0
  116. package/src/ai-dev-loop/dev-loop.ts +156 -0
  117. package/src/ai-dev-loop/dry-run.test.ts +107 -0
  118. package/src/ai-dev-loop/e2e-multi-fix.test.ts +473 -0
  119. package/src/ai-dev-loop/e2e.test.ts +324 -0
  120. package/src/ai-dev-loop/index.ts +15 -0
  121. package/src/ai-dev-loop/invariants.test.ts +253 -0
  122. package/src/ai-dev-loop/live-mode.test.ts +63 -0
  123. package/src/ai-dev-loop/live-mode.ts +33 -0
  124. package/src/ai-dev-loop/meta-tools.test.ts +120 -0
  125. package/src/ai-dev-loop/meta-tools.ts +142 -0
  126. package/src/ai-dev-loop/structured-runner.test.ts +159 -0
  127. package/src/ai-dev-loop/structured-runner.ts +209 -0
  128. package/src/ai-dev-loop/system-prompt.test.ts +102 -0
  129. package/src/ai-dev-loop/system-prompt.ts +81 -0
  130. package/src/ast.ts +186 -0
  131. package/src/compiler.test.ts +2933 -0
  132. package/src/compiler.ts +1103 -0
  133. package/src/e2e.test.ts +552 -0
  134. package/src/index.ts +16 -0
  135. package/src/lexer.test.ts +538 -0
  136. package/src/lexer.ts +222 -0
  137. package/src/parser.test.ts +1024 -0
  138. package/src/parser.ts +835 -0
  139. package/src/reference.test.ts +166 -0
  140. package/src/reference.ts +125 -0
  141. package/src/template.test.ts +210 -0
  142. package/src/template.ts +139 -0
  143. package/src/type-checker.test.ts +1494 -0
  144. package/src/type-checker.ts +785 -0
  145. package/tsconfig.json +9 -0
  146. package/tsdown.config.ts +12 -0
package/DESIGN.md ADDED
@@ -0,0 +1,41 @@
1
+ # ASH — Design
2
+
3
+ ## What ASH Is
4
+
5
+ ASH (Agentic Shell) is a **pipeline intermediate representation** designed for
6
+ agents and agentic workflows. It compiles declarative multi-stage pipelines
7
+ into executable jobs that run against any world interface (AFS, AOS namespace,
8
+ or custom implementations).
9
+
10
+ ```
11
+ find /world/users | where active == true | map { name, role } | save /world/active
12
+ ```
13
+
14
+ ## What ASH Is Not
15
+
16
+ ASH is **not** an interactive shell for humans. It does not handle:
17
+
18
+ - Prompts or REPL
19
+ - Command history
20
+ - Current working directory (cwd)
21
+ - Session management
22
+ - TUI / interactive UI
23
+ - Tab completion
24
+
25
+ ## Consumers
26
+
27
+ | Consumer | Interface |
28
+ |----------|-----------|
29
+ | AFS exec | `afs exec script.ash` — runs against AFS world |
30
+ | AOS runtime | Loads `.ash` as program entrypoint |
31
+ | Agent runtime | Calls `compileSource()` / `CompiledProgram.run()` directly |
32
+ | Console | Detects `|` in input → sends full line to ASH compiler |
33
+
34
+ ## Relationship to AFS
35
+
36
+ ```
37
+ ASH = Pipeline DSL (Agent / Advanced User)
38
+ AFS = World (read/write/publish interface)
39
+ ```
40
+
41
+ ASH operates on any `WorldInterface` — AFS is the primary but not sole target.
@@ -0,0 +1,12 @@
1
+
2
+ //#region src/ai-dev-loop/ash-run-result.ts
3
+ function isAshRunSuccess(result) {
4
+ return result.status === "ok";
5
+ }
6
+ function isAshRunFailure(result) {
7
+ return result.status === "error";
8
+ }
9
+
10
+ //#endregion
11
+ exports.isAshRunFailure = isAshRunFailure;
12
+ exports.isAshRunSuccess = isAshRunSuccess;
@@ -0,0 +1,28 @@
1
+ import { AshTypedError } from "./ash-typed-error.cjs";
2
+
3
+ //#region src/ai-dev-loop/ash-run-result.d.ts
4
+ interface AshStepResult {
5
+ step: number;
6
+ command: string;
7
+ status: "ok" | "error" | "skipped";
8
+ duration_ms: number;
9
+ output?: unknown[];
10
+ }
11
+ interface AshRunSuccess {
12
+ status: "ok";
13
+ steps: AshStepResult[];
14
+ output: unknown[];
15
+ duration_ms: number;
16
+ }
17
+ interface AshRunFailure {
18
+ status: "error";
19
+ steps: AshStepResult[];
20
+ failedAt: AshTypedError;
21
+ duration_ms: number;
22
+ }
23
+ type AshRunResult = AshRunSuccess | AshRunFailure;
24
+ declare function isAshRunSuccess(result: AshRunResult): result is AshRunSuccess;
25
+ declare function isAshRunFailure(result: AshRunResult): result is AshRunFailure;
26
+ //#endregion
27
+ export { AshRunFailure, AshRunResult, AshRunSuccess, AshStepResult, isAshRunFailure, isAshRunSuccess };
28
+ //# sourceMappingURL=ash-run-result.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ash-run-result.d.cts","names":[],"sources":["../../src/ai-dev-loop/ash-run-result.ts"],"mappings":";;;UAMiB,aAAA;EACf,IAAA;EACA,OAAA;EACA,MAAA;EACA,WAAA;EACA,MAAA;AAAA;AAAA,UAGe,aAAA;EACf,MAAA;EACA,KAAA,EAAO,aAAA;EACP,MAAA;EACA,WAAA;AAAA;AAAA,UAGe,aAAA;EACf,MAAA;EACA,KAAA,EAAO,aAAA;EACP,QAAA,EAAU,aAAA;EACV,WAAA;AAAA;AAAA,KAGU,YAAA,GAAe,aAAA,GAAgB,aAAA;AAAA,iBAE3B,eAAA,CAAgB,MAAA,EAAQ,YAAA,GAAe,MAAA,IAAU,aAAA;AAAA,iBAIjD,eAAA,CAAgB,MAAA,EAAQ,YAAA,GAAe,MAAA,IAAU,aAAA"}
@@ -0,0 +1,28 @@
1
+ import { AshTypedError } from "./ash-typed-error.mjs";
2
+
3
+ //#region src/ai-dev-loop/ash-run-result.d.ts
4
+ interface AshStepResult {
5
+ step: number;
6
+ command: string;
7
+ status: "ok" | "error" | "skipped";
8
+ duration_ms: number;
9
+ output?: unknown[];
10
+ }
11
+ interface AshRunSuccess {
12
+ status: "ok";
13
+ steps: AshStepResult[];
14
+ output: unknown[];
15
+ duration_ms: number;
16
+ }
17
+ interface AshRunFailure {
18
+ status: "error";
19
+ steps: AshStepResult[];
20
+ failedAt: AshTypedError;
21
+ duration_ms: number;
22
+ }
23
+ type AshRunResult = AshRunSuccess | AshRunFailure;
24
+ declare function isAshRunSuccess(result: AshRunResult): result is AshRunSuccess;
25
+ declare function isAshRunFailure(result: AshRunResult): result is AshRunFailure;
26
+ //#endregion
27
+ export { AshRunFailure, AshRunResult, AshRunSuccess, AshStepResult, isAshRunFailure, isAshRunSuccess };
28
+ //# sourceMappingURL=ash-run-result.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ash-run-result.d.mts","names":[],"sources":["../../src/ai-dev-loop/ash-run-result.ts"],"mappings":";;;UAMiB,aAAA;EACf,IAAA;EACA,OAAA;EACA,MAAA;EACA,WAAA;EACA,MAAA;AAAA;AAAA,UAGe,aAAA;EACf,MAAA;EACA,KAAA,EAAO,aAAA;EACP,MAAA;EACA,WAAA;AAAA;AAAA,UAGe,aAAA;EACf,MAAA;EACA,KAAA,EAAO,aAAA;EACP,QAAA,EAAU,aAAA;EACV,WAAA;AAAA;AAAA,KAGU,YAAA,GAAe,aAAA,GAAgB,aAAA;AAAA,iBAE3B,eAAA,CAAgB,MAAA,EAAQ,YAAA,GAAe,MAAA,IAAU,aAAA;AAAA,iBAIjD,eAAA,CAAgB,MAAA,EAAQ,YAAA,GAAe,MAAA,IAAU,aAAA"}
@@ -0,0 +1,11 @@
1
+ //#region src/ai-dev-loop/ash-run-result.ts
2
+ function isAshRunSuccess(result) {
3
+ return result.status === "ok";
4
+ }
5
+ function isAshRunFailure(result) {
6
+ return result.status === "error";
7
+ }
8
+
9
+ //#endregion
10
+ export { isAshRunFailure, isAshRunSuccess };
11
+ //# sourceMappingURL=ash-run-result.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ash-run-result.mjs","names":[],"sources":["../../src/ai-dev-loop/ash-run-result.ts"],"sourcesContent":["/**\n * AshRunResult — Structured execution result for ASH scripts.\n */\n\nimport type { AshTypedError } from \"./ash-typed-error.js\";\n\nexport interface AshStepResult {\n step: number;\n command: string;\n status: \"ok\" | \"error\" | \"skipped\";\n duration_ms: number;\n output?: unknown[];\n}\n\nexport interface AshRunSuccess {\n status: \"ok\";\n steps: AshStepResult[];\n output: unknown[];\n duration_ms: number;\n}\n\nexport interface AshRunFailure {\n status: \"error\";\n steps: AshStepResult[];\n failedAt: AshTypedError;\n duration_ms: number;\n}\n\nexport type AshRunResult = AshRunSuccess | AshRunFailure;\n\nexport function isAshRunSuccess(result: AshRunResult): result is AshRunSuccess {\n return result.status === \"ok\";\n}\n\nexport function isAshRunFailure(result: AshRunResult): result is AshRunFailure {\n return result.status === \"error\";\n}\n\nexport function validateRunResult(result: unknown): void {\n const r = result as any;\n if (!r || typeof r !== \"object\") throw new Error(\"AshRunResult: must be an object\");\n if (!Array.isArray(r.steps)) throw new Error(\"AshRunResult: missing steps array\");\n if (r.status === \"error\" && !r.failedAt) {\n throw new Error(\"AshRunFailure: missing failedAt field\");\n }\n}\n"],"mappings":";AA8BA,SAAgB,gBAAgB,QAA+C;AAC7E,QAAO,OAAO,WAAW;;AAG3B,SAAgB,gBAAgB,QAA+C;AAC7E,QAAO,OAAO,WAAW"}
@@ -0,0 +1,51 @@
1
+
2
+ //#region src/ai-dev-loop/ash-typed-error.ts
3
+ const VALID_KINDS = new Set([
4
+ "IntentDenied",
5
+ "CapabilityMissing",
6
+ "ToolNotFound",
7
+ "ValidationFailed",
8
+ "BudgetExceeded",
9
+ "Timeout",
10
+ "ParseError",
11
+ "RuntimeError"
12
+ ]);
13
+ function isAshTypedError(value) {
14
+ if (!value || typeof value !== "object") return false;
15
+ const obj = value;
16
+ return typeof obj.kind === "string" && VALID_KINDS.has(obj.kind) && typeof obj.message === "string";
17
+ }
18
+ /**
19
+ * Best-effort conversion from raw ASH error string → AshTypedError.
20
+ */
21
+ function fromJobError(errorStr) {
22
+ if (errorStr.startsWith("Capability denied:")) return {
23
+ kind: "CapabilityMissing",
24
+ capability: errorStr.replace("Capability denied:", "").trim(),
25
+ message: errorStr
26
+ };
27
+ if (errorStr.includes("not found") || errorStr.includes("unknown command")) return {
28
+ kind: "ToolNotFound",
29
+ name: errorStr,
30
+ available: [],
31
+ message: errorStr
32
+ };
33
+ if (errorStr.includes("timeout") || errorStr.includes("Timeout")) return {
34
+ kind: "Timeout",
35
+ step: "",
36
+ limit_ms: 0,
37
+ message: errorStr
38
+ };
39
+ if (errorStr.includes("parse") || errorStr.includes("syntax") || errorStr.includes("Unexpected")) return {
40
+ kind: "ParseError",
41
+ message: errorStr
42
+ };
43
+ return {
44
+ kind: "RuntimeError",
45
+ message: errorStr
46
+ };
47
+ }
48
+
49
+ //#endregion
50
+ exports.fromJobError = fromJobError;
51
+ exports.isAshTypedError = isAshTypedError;
@@ -0,0 +1,54 @@
1
+ //#region src/ai-dev-loop/ash-typed-error.d.ts
2
+ /**
3
+ * AshTypedError — Discriminated union of all ASH error types.
4
+ *
5
+ * Each kind carries enough structured information for AI self-repair.
6
+ */
7
+ type AshTypedError = {
8
+ kind: "IntentDenied";
9
+ invariant: string;
10
+ message: string;
11
+ suggestion?: string;
12
+ } | {
13
+ kind: "CapabilityMissing";
14
+ capability: string;
15
+ message: string;
16
+ } | {
17
+ kind: "ToolNotFound";
18
+ name: string;
19
+ available: string[];
20
+ message: string;
21
+ } | {
22
+ kind: "ValidationFailed";
23
+ field: string;
24
+ expected: string;
25
+ got: string;
26
+ message: string;
27
+ } | {
28
+ kind: "BudgetExceeded";
29
+ device: string;
30
+ limit: number;
31
+ used: number;
32
+ message: string;
33
+ } | {
34
+ kind: "Timeout";
35
+ step: string;
36
+ limit_ms: number;
37
+ message: string;
38
+ } | {
39
+ kind: "ParseError";
40
+ line?: number;
41
+ message: string;
42
+ } | {
43
+ kind: "RuntimeError";
44
+ message: string;
45
+ context?: Record<string, unknown>;
46
+ };
47
+ declare function isAshTypedError(value: unknown): value is AshTypedError;
48
+ /**
49
+ * Best-effort conversion from raw ASH error string → AshTypedError.
50
+ */
51
+ declare function fromJobError(errorStr: string): AshTypedError;
52
+ //#endregion
53
+ export { AshTypedError, fromJobError, isAshTypedError };
54
+ //# sourceMappingURL=ash-typed-error.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ash-typed-error.d.cts","names":[],"sources":["../../src/ai-dev-loop/ash-typed-error.ts"],"mappings":";;AAMA;;;;KAAY,aAAA;EACN,IAAA;EAAsB,SAAA;EAAmB,OAAA;EAAiB,UAAA;AAAA;EAC1D,IAAA;EAA2B,UAAA;EAAoB,OAAA;AAAA;EAC/C,IAAA;EAAsB,IAAA;EAAc,SAAA;EAAqB,OAAA;AAAA;EACzD,IAAA;EAA0B,KAAA;EAAe,QAAA;EAAkB,GAAA;EAAa,OAAA;AAAA;EACxE,IAAA;EAAwB,MAAA;EAAgB,KAAA;EAAe,IAAA;EAAc,OAAA;AAAA;EACrE,IAAA;EAAiB,IAAA;EAAc,QAAA;EAAkB,OAAA;AAAA;EACjD,IAAA;EAAoB,IAAA;EAAe,OAAA;AAAA;EACnC,IAAA;EAAsB,OAAA;EAAiB,OAAA,GAAU,MAAA;AAAA;AAAA,iBAOvC,eAAA,CAAgB,KAAA,YAAiB,KAAA,IAAS,aAAA;;;AAS1D;iBAAgB,YAAA,CAAa,QAAA,WAAmB,aAAA"}
@@ -0,0 +1,54 @@
1
+ //#region src/ai-dev-loop/ash-typed-error.d.ts
2
+ /**
3
+ * AshTypedError — Discriminated union of all ASH error types.
4
+ *
5
+ * Each kind carries enough structured information for AI self-repair.
6
+ */
7
+ type AshTypedError = {
8
+ kind: "IntentDenied";
9
+ invariant: string;
10
+ message: string;
11
+ suggestion?: string;
12
+ } | {
13
+ kind: "CapabilityMissing";
14
+ capability: string;
15
+ message: string;
16
+ } | {
17
+ kind: "ToolNotFound";
18
+ name: string;
19
+ available: string[];
20
+ message: string;
21
+ } | {
22
+ kind: "ValidationFailed";
23
+ field: string;
24
+ expected: string;
25
+ got: string;
26
+ message: string;
27
+ } | {
28
+ kind: "BudgetExceeded";
29
+ device: string;
30
+ limit: number;
31
+ used: number;
32
+ message: string;
33
+ } | {
34
+ kind: "Timeout";
35
+ step: string;
36
+ limit_ms: number;
37
+ message: string;
38
+ } | {
39
+ kind: "ParseError";
40
+ line?: number;
41
+ message: string;
42
+ } | {
43
+ kind: "RuntimeError";
44
+ message: string;
45
+ context?: Record<string, unknown>;
46
+ };
47
+ declare function isAshTypedError(value: unknown): value is AshTypedError;
48
+ /**
49
+ * Best-effort conversion from raw ASH error string → AshTypedError.
50
+ */
51
+ declare function fromJobError(errorStr: string): AshTypedError;
52
+ //#endregion
53
+ export { AshTypedError, fromJobError, isAshTypedError };
54
+ //# sourceMappingURL=ash-typed-error.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ash-typed-error.d.mts","names":[],"sources":["../../src/ai-dev-loop/ash-typed-error.ts"],"mappings":";;AAMA;;;;KAAY,aAAA;EACN,IAAA;EAAsB,SAAA;EAAmB,OAAA;EAAiB,UAAA;AAAA;EAC1D,IAAA;EAA2B,UAAA;EAAoB,OAAA;AAAA;EAC/C,IAAA;EAAsB,IAAA;EAAc,SAAA;EAAqB,OAAA;AAAA;EACzD,IAAA;EAA0B,KAAA;EAAe,QAAA;EAAkB,GAAA;EAAa,OAAA;AAAA;EACxE,IAAA;EAAwB,MAAA;EAAgB,KAAA;EAAe,IAAA;EAAc,OAAA;AAAA;EACrE,IAAA;EAAiB,IAAA;EAAc,QAAA;EAAkB,OAAA;AAAA;EACjD,IAAA;EAAoB,IAAA;EAAe,OAAA;AAAA;EACnC,IAAA;EAAsB,OAAA;EAAiB,OAAA,GAAU,MAAA;AAAA;AAAA,iBAOvC,eAAA,CAAgB,KAAA,YAAiB,KAAA,IAAS,aAAA;;;AAS1D;iBAAgB,YAAA,CAAa,QAAA,WAAmB,aAAA"}
@@ -0,0 +1,50 @@
1
+ //#region src/ai-dev-loop/ash-typed-error.ts
2
+ const VALID_KINDS = new Set([
3
+ "IntentDenied",
4
+ "CapabilityMissing",
5
+ "ToolNotFound",
6
+ "ValidationFailed",
7
+ "BudgetExceeded",
8
+ "Timeout",
9
+ "ParseError",
10
+ "RuntimeError"
11
+ ]);
12
+ function isAshTypedError(value) {
13
+ if (!value || typeof value !== "object") return false;
14
+ const obj = value;
15
+ return typeof obj.kind === "string" && VALID_KINDS.has(obj.kind) && typeof obj.message === "string";
16
+ }
17
+ /**
18
+ * Best-effort conversion from raw ASH error string → AshTypedError.
19
+ */
20
+ function fromJobError(errorStr) {
21
+ if (errorStr.startsWith("Capability denied:")) return {
22
+ kind: "CapabilityMissing",
23
+ capability: errorStr.replace("Capability denied:", "").trim(),
24
+ message: errorStr
25
+ };
26
+ if (errorStr.includes("not found") || errorStr.includes("unknown command")) return {
27
+ kind: "ToolNotFound",
28
+ name: errorStr,
29
+ available: [],
30
+ message: errorStr
31
+ };
32
+ if (errorStr.includes("timeout") || errorStr.includes("Timeout")) return {
33
+ kind: "Timeout",
34
+ step: "",
35
+ limit_ms: 0,
36
+ message: errorStr
37
+ };
38
+ if (errorStr.includes("parse") || errorStr.includes("syntax") || errorStr.includes("Unexpected")) return {
39
+ kind: "ParseError",
40
+ message: errorStr
41
+ };
42
+ return {
43
+ kind: "RuntimeError",
44
+ message: errorStr
45
+ };
46
+ }
47
+
48
+ //#endregion
49
+ export { fromJobError, isAshTypedError };
50
+ //# sourceMappingURL=ash-typed-error.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ash-typed-error.mjs","names":[],"sources":["../../src/ai-dev-loop/ash-typed-error.ts"],"sourcesContent":["/**\n * AshTypedError — Discriminated union of all ASH error types.\n *\n * Each kind carries enough structured information for AI self-repair.\n */\n\nexport type AshTypedError =\n | { kind: \"IntentDenied\"; invariant: string; message: string; suggestion?: string }\n | { kind: \"CapabilityMissing\"; capability: string; message: string }\n | { kind: \"ToolNotFound\"; name: string; available: string[]; message: string }\n | { kind: \"ValidationFailed\"; field: string; expected: string; got: string; message: string }\n | { kind: \"BudgetExceeded\"; device: string; limit: number; used: number; message: string }\n | { kind: \"Timeout\"; step: string; limit_ms: number; message: string }\n | { kind: \"ParseError\"; line?: number; message: string }\n | { kind: \"RuntimeError\"; message: string; context?: Record<string, unknown> };\n\nconst VALID_KINDS = new Set([\n \"IntentDenied\", \"CapabilityMissing\", \"ToolNotFound\", \"ValidationFailed\",\n \"BudgetExceeded\", \"Timeout\", \"ParseError\", \"RuntimeError\",\n]);\n\nexport function isAshTypedError(value: unknown): value is AshTypedError {\n if (!value || typeof value !== \"object\") return false;\n const obj = value as Record<string, unknown>;\n return typeof obj.kind === \"string\" && VALID_KINDS.has(obj.kind) && typeof obj.message === \"string\";\n}\n\n/**\n * Best-effort conversion from raw ASH error string → AshTypedError.\n */\nexport function fromJobError(errorStr: string): AshTypedError {\n if (errorStr.startsWith(\"Capability denied:\")) {\n const capability = errorStr.replace(\"Capability denied:\", \"\").trim();\n return { kind: \"CapabilityMissing\", capability, message: errorStr };\n }\n\n if (errorStr.includes(\"not found\") || errorStr.includes(\"unknown command\")) {\n return { kind: \"ToolNotFound\", name: errorStr, available: [], message: errorStr };\n }\n\n if (errorStr.includes(\"timeout\") || errorStr.includes(\"Timeout\")) {\n return { kind: \"Timeout\", step: \"\", limit_ms: 0, message: errorStr };\n }\n\n if (errorStr.includes(\"parse\") || errorStr.includes(\"syntax\") || errorStr.includes(\"Unexpected\")) {\n return { kind: \"ParseError\", message: errorStr };\n }\n\n return { kind: \"RuntimeError\", message: errorStr };\n}\n"],"mappings":";AAgBA,MAAM,cAAc,IAAI,IAAI;CAC1B;CAAgB;CAAqB;CAAgB;CACrD;CAAkB;CAAW;CAAc;CAC5C,CAAC;AAEF,SAAgB,gBAAgB,OAAwC;AACtE,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;CAChD,MAAM,MAAM;AACZ,QAAO,OAAO,IAAI,SAAS,YAAY,YAAY,IAAI,IAAI,KAAK,IAAI,OAAO,IAAI,YAAY;;;;;AAM7F,SAAgB,aAAa,UAAiC;AAC5D,KAAI,SAAS,WAAW,qBAAqB,CAE3C,QAAO;EAAE,MAAM;EAAqB,YADjB,SAAS,QAAQ,sBAAsB,GAAG,CAAC,MAAM;EACpB,SAAS;EAAU;AAGrE,KAAI,SAAS,SAAS,YAAY,IAAI,SAAS,SAAS,kBAAkB,CACxE,QAAO;EAAE,MAAM;EAAgB,MAAM;EAAU,WAAW,EAAE;EAAE,SAAS;EAAU;AAGnF,KAAI,SAAS,SAAS,UAAU,IAAI,SAAS,SAAS,UAAU,CAC9D,QAAO;EAAE,MAAM;EAAW,MAAM;EAAI,UAAU;EAAG,SAAS;EAAU;AAGtE,KAAI,SAAS,SAAS,QAAQ,IAAI,SAAS,SAAS,SAAS,IAAI,SAAS,SAAS,aAAa,CAC9F,QAAO;EAAE,MAAM;EAAc,SAAS;EAAU;AAGlD,QAAO;EAAE,MAAM;EAAgB,SAAS;EAAU"}
@@ -0,0 +1,27 @@
1
+ const require_compiler = require('../compiler.cjs');
2
+
3
+ //#region src/ai-dev-loop/ash-validate.ts
4
+ /**
5
+ * ash.validate — Static analysis for ASH scripts.
6
+ *
7
+ * Reuses existing compileSource() diagnostics to catch syntax + type errors
8
+ * without executing.
9
+ */
10
+ function ashValidate(source) {
11
+ if (source == null) throw new Error("ash.validate: source must be a string, got " + typeof source);
12
+ if (!source.trim()) return [];
13
+ const result = require_compiler.compileSource(source);
14
+ const errors = [];
15
+ for (const diag of result.diagnostics) {
16
+ if (diag.severity === "warning") continue;
17
+ errors.push({
18
+ kind: "ParseError",
19
+ line: diag.line,
20
+ message: diag.message
21
+ });
22
+ }
23
+ return errors;
24
+ }
25
+
26
+ //#endregion
27
+ exports.ashValidate = ashValidate;
@@ -0,0 +1,7 @@
1
+ import { AshTypedError } from "./ash-typed-error.cjs";
2
+
3
+ //#region src/ai-dev-loop/ash-validate.d.ts
4
+ declare function ashValidate(source: string): AshTypedError[];
5
+ //#endregion
6
+ export { ashValidate };
7
+ //# sourceMappingURL=ash-validate.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ash-validate.d.cts","names":[],"sources":["../../src/ai-dev-loop/ash-validate.ts"],"mappings":";;;iBAUgB,WAAA,CAAY,MAAA,WAAiB,aAAA"}
@@ -0,0 +1,7 @@
1
+ import { AshTypedError } from "./ash-typed-error.mjs";
2
+
3
+ //#region src/ai-dev-loop/ash-validate.d.ts
4
+ declare function ashValidate(source: string): AshTypedError[];
5
+ //#endregion
6
+ export { ashValidate };
7
+ //# sourceMappingURL=ash-validate.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ash-validate.d.mts","names":[],"sources":["../../src/ai-dev-loop/ash-validate.ts"],"mappings":";;;iBAUgB,WAAA,CAAY,MAAA,WAAiB,aAAA"}
@@ -0,0 +1,28 @@
1
+ import { compileSource } from "../compiler.mjs";
2
+
3
+ //#region src/ai-dev-loop/ash-validate.ts
4
+ /**
5
+ * ash.validate — Static analysis for ASH scripts.
6
+ *
7
+ * Reuses existing compileSource() diagnostics to catch syntax + type errors
8
+ * without executing.
9
+ */
10
+ function ashValidate(source) {
11
+ if (source == null) throw new Error("ash.validate: source must be a string, got " + typeof source);
12
+ if (!source.trim()) return [];
13
+ const result = compileSource(source);
14
+ const errors = [];
15
+ for (const diag of result.diagnostics) {
16
+ if (diag.severity === "warning") continue;
17
+ errors.push({
18
+ kind: "ParseError",
19
+ line: diag.line,
20
+ message: diag.message
21
+ });
22
+ }
23
+ return errors;
24
+ }
25
+
26
+ //#endregion
27
+ export { ashValidate };
28
+ //# sourceMappingURL=ash-validate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ash-validate.mjs","names":[],"sources":["../../src/ai-dev-loop/ash-validate.ts"],"sourcesContent":["/**\n * ash.validate — Static analysis for ASH scripts.\n *\n * Reuses existing compileSource() diagnostics to catch syntax + type errors\n * without executing.\n */\n\nimport { compileSource } from \"../compiler.js\";\nimport type { AshTypedError } from \"./ash-typed-error.js\";\n\nexport function ashValidate(source: string): AshTypedError[] {\n if (source == null) {\n throw new Error(\"ash.validate: source must be a string, got \" + typeof source);\n }\n\n if (!source.trim()) {\n return [];\n }\n\n const result = compileSource(source);\n const errors: AshTypedError[] = [];\n\n for (const diag of result.diagnostics) {\n if (diag.severity === \"warning\") continue;\n\n errors.push({\n kind: \"ParseError\",\n line: diag.line,\n message: diag.message,\n });\n }\n\n return errors;\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,YAAY,QAAiC;AAC3D,KAAI,UAAU,KACZ,OAAM,IAAI,MAAM,gDAAgD,OAAO,OAAO;AAGhF,KAAI,CAAC,OAAO,MAAM,CAChB,QAAO,EAAE;CAGX,MAAM,SAAS,cAAc,OAAO;CACpC,MAAM,SAA0B,EAAE;AAElC,MAAK,MAAM,QAAQ,OAAO,aAAa;AACrC,MAAI,KAAK,aAAa,UAAW;AAEjC,SAAO,KAAK;GACV,MAAM;GACN,MAAM,KAAK;GACX,SAAS,KAAK;GACf,CAAC;;AAGJ,QAAO"}
@@ -0,0 +1,134 @@
1
+ const require_system_prompt = require('./system-prompt.cjs');
2
+
3
+ //#region src/ai-dev-loop/dev-loop.ts
4
+ /**
5
+ * Run the AI dev loop: think → extract ASH → validate → run → observe → correct or return.
6
+ */
7
+ async function runDevLoop(config) {
8
+ const mode = config.mode ?? "dry-run";
9
+ const observations = [];
10
+ let lastFailure;
11
+ let lastScript;
12
+ for (let i = 0; i < config.max_iterations; i++) {
13
+ let thinkResult;
14
+ try {
15
+ const messages = [];
16
+ if (i === 0) {
17
+ messages.push({
18
+ role: "system",
19
+ content: require_system_prompt.buildSystemPrompt({ max_iterations: config.max_iterations })
20
+ });
21
+ messages.push({
22
+ role: "user",
23
+ content: config.intent
24
+ });
25
+ } else messages.push({
26
+ role: "user",
27
+ content: require_system_prompt.buildCorrectionPrompt(lastFailure, lastScript)
28
+ });
29
+ thinkResult = await config.think({ messages });
30
+ } catch (err) {
31
+ return {
32
+ status: "error",
33
+ iterations: i + 1,
34
+ mode,
35
+ observations,
36
+ error: err.message
37
+ };
38
+ }
39
+ const script = extractScript(thinkResult);
40
+ if (!script) {
41
+ const obs$1 = {
42
+ iteration: i + 1,
43
+ error: "empty_response"
44
+ };
45
+ observations.push(obs$1);
46
+ await config.observe(obs$1);
47
+ if (i === config.max_iterations - 1) return {
48
+ status: "error",
49
+ iterations: i + 1,
50
+ mode,
51
+ observations,
52
+ error: "LLM returned no script"
53
+ };
54
+ lastFailure = {
55
+ status: "error",
56
+ steps: [],
57
+ failedAt: {
58
+ kind: "RuntimeError",
59
+ message: "LLM returned no ASH script"
60
+ },
61
+ duration_ms: 0
62
+ };
63
+ lastScript = "";
64
+ continue;
65
+ }
66
+ lastScript = script;
67
+ const errors = await config.validate(script);
68
+ if (errors.length > 0) {
69
+ const obs$1 = {
70
+ iteration: i + 1,
71
+ script,
72
+ validation_errors: errors
73
+ };
74
+ observations.push(obs$1);
75
+ await config.observe(obs$1);
76
+ if (i === config.max_iterations - 1) return {
77
+ status: "error",
78
+ iterations: i + 1,
79
+ mode,
80
+ observations,
81
+ finalResult: {
82
+ status: "error",
83
+ steps: [],
84
+ failedAt: errors[0],
85
+ duration_ms: 0
86
+ }
87
+ };
88
+ lastFailure = {
89
+ status: "error",
90
+ steps: [],
91
+ failedAt: errors[0],
92
+ duration_ms: 0
93
+ };
94
+ continue;
95
+ }
96
+ const result = await config.runner(script);
97
+ const obs = {
98
+ iteration: i + 1,
99
+ script,
100
+ result
101
+ };
102
+ observations.push(obs);
103
+ await config.observe(obs);
104
+ if (result.status === "ok") return {
105
+ status: "ok",
106
+ iterations: i + 1,
107
+ mode,
108
+ finalResult: result,
109
+ observations
110
+ };
111
+ lastFailure = result;
112
+ }
113
+ return {
114
+ status: "error",
115
+ iterations: config.max_iterations,
116
+ mode,
117
+ finalResult: lastFailure,
118
+ observations
119
+ };
120
+ }
121
+ function extractScript(thinkResult) {
122
+ const toolCalls = thinkResult?.response?.tool_calls;
123
+ if (Array.isArray(toolCalls)) {
124
+ for (const tc of toolCalls) if (tc.name === "ash_run") try {
125
+ const args = typeof tc.arguments === "string" ? JSON.parse(tc.arguments) : tc.arguments;
126
+ if (args?.script) return args.script;
127
+ } catch {}
128
+ }
129
+ const content = thinkResult?.response?.content;
130
+ if (typeof content === "string" && content.trim()) return content.trim();
131
+ }
132
+
133
+ //#endregion
134
+ exports.runDevLoop = runDevLoop;
@@ -0,0 +1,28 @@
1
+ import { AshTypedError } from "./ash-typed-error.cjs";
2
+ import { AshRunResult } from "./ash-run-result.cjs";
3
+
4
+ //#region src/ai-dev-loop/dev-loop.d.ts
5
+ interface DevLoopConfig {
6
+ intent: string;
7
+ max_iterations: number;
8
+ mode?: "dry-run" | "live";
9
+ think: (request: any) => Promise<any>;
10
+ runner: (source: string) => Promise<AshRunResult>;
11
+ validate: (source: string) => Promise<AshTypedError[]>;
12
+ observe: (data: any) => Promise<void>;
13
+ }
14
+ interface DevLoopResult {
15
+ status: "ok" | "error";
16
+ iterations: number;
17
+ mode: "dry-run" | "live";
18
+ finalResult?: AshRunResult;
19
+ observations: any[];
20
+ error?: string;
21
+ }
22
+ /**
23
+ * Run the AI dev loop: think → extract ASH → validate → run → observe → correct or return.
24
+ */
25
+ declare function runDevLoop(config: DevLoopConfig): Promise<DevLoopResult>;
26
+ //#endregion
27
+ export { DevLoopConfig, DevLoopResult, runDevLoop };
28
+ //# sourceMappingURL=dev-loop.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-loop.d.cts","names":[],"sources":["../../src/ai-dev-loop/dev-loop.ts"],"mappings":";;;;UAaiB,aAAA;EACf,MAAA;EACA,cAAA;EACA,IAAA;EACA,KAAA,GAAQ,OAAA,UAAiB,OAAA;EACzB,MAAA,GAAS,MAAA,aAAmB,OAAA,CAAQ,YAAA;EACpC,QAAA,GAAW,MAAA,aAAmB,OAAA,CAAQ,aAAA;EACtC,OAAA,GAAU,IAAA,UAAc,OAAA;AAAA;AAAA,UAGT,aAAA;EACf,MAAA;EACA,UAAA;EACA,IAAA;EACA,WAAA,GAAc,YAAA;EACd,YAAA;EACA,KAAA;AAAA;;;;iBAMoB,UAAA,CAAW,MAAA,EAAQ,aAAA,GAAgB,OAAA,CAAQ,aAAA"}
@@ -0,0 +1,28 @@
1
+ import { AshTypedError } from "./ash-typed-error.mjs";
2
+ import { AshRunResult } from "./ash-run-result.mjs";
3
+
4
+ //#region src/ai-dev-loop/dev-loop.d.ts
5
+ interface DevLoopConfig {
6
+ intent: string;
7
+ max_iterations: number;
8
+ mode?: "dry-run" | "live";
9
+ think: (request: any) => Promise<any>;
10
+ runner: (source: string) => Promise<AshRunResult>;
11
+ validate: (source: string) => Promise<AshTypedError[]>;
12
+ observe: (data: any) => Promise<void>;
13
+ }
14
+ interface DevLoopResult {
15
+ status: "ok" | "error";
16
+ iterations: number;
17
+ mode: "dry-run" | "live";
18
+ finalResult?: AshRunResult;
19
+ observations: any[];
20
+ error?: string;
21
+ }
22
+ /**
23
+ * Run the AI dev loop: think → extract ASH → validate → run → observe → correct or return.
24
+ */
25
+ declare function runDevLoop(config: DevLoopConfig): Promise<DevLoopResult>;
26
+ //#endregion
27
+ export { DevLoopConfig, DevLoopResult, runDevLoop };
28
+ //# sourceMappingURL=dev-loop.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-loop.d.mts","names":[],"sources":["../../src/ai-dev-loop/dev-loop.ts"],"mappings":";;;;UAaiB,aAAA;EACf,MAAA;EACA,cAAA;EACA,IAAA;EACA,KAAA,GAAQ,OAAA,UAAiB,OAAA;EACzB,MAAA,GAAS,MAAA,aAAmB,OAAA,CAAQ,YAAA;EACpC,QAAA,GAAW,MAAA,aAAmB,OAAA,CAAQ,aAAA;EACtC,OAAA,GAAU,IAAA,UAAc,OAAA;AAAA;AAAA,UAGT,aAAA;EACf,MAAA;EACA,UAAA;EACA,IAAA;EACA,WAAA,GAAc,YAAA;EACd,YAAA;EACA,KAAA;AAAA;;;;iBAMoB,UAAA,CAAW,MAAA,EAAQ,aAAA,GAAgB,OAAA,CAAQ,aAAA"}