nativeapptemplate-agent 0.1.0 → 0.1.2

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.
@@ -1 +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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAQA,wBAAsB,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBvD"}
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
+ import { realpathSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
2
4
  import { dispatch } from "./dispatch.js";
3
5
  import { loadDotenvIfPresent } from "./env.js";
4
6
  loadDotenvIfPresent();
@@ -17,10 +19,29 @@ export async function main(spec) {
17
19
  console.log(`result: ${result.summary}`);
18
20
  console.log(`overall: ${result.overallPass ? 'PASS' : 'FAIL'}`);
19
21
  }
20
- if (import.meta.url === `file://${process.argv[1]}`) {
22
+ // Entry guard: run main() when this file is the program entry point. Resolve
23
+ // both sides to canonical (symlink-followed) paths so npm bin symlinks (e.g.
24
+ // node_modules/.bin/nativeapptemplate-agent → ../nativeapptemplate-agent/dist/
25
+ // index.js) compare equal to import.meta.url. Without realpath, the guard
26
+ // fails silently on symlinked invocations and main() never runs — the CLI
27
+ // would exit 0 with no output.
28
+ if (isEntryPoint()) {
21
29
  main().catch((err) => {
22
30
  console.error(err);
23
31
  process.exitCode = 1;
24
32
  });
25
33
  }
34
+ function isEntryPoint() {
35
+ const argv1 = process.argv[1];
36
+ if (!argv1)
37
+ return false;
38
+ try {
39
+ const modulePath = fileURLToPath(import.meta.url);
40
+ const argv1Real = realpathSync(argv1);
41
+ return argv1Real === modulePath;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
26
47
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,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,6EAA6E;AAC7E,6EAA6E;AAC7E,+EAA+E;AAC/E,0EAA0E;AAC1E,0EAA0E;AAC1E,+BAA+B;AAC/B,IAAI,YAAY,EAAE,EAAE,CAAC;IACnB,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;AAED,SAAS,YAAY;IACnB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACtC,OAAO,SAAS,KAAK,UAAU,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -1 +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"}
1
+ {"version":3,"file":"ruby.d.ts","sourceRoot":"","sources":["../src/ruby.ts"],"names":[],"mappings":"AAcA,wBAAsB,OAAO,CAAC,MAAM,EAAE,OAAO,EAC3C,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAqBlB"}
package/dist/ruby.js CHANGED
@@ -1,8 +1,17 @@
1
1
  import { spawn } from "node:child_process";
2
- import { resolve } from "node:path";
2
+ import { resolve, dirname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
3
4
  import { scrubbedEnv } from "./env.js";
5
+ // Resolve scripts/ruby/ relative to the module's own location, not the
6
+ // caller's cwd. When installed via npm, the package layout is:
7
+ // <install>/dist/ruby.js
8
+ // <install>/scripts/ruby/<script>.rb
9
+ // So scripts/ruby/ is one level up from the dist file. Using process.cwd()
10
+ // here would look for scripts/ in whatever directory the user runs `npx`
11
+ // from — broken for every published-package code path.
12
+ const SCRIPTS_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..", "scripts", "ruby");
4
13
  export async function runRuby(scriptName, input) {
5
- const scriptPath = resolve(process.cwd(), "scripts/ruby", scriptName);
14
+ const scriptPath = resolve(SCRIPTS_DIR, scriptName);
6
15
  const child = spawn("ruby", [scriptPath], { env: scrubbedEnv() });
7
16
  const stdoutChunks = [];
8
17
  const stderrChunks = [];
package/dist/ruby.js.map CHANGED
@@ -1 +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"}
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,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,uEAAuE;AACvE,+DAA+D;AAC/D,2BAA2B;AAC3B,uCAAuC;AACvC,2EAA2E;AAC3E,yEAAyE;AACzE,uDAAuD;AACvD,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAE9F,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,UAAkB,EAClB,KAAa;IAEb,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACpD,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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nativeapptemplate-agent",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "A Claude Code agent that turns a natural-language SaaS spec into a working three-platform implementation (Rails API + SwiftUI iOS + Jetpack Compose Android).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -160,9 +160,15 @@ end
160
160
 
161
161
  all_patterns = plan.flat_map { |p| build_patterns(p.fetch("from"), p.fetch("to")) }
162
162
 
163
- def skip?(path)
164
- return true if SKIP_DIR_SEGMENTS.any? { |d| path.include?("/#{d}/") || path.end_with?("/#{d}") }
165
- return true if SKIP_SUBPATHS.any? { |sp| path.include?("/#{sp}") }
163
+ def skip?(path, root)
164
+ # Compare against the path RELATIVE to the project root, not the absolute
165
+ # path. Otherwise SKIP_DIR_SEGMENTS like "tmp" / "log" / "build" silently
166
+ # match user-cwd ancestors (e.g. /tmp/myproject/...) and skip every file.
167
+ rel = path.sub(/\A#{Regexp.escape(root)}\/?/, "")
168
+ return false if rel == path # path wasn't under root; don't skip
169
+ segments = rel.split("/")
170
+ return true if segments.any? { |seg| SKIP_DIR_SEGMENTS.include?(seg) }
171
+ return true if SKIP_SUBPATHS.any? { |sp| rel.include?(sp) || rel.start_with?(sp) }
166
172
  false
167
173
  end
168
174
 
@@ -176,7 +182,7 @@ end
176
182
  # Pass 1 — rewrite file contents.
177
183
  Dir.glob("#{root}/**/*", File::FNM_DOTMATCH).each do |path|
178
184
  next unless File.file?(path)
179
- next if skip?(path)
185
+ next if skip?(path, root)
180
186
  next unless text_file?(path)
181
187
 
182
188
  stats[:files_scanned] += 1
@@ -203,7 +209,7 @@ end
203
209
  # Pass 2 — rename paths. Deepest-first so renaming a parent directory
204
210
  # doesn't invalidate paths we haven't visited yet.
205
211
  Dir.glob("#{root}/**/*", File::FNM_DOTMATCH).sort_by { |p| -p.length }.each do |path|
206
- next if skip?(path)
212
+ next if skip?(path, root)
207
213
  next unless File.exist?(path)
208
214
 
209
215
  old_name = File.basename(path)