nativeapptemplate-agent 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.
- package/CLAUDE.md +137 -0
- package/LICENSE +21 -0
- package/README.md +192 -0
- package/dist/adb.d.ts +2 -0
- package/dist/adb.d.ts.map +1 -0
- package/dist/adb.js +31 -0
- package/dist/adb.js.map +1 -0
- package/dist/agents/contract-extract.d.ts +26 -0
- package/dist/agents/contract-extract.d.ts.map +1 -0
- package/dist/agents/contract-extract.js +205 -0
- package/dist/agents/contract-extract.js.map +1 -0
- package/dist/agents/judge.d.ts +21 -0
- package/dist/agents/judge.d.ts.map +1 -0
- package/dist/agents/judge.js +119 -0
- package/dist/agents/judge.js.map +1 -0
- package/dist/agents/planner.d.ts +3 -0
- package/dist/agents/planner.d.ts.map +1 -0
- package/dist/agents/planner.js +154 -0
- package/dist/agents/planner.js.map +1 -0
- package/dist/agents/reviewer.d.ts +9 -0
- package/dist/agents/reviewer.d.ts.map +1 -0
- package/dist/agents/reviewer.js +108 -0
- package/dist/agents/reviewer.js.map +1 -0
- package/dist/agents/types.d.ts +54 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/agents/workers/android.d.ts +3 -0
- package/dist/agents/workers/android.d.ts.map +1 -0
- package/dist/agents/workers/android.js +116 -0
- package/dist/agents/workers/android.js.map +1 -0
- package/dist/agents/workers/ios.d.ts +3 -0
- package/dist/agents/workers/ios.d.ts.map +1 -0
- package/dist/agents/workers/ios.js +110 -0
- package/dist/agents/workers/ios.js.map +1 -0
- package/dist/agents/workers/rails.d.ts +3 -0
- package/dist/agents/workers/rails.d.ts.map +1 -0
- package/dist/agents/workers/rails.js +145 -0
- package/dist/agents/workers/rails.js.map +1 -0
- package/dist/dispatch.d.ts +3 -0
- package/dist/dispatch.d.ts.map +1 -0
- package/dist/dispatch.js +38 -0
- package/dist/dispatch.js.map +1 -0
- package/dist/env.d.ts +3 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +48 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/ruby.d.ts +2 -0
- package/dist/ruby.d.ts.map +1 -0
- package/dist/ruby.js +21 -0
- package/dist/ruby.js.map +1 -0
- package/dist/slug.d.ts +3 -0
- package/dist/slug.d.ts.map +1 -0
- package/dist/slug.js +11 -0
- package/dist/slug.js.map +1 -0
- package/dist/stub.d.ts +3 -0
- package/dist/stub.d.ts.map +1 -0
- package/dist/stub.js +6 -0
- package/dist/stub.js.map +1 -0
- package/dist/trace.d.ts +3 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +13 -0
- package/dist/trace.js.map +1 -0
- package/dist/validation/capture.d.ts +15 -0
- package/dist/validation/capture.d.ts.map +1 -0
- package/dist/validation/capture.js +141 -0
- package/dist/validation/capture.js.map +1 -0
- package/dist/validation/discover.d.ts +11 -0
- package/dist/validation/discover.d.ts.map +1 -0
- package/dist/validation/discover.js +113 -0
- package/dist/validation/discover.js.map +1 -0
- package/dist/validation/index.d.ts +17 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +9 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/launch.d.ts +21 -0
- package/dist/validation/launch.d.ts.map +1 -0
- package/dist/validation/launch.js +109 -0
- package/dist/validation/launch.js.map +1 -0
- package/dist/validation/layer1.d.ts +16 -0
- package/dist/validation/layer1.d.ts.map +1 -0
- package/dist/validation/layer1.js +98 -0
- package/dist/validation/layer1.js.map +1 -0
- package/dist/validation/layer2.d.ts +17 -0
- package/dist/validation/layer2.d.ts.map +1 -0
- package/dist/validation/layer2.js +168 -0
- package/dist/validation/layer2.js.map +1 -0
- package/dist/validation/layer3.d.ts +22 -0
- package/dist/validation/layer3.d.ts.map +1 -0
- package/dist/validation/layer3.js +96 -0
- package/dist/validation/layer3.js.map +1 -0
- package/dist/validation/stage1.d.ts +17 -0
- package/dist/validation/stage1.d.ts.map +1 -0
- package/dist/validation/stage1.js +71 -0
- package/dist/validation/stage1.js.map +1 -0
- package/dist/validation/visual-judge.d.ts +25 -0
- package/dist/validation/visual-judge.d.ts.map +1 -0
- package/dist/validation/visual-judge.js +89 -0
- package/dist/validation/visual-judge.js.map +1 -0
- package/package.json +69 -0
- package/scripts/ruby/.gitkeep +0 -0
- package/scripts/ruby/rename.rb +221 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { cp, lstat, mkdir, rm, stat } from "node:fs/promises";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { scrubbedEnv } from "../../env.js";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { trace } from "../../trace.js";
|
|
6
|
+
import { isStub } from "../../stub.js";
|
|
7
|
+
import { runRuby } from "../../ruby.js";
|
|
8
|
+
import { slugToPascal } from "../../slug.js";
|
|
9
|
+
const SKIP_SEGMENTS = new Set([
|
|
10
|
+
".git",
|
|
11
|
+
".claude",
|
|
12
|
+
"build",
|
|
13
|
+
".gradle",
|
|
14
|
+
".idea",
|
|
15
|
+
".kotlin",
|
|
16
|
+
"captures",
|
|
17
|
+
"node_modules",
|
|
18
|
+
]);
|
|
19
|
+
export async function runAndroidWorker(domain) {
|
|
20
|
+
if (isStub("android")) {
|
|
21
|
+
return runStubAndroidWorker(domain);
|
|
22
|
+
}
|
|
23
|
+
const substrate = process.env['NATIVEAPPTEMPLATE_ANDROID'];
|
|
24
|
+
if (!substrate) {
|
|
25
|
+
throw new Error("android worker: NATIVEAPPTEMPLATE_ANDROID env var is not set; see CLAUDE.md Substrate section");
|
|
26
|
+
}
|
|
27
|
+
const outDir = resolve(process.cwd(), "out", domain.slug, "android");
|
|
28
|
+
trace("android", `copying substrate from ${substrate} to ${outDir}`);
|
|
29
|
+
await prepareFresh(outDir);
|
|
30
|
+
await copyFiltered(substrate, outDir);
|
|
31
|
+
const productPairs = buildProductRenamePairs(domain.slug);
|
|
32
|
+
const renamePlan = [...productPairs, ...domain.renamePlan].filter((p) => p.from !== p.to);
|
|
33
|
+
const plan = renamePlan.map((p) => `${p.from}->${p.to}`).join(", ");
|
|
34
|
+
trace("android", `running scripts/ruby/rename.rb: ${plan}`);
|
|
35
|
+
const renameStats = await runRuby("rename.rb", { renamePlan, root: outDir });
|
|
36
|
+
trace("android", `scanned ${renameStats.files_scanned} files, changed ${renameStats.files_changed}, ${renameStats.substitutions} substitutions, ${renameStats.files_renamed} file/dir renames`);
|
|
37
|
+
await initGit(outDir);
|
|
38
|
+
trace("android", `done (out/${domain.slug}/android)`);
|
|
39
|
+
return {
|
|
40
|
+
platform: "android",
|
|
41
|
+
outDir: `./out/${domain.slug}/android`,
|
|
42
|
+
filesTouched: renameStats.files_changed + renameStats.files_renamed,
|
|
43
|
+
renamedFrom: renamePlan.map((p) => p.from),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function buildProductRenamePairs(slug) {
|
|
47
|
+
const pascal = slugToPascal(slug);
|
|
48
|
+
return [
|
|
49
|
+
{ from: "NativeAppTemplateFree", to: `${pascal}App` },
|
|
50
|
+
{ from: "NativeAppTemplate", to: pascal },
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
async function prepareFresh(dir) {
|
|
54
|
+
try {
|
|
55
|
+
await stat(dir);
|
|
56
|
+
await rm(dir, { recursive: true, force: true });
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// dest doesn't exist
|
|
60
|
+
}
|
|
61
|
+
await mkdir(dir, { recursive: true });
|
|
62
|
+
}
|
|
63
|
+
async function copyFiltered(src, dest) {
|
|
64
|
+
await cp(src, dest, {
|
|
65
|
+
recursive: true,
|
|
66
|
+
force: true,
|
|
67
|
+
filter: async (source) => {
|
|
68
|
+
const rel = source.slice(src.length);
|
|
69
|
+
const segments = rel.split("/").filter(Boolean);
|
|
70
|
+
if (segments.some((seg) => SKIP_SEGMENTS.has(seg)))
|
|
71
|
+
return false;
|
|
72
|
+
try {
|
|
73
|
+
const s = await lstat(source);
|
|
74
|
+
if (s.isSocket() || s.isFIFO() || s.isBlockDevice() || s.isCharacterDevice())
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async function initGit(dir) {
|
|
85
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
86
|
+
const child = spawn("git", ["init", "-q", "-b", "main"], { cwd: dir, env: scrubbedEnv() });
|
|
87
|
+
child.on("close", (code) => {
|
|
88
|
+
if (code === 0)
|
|
89
|
+
resolvePromise();
|
|
90
|
+
else
|
|
91
|
+
rejectPromise(new Error(`git init exited ${code}`));
|
|
92
|
+
});
|
|
93
|
+
child.on("error", rejectPromise);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const delay = (ms) => new Promise((r) => { setTimeout(r, ms); });
|
|
97
|
+
async function runStubAndroidWorker(domain) {
|
|
98
|
+
const plan = domain.renamePlan.map((p) => `${p.from}->${p.to}`).join(", ");
|
|
99
|
+
trace("android", "(stub mode)");
|
|
100
|
+
trace("android", `copying Jetpack Compose substrate for ${domain.displayName}`);
|
|
101
|
+
await delay(200);
|
|
102
|
+
trace("android", `renaming Kotlin symbols: ${plan}`);
|
|
103
|
+
await delay(300);
|
|
104
|
+
trace("android", "regenerating data classes + Hilt modules");
|
|
105
|
+
await delay(250);
|
|
106
|
+
trace("android", "updating res/values/strings.xml");
|
|
107
|
+
await delay(200);
|
|
108
|
+
trace("android", `done (out/${domain.slug}/android)`);
|
|
109
|
+
return {
|
|
110
|
+
platform: "android",
|
|
111
|
+
outDir: `./out/${domain.slug}/android`,
|
|
112
|
+
filesTouched: 81,
|
|
113
|
+
renamedFrom: domain.renamePlan.map((p) => p.from),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=android.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"android.js","sourceRoot":"","sources":["../../../src/agents/workers/android.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ios.d.ts","sourceRoot":"","sources":["../../../src/agents/workers/ios.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAc,YAAY,EAAE,MAAM,aAAa,CAAC;AAYxE,wBAAsB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAwC5E"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { cp, lstat, mkdir, rm, stat } from "node:fs/promises";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { scrubbedEnv } from "../../env.js";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { trace } from "../../trace.js";
|
|
6
|
+
import { isStub } from "../../stub.js";
|
|
7
|
+
import { runRuby } from "../../ruby.js";
|
|
8
|
+
import { slugToPascal } from "../../slug.js";
|
|
9
|
+
const SKIP_RELATIVE_PATHS = ["/.git", "/.claude", "/DerivedData", "/.build", "/Pods", "/Carthage"];
|
|
10
|
+
const SKIP_DIR_NAMES = new Set(["xcuserdata"]);
|
|
11
|
+
export async function runIosWorker(domain) {
|
|
12
|
+
if (isStub("ios")) {
|
|
13
|
+
return runStubIosWorker(domain);
|
|
14
|
+
}
|
|
15
|
+
const substrate = process.env['NATIVEAPPTEMPLATE_IOS'];
|
|
16
|
+
if (!substrate) {
|
|
17
|
+
throw new Error("ios worker: NATIVEAPPTEMPLATE_IOS env var is not set; see CLAUDE.md Substrate section");
|
|
18
|
+
}
|
|
19
|
+
const outDir = resolve(process.cwd(), "out", domain.slug, "ios");
|
|
20
|
+
trace("ios", `copying substrate from ${substrate} to ${outDir}`);
|
|
21
|
+
await prepareFresh(outDir);
|
|
22
|
+
await copyFiltered(substrate, outDir);
|
|
23
|
+
const productPairs = buildProductRenamePairs(domain.slug);
|
|
24
|
+
const renamePlan = [...productPairs, ...domain.renamePlan].filter((p) => p.from !== p.to);
|
|
25
|
+
const plan = renamePlan.map((p) => `${p.from}->${p.to}`).join(", ");
|
|
26
|
+
trace("ios", `running scripts/ruby/rename.rb: ${plan}`);
|
|
27
|
+
const renameStats = await runRuby("rename.rb", { renamePlan, root: outDir });
|
|
28
|
+
trace("ios", `scanned ${renameStats.files_scanned} files, changed ${renameStats.files_changed}, ${renameStats.substitutions} substitutions, ${renameStats.files_renamed} file/dir renames`);
|
|
29
|
+
await initGit(outDir);
|
|
30
|
+
trace("ios", `done (out/${domain.slug}/ios)`);
|
|
31
|
+
return {
|
|
32
|
+
platform: "ios",
|
|
33
|
+
outDir: `./out/${domain.slug}/ios`,
|
|
34
|
+
filesTouched: renameStats.files_changed + renameStats.files_renamed,
|
|
35
|
+
renamedFrom: renamePlan.map((p) => p.from),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function buildProductRenamePairs(slug) {
|
|
39
|
+
const pascal = slugToPascal(slug);
|
|
40
|
+
return [
|
|
41
|
+
{ from: "NativeAppTemplateFree", to: `${pascal}App` },
|
|
42
|
+
{ from: "NativeAppTemplate", to: pascal },
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
async function prepareFresh(dir) {
|
|
46
|
+
try {
|
|
47
|
+
await stat(dir);
|
|
48
|
+
await rm(dir, { recursive: true, force: true });
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// dest doesn't exist
|
|
52
|
+
}
|
|
53
|
+
await mkdir(dir, { recursive: true });
|
|
54
|
+
}
|
|
55
|
+
async function copyFiltered(src, dest) {
|
|
56
|
+
await cp(src, dest, {
|
|
57
|
+
recursive: true,
|
|
58
|
+
force: true,
|
|
59
|
+
filter: async (source) => {
|
|
60
|
+
const rel = source.slice(src.length);
|
|
61
|
+
if (SKIP_RELATIVE_PATHS.some((p) => rel === p || rel.startsWith(`${p}/`)))
|
|
62
|
+
return false;
|
|
63
|
+
const segments = rel.split("/").filter(Boolean);
|
|
64
|
+
if (segments.some((seg) => SKIP_DIR_NAMES.has(seg)))
|
|
65
|
+
return false;
|
|
66
|
+
try {
|
|
67
|
+
const s = await lstat(source);
|
|
68
|
+
if (s.isSocket() || s.isFIFO() || s.isBlockDevice() || s.isCharacterDevice())
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async function initGit(dir) {
|
|
79
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
80
|
+
const child = spawn("git", ["init", "-q", "-b", "main"], { cwd: dir, env: scrubbedEnv() });
|
|
81
|
+
child.on("close", (code) => {
|
|
82
|
+
if (code === 0)
|
|
83
|
+
resolvePromise();
|
|
84
|
+
else
|
|
85
|
+
rejectPromise(new Error(`git init exited ${code}`));
|
|
86
|
+
});
|
|
87
|
+
child.on("error", rejectPromise);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const delay = (ms) => new Promise((r) => { setTimeout(r, ms); });
|
|
91
|
+
async function runStubIosWorker(domain) {
|
|
92
|
+
const plan = domain.renamePlan.map((p) => `${p.from}->${p.to}`).join(", ");
|
|
93
|
+
trace("ios", "(stub mode)");
|
|
94
|
+
trace("ios", `copying SwiftUI substrate for ${domain.displayName}`);
|
|
95
|
+
await delay(200);
|
|
96
|
+
trace("ios", `renaming Swift symbols: ${plan}`);
|
|
97
|
+
await delay(300);
|
|
98
|
+
trace("ios", "regenerating @Observable view models");
|
|
99
|
+
await delay(250);
|
|
100
|
+
trace("ios", "updating Localizable.strings");
|
|
101
|
+
await delay(200);
|
|
102
|
+
trace("ios", `done (out/${domain.slug}/ios)`);
|
|
103
|
+
return {
|
|
104
|
+
platform: "ios",
|
|
105
|
+
outDir: `./out/${domain.slug}/ios`,
|
|
106
|
+
filesTouched: 63,
|
|
107
|
+
renamedFrom: domain.renamePlan.map((p) => p.from),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=ios.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ios.js","sourceRoot":"","sources":["../../../src/agents/workers/ios.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rails.d.ts","sourceRoot":"","sources":["../../../src/agents/workers/rails.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAc,YAAY,EAAE,MAAM,aAAa,CAAC;AAWxE,wBAAsB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAyC9E"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { cp, lstat, mkdir, rm, stat } from "node:fs/promises";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { scrubbedEnv } from "../../env.js";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { trace } from "../../trace.js";
|
|
6
|
+
import { isStub } from "../../stub.js";
|
|
7
|
+
import { runRuby } from "../../ruby.js";
|
|
8
|
+
import { slugToPascal, slugToSnake } from "../../slug.js";
|
|
9
|
+
const SKIP_RELATIVE_PATHS = ["/.git", "/.claude", "/node_modules", "/tmp", "/log", "/vendor/bundle"];
|
|
10
|
+
export async function runRailsWorker(domain) {
|
|
11
|
+
if (isStub("rails")) {
|
|
12
|
+
return runStubRailsWorker(domain);
|
|
13
|
+
}
|
|
14
|
+
const substrate = process.env['NATIVEAPPTEMPLATE_API'];
|
|
15
|
+
if (!substrate) {
|
|
16
|
+
throw new Error("rails worker: NATIVEAPPTEMPLATE_API env var is not set; see CLAUDE.md Substrate section");
|
|
17
|
+
}
|
|
18
|
+
const outDir = resolve(process.cwd(), "out", domain.slug, "rails");
|
|
19
|
+
trace("rails", `copying substrate from ${substrate} to ${outDir}`);
|
|
20
|
+
await prepareFresh(outDir);
|
|
21
|
+
await copyFiltered(substrate, outDir);
|
|
22
|
+
const productPairs = buildProductRenamePairs(domain.slug);
|
|
23
|
+
const renamePlan = [...productPairs, ...domain.renamePlan].filter((p) => p.from !== p.to);
|
|
24
|
+
const plan = renamePlan.map((p) => `${p.from}->${p.to}`).join(", ");
|
|
25
|
+
trace("rails", `running scripts/ruby/rename.rb: ${plan}`);
|
|
26
|
+
const renameStats = await runRuby("rename.rb", { renamePlan, root: outDir });
|
|
27
|
+
trace("rails", `scanned ${renameStats.files_scanned} files, changed ${renameStats.files_changed}, ${renameStats.substitutions} substitutions, ${renameStats.files_renamed} file/dir renames`);
|
|
28
|
+
await dropSlugDatabases(domain.slug);
|
|
29
|
+
await initGit(outDir);
|
|
30
|
+
trace("rails", `done (out/${domain.slug}/rails)`);
|
|
31
|
+
return {
|
|
32
|
+
platform: "rails",
|
|
33
|
+
outDir: `./out/${domain.slug}/rails`,
|
|
34
|
+
filesTouched: renameStats.files_changed + renameStats.files_renamed,
|
|
35
|
+
renamedFrom: renamePlan.map((p) => p.from),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function buildProductRenamePairs(slug) {
|
|
39
|
+
const pascal = slugToPascal(slug);
|
|
40
|
+
return [
|
|
41
|
+
{ from: "Nativeapptemplateapi", to: `${pascal}Api` },
|
|
42
|
+
{ from: "NativeAppTemplate", to: pascal },
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
async function prepareFresh(dir) {
|
|
46
|
+
try {
|
|
47
|
+
await stat(dir);
|
|
48
|
+
await rm(dir, { recursive: true, force: true });
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// dest doesn't exist — nothing to clean
|
|
52
|
+
}
|
|
53
|
+
await mkdir(dir, { recursive: true });
|
|
54
|
+
}
|
|
55
|
+
async function copyFiltered(src, dest) {
|
|
56
|
+
await cp(src, dest, {
|
|
57
|
+
recursive: true,
|
|
58
|
+
force: true,
|
|
59
|
+
filter: async (source) => {
|
|
60
|
+
const rel = source.slice(src.length);
|
|
61
|
+
if (SKIP_RELATIVE_PATHS.some((p) => rel === p || rel.startsWith(`${p}/`)))
|
|
62
|
+
return false;
|
|
63
|
+
try {
|
|
64
|
+
const s = await lstat(source);
|
|
65
|
+
if (s.isSocket() || s.isFIFO() || s.isBlockDevice() || s.isCharacterDevice())
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async function dropSlugDatabases(slug) {
|
|
76
|
+
const prefix = `${slugToSnake(slug)}_api`;
|
|
77
|
+
const names = await listDatabasesStartingWith(prefix);
|
|
78
|
+
if (names.length === 0) {
|
|
79
|
+
trace("rails", `no stale ${prefix}* databases to drop`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
for (const name of names) {
|
|
83
|
+
await execPsql(["-c", `DROP DATABASE IF EXISTS "${name}";`]);
|
|
84
|
+
}
|
|
85
|
+
trace("rails", `dropped ${names.length} stale slug-scoped database(s): ${names.join(", ")}`);
|
|
86
|
+
}
|
|
87
|
+
async function listDatabasesStartingWith(prefix) {
|
|
88
|
+
try {
|
|
89
|
+
const stdout = await execPsql(["-tAc", `SELECT datname FROM pg_database WHERE datname LIKE '${prefix}%' ORDER BY datname;`]);
|
|
90
|
+
return stdout.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
trace("rails", "psql unavailable or refused connection — skipping stale-DB cleanup");
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function execPsql(args) {
|
|
98
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
99
|
+
const child = spawn("psql", ["-h", "localhost", "-d", "postgres", ...args], { env: scrubbedEnv() });
|
|
100
|
+
const stdoutChunks = [];
|
|
101
|
+
const stderrChunks = [];
|
|
102
|
+
child.stdout.on("data", (c) => stdoutChunks.push(c));
|
|
103
|
+
child.stderr.on("data", (c) => stderrChunks.push(c));
|
|
104
|
+
child.on("close", (code) => {
|
|
105
|
+
if (code === 0)
|
|
106
|
+
resolvePromise(Buffer.concat(stdoutChunks).toString("utf8"));
|
|
107
|
+
else
|
|
108
|
+
rejectPromise(new Error(`psql exited ${code}: ${Buffer.concat(stderrChunks).toString("utf8")}`));
|
|
109
|
+
});
|
|
110
|
+
child.on("error", rejectPromise);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
async function initGit(dir) {
|
|
114
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
115
|
+
const child = spawn("git", ["init", "-q", "-b", "main"], { cwd: dir, env: scrubbedEnv() });
|
|
116
|
+
child.on("close", (code) => {
|
|
117
|
+
if (code === 0)
|
|
118
|
+
resolvePromise();
|
|
119
|
+
else
|
|
120
|
+
rejectPromise(new Error(`git init exited ${code}`));
|
|
121
|
+
});
|
|
122
|
+
child.on("error", rejectPromise);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
const delay = (ms) => new Promise((r) => { setTimeout(r, ms); });
|
|
126
|
+
async function runStubRailsWorker(domain) {
|
|
127
|
+
const plan = domain.renamePlan.map((p) => `${p.from}->${p.to}`).join(", ");
|
|
128
|
+
trace("rails", "(stub mode)");
|
|
129
|
+
trace("rails", `copying substrate for ${domain.displayName}`);
|
|
130
|
+
await delay(200);
|
|
131
|
+
trace("rails", `renaming Ruby symbols: ${plan}`);
|
|
132
|
+
await delay(300);
|
|
133
|
+
trace("rails", "regenerating migrations");
|
|
134
|
+
await delay(250);
|
|
135
|
+
trace("rails", "updating routes.rb + JSON:API serializers");
|
|
136
|
+
await delay(200);
|
|
137
|
+
trace("rails", `done (out/${domain.slug}/rails)`);
|
|
138
|
+
return {
|
|
139
|
+
platform: "rails",
|
|
140
|
+
outDir: `./out/${domain.slug}/rails`,
|
|
141
|
+
filesTouched: 47,
|
|
142
|
+
renamedFrom: domain.renamePlan.map((p) => p.from),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=rails.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rails.js","sourceRoot":"","sources":["../../../src/agents/workers/rails.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA+BjE"}
|
package/dist/dispatch.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { runPlanner } from "./agents/planner.js";
|
|
3
|
+
import { runRailsWorker } from "./agents/workers/rails.js";
|
|
4
|
+
import { runIosWorker } from "./agents/workers/ios.js";
|
|
5
|
+
import { runAndroidWorker } from "./agents/workers/android.js";
|
|
6
|
+
import { runReviewer } from "./agents/reviewer.js";
|
|
7
|
+
import { runJudge } from "./agents/judge.js";
|
|
8
|
+
export async function dispatch(spec) {
|
|
9
|
+
const domain = await runPlanner(spec);
|
|
10
|
+
const [rails, ios, android] = await Promise.all([
|
|
11
|
+
runRailsWorker(domain),
|
|
12
|
+
runIosWorker(domain),
|
|
13
|
+
runAndroidWorker(domain),
|
|
14
|
+
]);
|
|
15
|
+
const reviewer = await runReviewer({ domain, rails, ios, android });
|
|
16
|
+
// Stage 1 visual judging is opt-in via NATIVEAPPTEMPLATE_VISUAL=1.
|
|
17
|
+
// It forces Layer 2 build mode (so .app / .apk artifacts exist for the
|
|
18
|
+
// discovery + install + launch + capture chain) and adds 60-180s to a
|
|
19
|
+
// run depending on the substrate's cold-build time. Off by default.
|
|
20
|
+
const visualEnabled = process.env['NATIVEAPPTEMPLATE_VISUAL'] === "1";
|
|
21
|
+
const visual = visualEnabled
|
|
22
|
+
? {
|
|
23
|
+
iosDir: resolve(process.cwd(), ios.outDir),
|
|
24
|
+
androidDir: resolve(process.cwd(), android.outDir),
|
|
25
|
+
spec: domain.displayName,
|
|
26
|
+
}
|
|
27
|
+
: undefined;
|
|
28
|
+
return runJudge({
|
|
29
|
+
domain,
|
|
30
|
+
rails,
|
|
31
|
+
ios,
|
|
32
|
+
android,
|
|
33
|
+
reviewer,
|
|
34
|
+
...(visualEnabled ? { layer2Mode: "build" } : {}),
|
|
35
|
+
...(visual ? { visual } : {}),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAA0B,MAAM,mBAAmB,CAAC;AAGrE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY;IACzC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC9C,cAAc,CAAC,MAAM,CAAC;QACtB,YAAY,CAAC,MAAM,CAAC;QACpB,gBAAgB,CAAC,MAAM,CAAC;KACzB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IAEpE,mEAAmE;IACnE,uEAAuE;IACvE,sEAAsE;IACtE,oEAAoE;IACpE,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,KAAK,GAAG,CAAC;IACtE,MAAM,MAAM,GAAkC,aAAa;QACzD,CAAC,CAAC;YACE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC;YAC1C,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC;YAClD,IAAI,EAAE,MAAM,CAAC,WAAW;SACzB;QACH,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO,QAAQ,CAAC;QACd,MAAM;QACN,KAAK;QACL,GAAG;QACH,OAAO;QACP,QAAQ;QACR,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,CAAC,CAAC;AACL,CAAC"}
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAcA,wBAAgB,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAIxE;AASD,wBAAgB,mBAAmB,CAAC,IAAI,SAAS,GAAG,IAAI,CAmBvD"}
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
// Subprocesses inherit the agent's full environment by default, including
|
|
3
|
+
// ANTHROPIC_API_KEY. None of the things the agent spawns (ruby, git, psql,
|
|
4
|
+
// xcodebuild, gradlew, bin/rails) need that key, and one of them — eventually
|
|
5
|
+
// the mobile-mcp client — is third-party code. Strip anything that looks like
|
|
6
|
+
// an Anthropic credential before handing env to a child.
|
|
7
|
+
const SENSITIVE_KEYS = [
|
|
8
|
+
"ANTHROPIC_API_KEY",
|
|
9
|
+
"ANTHROPIC_AUTH_TOKEN",
|
|
10
|
+
"NATIVEAPPTEMPLATE_AGENT_ANTHROPIC_KEY",
|
|
11
|
+
];
|
|
12
|
+
export function scrubbedEnv(extra) {
|
|
13
|
+
const env = { ...process.env };
|
|
14
|
+
for (const key of SENSITIVE_KEYS)
|
|
15
|
+
delete env[key];
|
|
16
|
+
return extra ? { ...env, ...extra } : env;
|
|
17
|
+
}
|
|
18
|
+
// Load `.env` if present, but never overwrite an already-set process.env
|
|
19
|
+
// value. Shell exports (`export FOO=x`) and inline assignment
|
|
20
|
+
// (`FOO=x npm run dev`) win over the file. `.env` is just a convenience
|
|
21
|
+
// for users who don't want to manage shell config.
|
|
22
|
+
//
|
|
23
|
+
// Format: KEY=value per line, comments with `#`, surrounding double or
|
|
24
|
+
// single quotes are stripped. No shell interpolation.
|
|
25
|
+
export function loadDotenvIfPresent(path = ".env") {
|
|
26
|
+
let raw;
|
|
27
|
+
try {
|
|
28
|
+
raw = readFileSync(path, "utf8");
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
for (const line of raw.split("\n")) {
|
|
34
|
+
const trimmed = line.trim();
|
|
35
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
36
|
+
continue;
|
|
37
|
+
const eq = trimmed.indexOf("=");
|
|
38
|
+
if (eq < 1)
|
|
39
|
+
continue;
|
|
40
|
+
const key = trimmed.slice(0, eq).trim();
|
|
41
|
+
const valueRaw = trimmed.slice(eq + 1).trim();
|
|
42
|
+
const value = valueRaw.replace(/^"(.*)"$/, "$1").replace(/^'(.*)'$/, "$1");
|
|
43
|
+
if (process.env[key] === undefined) {
|
|
44
|
+
process.env[key] = value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,0EAA0E;AAC1E,2EAA2E;AAC3E,8EAA8E;AAC9E,8EAA8E;AAC9E,yDAAyD;AAEzD,MAAM,cAAc,GAAG;IACrB,mBAAmB;IACnB,sBAAsB;IACtB,uCAAuC;CAC/B,CAAC;AAEX,MAAM,UAAU,WAAW,CAAC,KAAyB;IACnD,MAAM,GAAG,GAAsB,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAClD,KAAK,MAAM,GAAG,IAAI,cAAc;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AAC5C,CAAC;AAED,yEAAyE;AACzE,8DAA8D;AAC9D,wEAAwE;AACxE,mDAAmD;AACnD,EAAE;AACF,uEAAuE;AACvE,sDAAsD;AACtD,MAAM,UAAU,mBAAmB,CAAC,IAAI,GAAG,MAAM;IAC/C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAClD,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,EAAE,GAAG,CAAC;YAAE,SAAS;QACrB,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC3E,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAMA,wBAAsB,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBvD"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { dispatch } from "./dispatch.js";
|
|
3
|
+
import { loadDotenvIfPresent } from "./env.js";
|
|
4
|
+
loadDotenvIfPresent();
|
|
5
|
+
export async function main(spec) {
|
|
6
|
+
const input = spec ?? process.argv.slice(2).join(" ").trim();
|
|
7
|
+
if (!input) {
|
|
8
|
+
console.error('Usage: nativeapptemplate-agent "your spec here"');
|
|
9
|
+
process.exitCode = 1;
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
console.log(`nativeapptemplate-agent: received spec: ${input}`);
|
|
13
|
+
console.log('(tail tmp/trace/*.log in a tiled view via scripts/demo-tmux.sh)');
|
|
14
|
+
const result = await dispatch(input);
|
|
15
|
+
console.log('');
|
|
16
|
+
console.log('=== run complete ===');
|
|
17
|
+
console.log(`result: ${result.summary}`);
|
|
18
|
+
console.log(`overall: ${result.overallPass ? 'PASS' : 'FAIL'}`);
|
|
19
|
+
}
|
|
20
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
21
|
+
main().catch((err) => {
|
|
22
|
+
console.error(err);
|
|
23
|
+
process.exitCode = 1;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C,mBAAmB,EAAE,CAAC;AAEtB,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAa;IACtC,MAAM,KAAK,GAAG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2CAA2C,KAAK,EAAE,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;IAE/E,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IAErC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAClE,CAAC;AAED,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/ruby.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruby.d.ts","sourceRoot":"","sources":["../src/ruby.ts"],"names":[],"mappings":"AAIA,wBAAsB,OAAO,CAAC,MAAM,EAAE,OAAO,EAC3C,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAqBlB"}
|
package/dist/ruby.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { scrubbedEnv } from "./env.js";
|
|
4
|
+
export async function runRuby(scriptName, input) {
|
|
5
|
+
const scriptPath = resolve(process.cwd(), "scripts/ruby", scriptName);
|
|
6
|
+
const child = spawn("ruby", [scriptPath], { env: scrubbedEnv() });
|
|
7
|
+
const stdoutChunks = [];
|
|
8
|
+
const stderrChunks = [];
|
|
9
|
+
child.stdout.on("data", (c) => stdoutChunks.push(c));
|
|
10
|
+
child.stderr.on("data", (c) => stderrChunks.push(c));
|
|
11
|
+
child.stdin.write(JSON.stringify(input));
|
|
12
|
+
child.stdin.end();
|
|
13
|
+
const code = await new Promise((r) => { child.on("close", r); });
|
|
14
|
+
if (code !== 0) {
|
|
15
|
+
const stderr = Buffer.concat(stderrChunks).toString("utf8");
|
|
16
|
+
throw new Error(`ruby script ${scriptName} exited ${code}: ${stderr}`);
|
|
17
|
+
}
|
|
18
|
+
const stdout = Buffer.concat(stdoutChunks).toString("utf8");
|
|
19
|
+
return JSON.parse(stdout);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=ruby.js.map
|
package/dist/ruby.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruby.js","sourceRoot":"","sources":["../src/ruby.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,UAAkB,EAClB,KAAa;IAEb,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;IAElE,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7D,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACzC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IAElB,MAAM,IAAI,GAAW,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,eAAe,UAAU,WAAW,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAY,CAAC;AACvC,CAAC"}
|
package/dist/slug.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slug.d.ts","sourceRoot":"","sources":["../src/slug.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD"}
|
package/dist/slug.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function slugToPascal(slug) {
|
|
2
|
+
return slug
|
|
3
|
+
.split(/[-_]/)
|
|
4
|
+
.filter(Boolean)
|
|
5
|
+
.map((s) => s.charAt(0).toUpperCase() + s.slice(1))
|
|
6
|
+
.join("");
|
|
7
|
+
}
|
|
8
|
+
export function slugToSnake(slug) {
|
|
9
|
+
return slug.replace(/-/g, "_");
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=slug.js.map
|