@rsconcept/rstool 0.1.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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -0
  3. package/dist/index.d.ts +15 -0
  4. package/dist/index.js +585 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/mappers/model-adapter.d.ts +27 -0
  7. package/dist/mappers/model-adapter.js +248 -0
  8. package/dist/mappers/model-adapter.js.map +1 -0
  9. package/dist/mappers/schema-adapter.d.ts +22 -0
  10. package/dist/mappers/schema-adapter.js +89 -0
  11. package/dist/mappers/schema-adapter.js.map +1 -0
  12. package/dist/mappers/types.d.ts +23 -0
  13. package/dist/mappers/types.js +22 -0
  14. package/dist/mappers/types.js.map +1 -0
  15. package/dist/models/analysis.d.ts +18 -0
  16. package/dist/models/analysis.js +1 -0
  17. package/dist/models/analysis.js.map +1 -0
  18. package/dist/models/common.d.ts +15 -0
  19. package/dist/models/common.js +12 -0
  20. package/dist/models/common.js.map +1 -0
  21. package/dist/models/constituenta.d.ts +38 -0
  22. package/dist/models/constituenta.js +1 -0
  23. package/dist/models/constituenta.js.map +1 -0
  24. package/dist/models/diagnostic.d.ts +17 -0
  25. package/dist/models/diagnostic.js +1 -0
  26. package/dist/models/diagnostic.js.map +1 -0
  27. package/dist/models/evaluation.d.ts +23 -0
  28. package/dist/models/evaluation.js +1 -0
  29. package/dist/models/evaluation.js.map +1 -0
  30. package/dist/models/index.d.ts +13 -0
  31. package/dist/models/index.js +491 -0
  32. package/dist/models/index.js.map +1 -0
  33. package/dist/models/model-value.d.ts +37 -0
  34. package/dist/models/model-value.js +1 -0
  35. package/dist/models/model-value.js.map +1 -0
  36. package/dist/models/rstool-agent.d.ts +36 -0
  37. package/dist/models/rstool-agent.js +480 -0
  38. package/dist/models/rstool-agent.js.map +1 -0
  39. package/dist/models/session.d.ts +29 -0
  40. package/dist/models/session.js +1 -0
  41. package/dist/models/session.js.map +1 -0
  42. package/dist/models/tool-contract.d.ts +33 -0
  43. package/dist/models/tool-contract.js +6 -0
  44. package/dist/models/tool-contract.js.map +1 -0
  45. package/dist/session/session-store.d.ts +26 -0
  46. package/dist/session/session-store.js +66 -0
  47. package/dist/session/session-store.js.map +1 -0
  48. package/dist/wrapper/client.d.ts +30 -0
  49. package/dist/wrapper/client.js +96 -0
  50. package/dist/wrapper/client.js.map +1 -0
  51. package/dist/wrapper/stdio-wrapper.d.ts +1 -0
  52. package/dist/wrapper/stdio-wrapper.js +679 -0
  53. package/dist/wrapper/stdio-wrapper.js.map +1 -0
  54. package/docs/CONSTITUENTA.md +55 -0
  55. package/docs/DIAGNOSTICS.md +125 -0
  56. package/docs/DOMAIN.md +89 -0
  57. package/docs/GRAMMAR-REF.md +98 -0
  58. package/docs/PORTAL-API.md +48 -0
  59. package/docs/README.md +15 -0
  60. package/docs/SYNTAX.md +139 -0
  61. package/docs/TYPIFICATION.md +79 -0
  62. package/package.json +76 -0
  63. package/skills/README.md +15 -0
  64. package/skills/rstool-helper/EXAMPLES.md +154 -0
  65. package/skills/rstool-helper/REFERENCE.md +169 -0
  66. package/skills/rstool-helper/SKILL.md +148 -0
  67. package/src/index.ts +43 -0
  68. package/src/mappers/model-adapter.ts +276 -0
  69. package/src/mappers/schema-adapter.ts +87 -0
  70. package/src/mappers/types.ts +35 -0
  71. package/src/models/analysis.ts +13 -0
  72. package/src/models/common.ts +17 -0
  73. package/src/models/constituenta.ts +35 -0
  74. package/src/models/diagnostic.ts +12 -0
  75. package/src/models/evaluation.ts +25 -0
  76. package/src/models/index.ts +33 -0
  77. package/src/models/model-value.ts +31 -0
  78. package/src/models/rstool-agent.test.ts +300 -0
  79. package/src/models/rstool-agent.ts +143 -0
  80. package/src/models/session.ts +22 -0
  81. package/src/models/tool-contract.ts +47 -0
  82. package/src/session/session-store.ts +81 -0
  83. package/src/wrapper/client.ts +116 -0
  84. package/src/wrapper/stdio-wrapper.ts +225 -0
@@ -0,0 +1,66 @@
1
+ // src/session/session-store.ts
2
+ import { randomUUID } from "crypto";
3
+ var SessionStore = class {
4
+ sessions = /* @__PURE__ */ new Map();
5
+ create(initial, contractVersion) {
6
+ const now = (/* @__PURE__ */ new Date()).toISOString();
7
+ const sessionId = initial?.sessionId ?? randomUUID();
8
+ const state = {
9
+ sessionId,
10
+ createdAt: initial?.createdAt ?? now,
11
+ updatedAt: now,
12
+ revisions: initial?.revisions ?? [],
13
+ items: initial?.items ?? [],
14
+ model: initial?.model ?? { items: [] }
15
+ };
16
+ this.sessions.set(sessionId, {
17
+ state,
18
+ diagnostics: []
19
+ });
20
+ return {
21
+ sessionId,
22
+ contractVersion: contractVersion ?? "1.0.0"
23
+ };
24
+ }
25
+ get(sessionId) {
26
+ const found = this.sessions.get(sessionId);
27
+ if (!found) {
28
+ throw new Error(`Unknown session: ${sessionId}`);
29
+ }
30
+ return found;
31
+ }
32
+ replaceState(sessionId, nextState) {
33
+ const found = this.get(sessionId);
34
+ found.state = {
35
+ ...nextState,
36
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
37
+ };
38
+ }
39
+ addRevision(sessionId, message) {
40
+ const found = this.get(sessionId);
41
+ const revision = {
42
+ revisionId: randomUUID(),
43
+ at: (/* @__PURE__ */ new Date()).toISOString(),
44
+ message
45
+ };
46
+ found.state.revisions.push(revision);
47
+ found.state.updatedAt = revision.at;
48
+ return revision;
49
+ }
50
+ appendDiagnostics(sessionId, records) {
51
+ const found = this.get(sessionId);
52
+ found.diagnostics.push(...records);
53
+ found.state.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
54
+ }
55
+ listDiagnostics(sessionId, filters) {
56
+ const found = this.get(sessionId);
57
+ if (!filters?.constituentId) {
58
+ return [...found.diagnostics];
59
+ }
60
+ return found.diagnostics.filter((record) => record.constituentId === filters.constituentId);
61
+ }
62
+ };
63
+ export {
64
+ SessionStore
65
+ };
66
+ //# sourceMappingURL=session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/session/session-store.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport {\n type DiagnosticRecord,\n type ListDiagnosticsFilters,\n type SessionHandle,\n type SessionRevision,\n type SessionState\n} from '../models';\n\ninterface SessionEnvelope {\n state: SessionState;\n diagnostics: DiagnosticRecord[];\n}\n\nexport class SessionStore {\n private sessions = new Map<string, SessionEnvelope>();\n\n public create(initial?: Partial<SessionState>, contractVersion?: string): SessionHandle {\n const now = new Date().toISOString();\n const sessionId = initial?.sessionId ?? randomUUID();\n const state: SessionState = {\n sessionId,\n createdAt: initial?.createdAt ?? now,\n updatedAt: now,\n revisions: initial?.revisions ?? [],\n items: initial?.items ?? [],\n model: initial?.model ?? { items: [] }\n };\n this.sessions.set(sessionId, {\n state,\n diagnostics: []\n });\n return {\n sessionId,\n contractVersion: contractVersion ?? '1.0.0'\n };\n }\n\n public get(sessionId: string): SessionEnvelope {\n const found = this.sessions.get(sessionId);\n if (!found) {\n throw new Error(`Unknown session: ${sessionId}`);\n }\n return found;\n }\n\n public replaceState(sessionId: string, nextState: SessionState): void {\n const found = this.get(sessionId);\n found.state = {\n ...nextState,\n updatedAt: new Date().toISOString()\n };\n }\n\n public addRevision(sessionId: string, message?: string): SessionRevision {\n const found = this.get(sessionId);\n const revision: SessionRevision = {\n revisionId: randomUUID(),\n at: new Date().toISOString(),\n message\n };\n found.state.revisions.push(revision);\n found.state.updatedAt = revision.at;\n return revision;\n }\n\n public appendDiagnostics(sessionId: string, records: DiagnosticRecord[]): void {\n const found = this.get(sessionId);\n found.diagnostics.push(...records);\n found.state.updatedAt = new Date().toISOString();\n }\n\n public listDiagnostics(sessionId: string, filters?: ListDiagnosticsFilters): DiagnosticRecord[] {\n const found = this.get(sessionId);\n if (!filters?.constituentId) {\n return [...found.diagnostics];\n }\n return found.diagnostics.filter(record => record.constituentId === filters.constituentId);\n }\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;AAepB,IAAM,eAAN,MAAmB;AAAA,EAChB,WAAW,oBAAI,IAA6B;AAAA,EAE7C,OAAO,SAAiC,iBAAyC;AACtF,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,YAAY,SAAS,aAAa,WAAW;AACnD,UAAM,QAAsB;AAAA,MAC1B;AAAA,MACA,WAAW,SAAS,aAAa;AAAA,MACjC,WAAW;AAAA,MACX,WAAW,SAAS,aAAa,CAAC;AAAA,MAClC,OAAO,SAAS,SAAS,CAAC;AAAA,MAC1B,OAAO,SAAS,SAAS,EAAE,OAAO,CAAC,EAAE;AAAA,IACvC;AACA,SAAK,SAAS,IAAI,WAAW;AAAA,MAC3B;AAAA,MACA,aAAa,CAAC;AAAA,IAChB,CAAC;AACD,WAAO;AAAA,MACL;AAAA,MACA,iBAAiB,mBAAmB;AAAA,IACtC;AAAA,EACF;AAAA,EAEO,IAAI,WAAoC;AAC7C,UAAM,QAAQ,KAAK,SAAS,IAAI,SAAS;AACzC,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,oBAAoB,SAAS,EAAE;AAAA,IACjD;AACA,WAAO;AAAA,EACT;AAAA,EAEO,aAAa,WAAmB,WAA+B;AACpE,UAAM,QAAQ,KAAK,IAAI,SAAS;AAChC,UAAM,QAAQ;AAAA,MACZ,GAAG;AAAA,MACH,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AAAA,EACF;AAAA,EAEO,YAAY,WAAmB,SAAmC;AACvE,UAAM,QAAQ,KAAK,IAAI,SAAS;AAChC,UAAM,WAA4B;AAAA,MAChC,YAAY,WAAW;AAAA,MACvB,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC3B;AAAA,IACF;AACA,UAAM,MAAM,UAAU,KAAK,QAAQ;AACnC,UAAM,MAAM,YAAY,SAAS;AACjC,WAAO;AAAA,EACT;AAAA,EAEO,kBAAkB,WAAmB,SAAmC;AAC7E,UAAM,QAAQ,KAAK,IAAI,SAAS;AAChC,UAAM,YAAY,KAAK,GAAG,OAAO;AACjC,UAAM,MAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,EACjD;AAAA,EAEO,gBAAgB,WAAmB,SAAsD;AAC9F,UAAM,QAAQ,KAAK,IAAI,SAAS;AAChC,QAAI,CAAC,SAAS,eAAe;AAC3B,aAAO,CAAC,GAAG,MAAM,WAAW;AAAA,IAC9B;AACA,WAAO,MAAM,YAAY,OAAO,YAAU,OAAO,kBAAkB,QAAQ,aAAa;AAAA,EAC1F;AACF;","names":[]}
@@ -0,0 +1,30 @@
1
+ interface WrapperResponse<T = unknown> {
2
+ id: string | number | null;
3
+ ok: boolean;
4
+ result?: T;
5
+ error?: {
6
+ code: string;
7
+ message: string;
8
+ details?: unknown;
9
+ };
10
+ }
11
+ interface RSToolWrapperClientOptions {
12
+ command?: string;
13
+ args?: string[];
14
+ cwd?: string;
15
+ shell?: boolean;
16
+ }
17
+ declare class RSToolWrapperClient {
18
+ private process;
19
+ private input;
20
+ private pending;
21
+ private requestCounter;
22
+ constructor(options?: RSToolWrapperClientOptions);
23
+ waitUntilReady(): Promise<void>;
24
+ call<T>(method: string, params?: unknown): Promise<T>;
25
+ close(): Promise<void>;
26
+ private readOneEvent;
27
+ private handleLine;
28
+ }
29
+
30
+ export { RSToolWrapperClient, type RSToolWrapperClientOptions, type WrapperResponse };
@@ -0,0 +1,96 @@
1
+ // src/wrapper/client.ts
2
+ import { spawn } from "child_process";
3
+ import readline from "readline";
4
+ var RSToolWrapperClient = class {
5
+ process;
6
+ input;
7
+ pending = /* @__PURE__ */ new Map();
8
+ requestCounter = 1;
9
+ constructor(options = {}) {
10
+ this.process = spawn(options.command ?? "npm", options.args ?? ["run", "wrapper"], {
11
+ cwd: options.cwd ?? process.cwd(),
12
+ shell: options.shell ?? true,
13
+ stdio: ["pipe", "pipe", "inherit"]
14
+ });
15
+ this.input = readline.createInterface({
16
+ input: this.process.stdout,
17
+ crlfDelay: Infinity
18
+ });
19
+ this.input.on("line", (line) => this.handleLine(line));
20
+ }
21
+ async waitUntilReady() {
22
+ for (; ; ) {
23
+ const line = await this.readOneEvent();
24
+ let response = null;
25
+ try {
26
+ response = JSON.parse(line);
27
+ } catch {
28
+ continue;
29
+ }
30
+ if (response.ok && response.result?.ready) {
31
+ return;
32
+ }
33
+ }
34
+ }
35
+ async call(method, params = {}) {
36
+ const id = String(this.requestCounter++);
37
+ const payload = JSON.stringify({ id, method, params });
38
+ const responsePromise = new Promise((resolve) => {
39
+ this.pending.set(id, resolve);
40
+ });
41
+ this.process.stdin.write(`${payload}
42
+ `);
43
+ const response = await responsePromise;
44
+ if (!response.ok) {
45
+ throw new Error(`${response.error?.code ?? "UNKNOWN"}: ${response.error?.message ?? "Request failed"}`);
46
+ }
47
+ return response.result;
48
+ }
49
+ async close() {
50
+ this.input.close();
51
+ this.process.stdin.end();
52
+ if (!this.process.killed) {
53
+ this.process.kill();
54
+ }
55
+ }
56
+ async readOneEvent() {
57
+ return new Promise((resolve, reject) => {
58
+ const onLine = (line) => {
59
+ cleanup();
60
+ resolve(line);
61
+ };
62
+ const onExit = () => {
63
+ cleanup();
64
+ reject(new Error("Wrapper exited before ready"));
65
+ };
66
+ const cleanup = () => {
67
+ this.input.off("line", onLine);
68
+ this.process.off("exit", onExit);
69
+ };
70
+ this.input.on("line", onLine);
71
+ this.process.on("exit", onExit);
72
+ });
73
+ }
74
+ handleLine(line) {
75
+ let parsed;
76
+ try {
77
+ parsed = JSON.parse(line);
78
+ } catch {
79
+ return;
80
+ }
81
+ if (parsed.id === null || parsed.id === void 0) {
82
+ return;
83
+ }
84
+ const id = String(parsed.id);
85
+ const resolver = this.pending.get(id);
86
+ if (!resolver) {
87
+ return;
88
+ }
89
+ this.pending.delete(id);
90
+ resolver(parsed);
91
+ }
92
+ };
93
+ export {
94
+ RSToolWrapperClient
95
+ };
96
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/wrapper/client.ts"],"sourcesContent":["import { spawn, type ChildProcessByStdio } from 'node:child_process';\nimport readline from 'node:readline';\nimport { type Readable, type Writable } from 'node:stream';\n\nexport interface WrapperResponse<T = unknown> {\n id: string | number | null;\n ok: boolean;\n result?: T;\n error?: {\n code: string;\n message: string;\n details?: unknown;\n };\n}\n\nexport interface RSToolWrapperClientOptions {\n command?: string;\n args?: string[];\n cwd?: string;\n shell?: boolean;\n}\n\nexport class RSToolWrapperClient {\n private process: ChildProcessByStdio<Writable, Readable, null>;\n private input: readline.Interface;\n private pending = new Map<string, (value: WrapperResponse) => void>();\n private requestCounter = 1;\n\n public constructor(options: RSToolWrapperClientOptions = {}) {\n this.process = spawn(options.command ?? 'npm', options.args ?? ['run', 'wrapper'], {\n cwd: options.cwd ?? process.cwd(),\n shell: options.shell ?? true,\n stdio: ['pipe', 'pipe', 'inherit']\n });\n this.input = readline.createInterface({\n input: this.process.stdout,\n crlfDelay: Infinity\n });\n this.input.on('line', line => this.handleLine(line));\n }\n\n public async waitUntilReady(): Promise<void> {\n for (;;) {\n const line = await this.readOneEvent();\n let response: WrapperResponse<{ ready: boolean }> | null = null;\n try {\n response = JSON.parse(line) as WrapperResponse<{ ready: boolean }>;\n } catch {\n continue;\n }\n if (response.ok && response.result?.ready) {\n return;\n }\n }\n }\n\n public async call<T>(method: string, params: unknown = {}): Promise<T> {\n const id = String(this.requestCounter++);\n const payload = JSON.stringify({ id, method, params });\n const responsePromise = new Promise<WrapperResponse>(resolve => {\n this.pending.set(id, resolve);\n });\n this.process.stdin.write(`${payload}\\n`);\n const response = await responsePromise;\n if (!response.ok) {\n throw new Error(`${response.error?.code ?? 'UNKNOWN'}: ${response.error?.message ?? 'Request failed'}`);\n }\n return response.result as T;\n }\n\n public async close(): Promise<void> {\n this.input.close();\n this.process.stdin.end();\n if (!this.process.killed) {\n this.process.kill();\n }\n }\n\n private async readOneEvent(): Promise<string> {\n return new Promise((resolve, reject) => {\n const onLine = (line: string) => {\n cleanup();\n resolve(line);\n };\n const onExit = () => {\n cleanup();\n reject(new Error('Wrapper exited before ready'));\n };\n const cleanup = () => {\n this.input.off('line', onLine);\n this.process.off('exit', onExit);\n };\n this.input.on('line', onLine);\n this.process.on('exit', onExit);\n });\n }\n\n private handleLine(line: string): void {\n let parsed: WrapperResponse;\n try {\n parsed = JSON.parse(line) as WrapperResponse;\n } catch {\n return;\n }\n if (parsed.id === null || parsed.id === undefined) {\n return;\n }\n const id = String(parsed.id);\n const resolver = this.pending.get(id);\n if (!resolver) {\n return;\n }\n this.pending.delete(id);\n resolver(parsed);\n }\n}\n"],"mappings":";AAAA,SAAS,aAAuC;AAChD,OAAO,cAAc;AAqBd,IAAM,sBAAN,MAA0B;AAAA,EACvB;AAAA,EACA;AAAA,EACA,UAAU,oBAAI,IAA8C;AAAA,EAC5D,iBAAiB;AAAA,EAElB,YAAY,UAAsC,CAAC,GAAG;AAC3D,SAAK,UAAU,MAAM,QAAQ,WAAW,OAAO,QAAQ,QAAQ,CAAC,OAAO,SAAS,GAAG;AAAA,MACjF,KAAK,QAAQ,OAAO,QAAQ,IAAI;AAAA,MAChC,OAAO,QAAQ,SAAS;AAAA,MACxB,OAAO,CAAC,QAAQ,QAAQ,SAAS;AAAA,IACnC,CAAC;AACD,SAAK,QAAQ,SAAS,gBAAgB;AAAA,MACpC,OAAO,KAAK,QAAQ;AAAA,MACpB,WAAW;AAAA,IACb,CAAC;AACD,SAAK,MAAM,GAAG,QAAQ,UAAQ,KAAK,WAAW,IAAI,CAAC;AAAA,EACrD;AAAA,EAEA,MAAa,iBAAgC;AAC3C,eAAS;AACP,YAAM,OAAO,MAAM,KAAK,aAAa;AACrC,UAAI,WAAuD;AAC3D,UAAI;AACF,mBAAW,KAAK,MAAM,IAAI;AAAA,MAC5B,QAAQ;AACN;AAAA,MACF;AACA,UAAI,SAAS,MAAM,SAAS,QAAQ,OAAO;AACzC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAa,KAAQ,QAAgB,SAAkB,CAAC,GAAe;AACrE,UAAM,KAAK,OAAO,KAAK,gBAAgB;AACvC,UAAM,UAAU,KAAK,UAAU,EAAE,IAAI,QAAQ,OAAO,CAAC;AACrD,UAAM,kBAAkB,IAAI,QAAyB,aAAW;AAC9D,WAAK,QAAQ,IAAI,IAAI,OAAO;AAAA,IAC9B,CAAC;AACD,SAAK,QAAQ,MAAM,MAAM,GAAG,OAAO;AAAA,CAAI;AACvC,UAAM,WAAW,MAAM;AACvB,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,GAAG,SAAS,OAAO,QAAQ,SAAS,KAAK,SAAS,OAAO,WAAW,gBAAgB,EAAE;AAAA,IACxG;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAa,QAAuB;AAClC,SAAK,MAAM,MAAM;AACjB,SAAK,QAAQ,MAAM,IAAI;AACvB,QAAI,CAAC,KAAK,QAAQ,QAAQ;AACxB,WAAK,QAAQ,KAAK;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAc,eAAgC;AAC5C,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,SAAS,CAAC,SAAiB;AAC/B,gBAAQ;AACR,gBAAQ,IAAI;AAAA,MACd;AACA,YAAM,SAAS,MAAM;AACnB,gBAAQ;AACR,eAAO,IAAI,MAAM,6BAA6B,CAAC;AAAA,MACjD;AACA,YAAM,UAAU,MAAM;AACpB,aAAK,MAAM,IAAI,QAAQ,MAAM;AAC7B,aAAK,QAAQ,IAAI,QAAQ,MAAM;AAAA,MACjC;AACA,WAAK,MAAM,GAAG,QAAQ,MAAM;AAC5B,WAAK,QAAQ,GAAG,QAAQ,MAAM;AAAA,IAChC,CAAC;AAAA,EACH;AAAA,EAEQ,WAAW,MAAoB;AACrC,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,IAAI;AAAA,IAC1B,QAAQ;AACN;AAAA,IACF;AACA,QAAI,OAAO,OAAO,QAAQ,OAAO,OAAO,QAAW;AACjD;AAAA,IACF;AACA,UAAM,KAAK,OAAO,OAAO,EAAE;AAC3B,UAAM,WAAW,KAAK,QAAQ,IAAI,EAAE;AACpC,QAAI,CAAC,UAAU;AACb;AAAA,IACF;AACA,SAAK,QAAQ,OAAO,EAAE;AACtB,aAAS,MAAM;AAAA,EACjB;AACF;","names":[]}
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node