@nagarjuna2002/ios-agent 0.2.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.
@@ -0,0 +1,402 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { APP_DIR, INTERNAL_ENTRIES, gitignoreContents, layoutFor } from "./layout.js";
4
+ import { defaultConfig, writeConfig } from "./config.js";
5
+ export class ScaffoldError extends Error {
6
+ }
7
+ /** Reserved on Windows regardless of extension. Creating one produces an unopenable directory. */
8
+ const WINDOWS_RESERVED = new Set([
9
+ "con", "prn", "aux", "nul",
10
+ ...Array.from({ length: 9 }, (_, i) => `com${i + 1}`),
11
+ ...Array.from({ length: 9 }, (_, i) => `lpt${i + 1}`),
12
+ ]);
13
+ /**
14
+ * Validate a project name before any directory exists.
15
+ *
16
+ * Stricter than the filesystem on purpose. The name becomes a Swift type
17
+ * prefix, a directory, and a target name, so the intersection of what all three
18
+ * accept is what is actually usable — and a name rejected up front costs
19
+ * nothing, while one rejected by Xcode two steps later costs a rebuild.
20
+ */
21
+ export function validateProjectName(name) {
22
+ if (name.length === 0)
23
+ throw new ScaffoldError("Project name cannot be empty.");
24
+ if (name.length > 64)
25
+ throw new ScaffoldError("Project name cannot exceed 64 characters.");
26
+ if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(name)) {
27
+ throw new ScaffoldError(`Invalid project name "${name}". Use a letter followed by letters, digits, or underscores — it becomes a Swift type name.`);
28
+ }
29
+ if (WINDOWS_RESERVED.has(name.toLowerCase())) {
30
+ throw new ScaffoldError(`"${name}" is reserved on Windows and cannot be a directory name.`);
31
+ }
32
+ }
33
+ export function scaffoldProject(options) {
34
+ const { name, parentDir, minimal = false, license = "MIT", force = false, now = new Date() } = options;
35
+ validateProjectName(name);
36
+ if (options.brief !== undefined && !options.brief.trim())
37
+ throw new ScaffoldError("--brief requires a non-empty description.");
38
+ const root = path.join(path.resolve(parentDir), name);
39
+ const layout = layoutFor(root);
40
+ const created = [];
41
+ if (fs.existsSync(root) && !force) {
42
+ const existing = fs.readdirSync(root);
43
+ if (existing.length > 0) {
44
+ throw new ScaffoldError(`${root} already exists and is not empty (${existing.length} entries). Pass --force to scaffold into it anyway.`);
45
+ }
46
+ }
47
+ const planned = new Map();
48
+ const write = (target, contents) => { planned.set(target, contents); };
49
+ const sourceDir = path.join(layout.app, name);
50
+ const testDir = path.join(layout.app, `${name}Tests`);
51
+ write(path.join(sourceDir, `${name}App.swift`), appEntryPoint(name));
52
+ write(path.join(sourceDir, "ContentView.swift"), contentView(name));
53
+ write(path.join(testDir, `${name}Tests.swift`), testStub(name));
54
+ if (options.brief !== undefined)
55
+ write(path.join(layout.app, "APP_BRIEF.md"), implementationBrief(name, options.brief));
56
+ if (options.xcodegen) {
57
+ write(path.join(layout.app, "project.yml"), projectSpec(name));
58
+ write(path.join(layout.app, "BUILD.md"), buildInstructions(name));
59
+ for (const [file, contents] of Object.entries(iconLayers()))
60
+ write(path.join(sourceDir, "IconLayers", file), contents);
61
+ }
62
+ if (!minimal) {
63
+ write(path.join(root, "README.md"), options.xcodegen ? readme(name).replace(/## Opening this in Xcode[\s\S]*?## Commands/, "## Opening this in Xcode\n\nSee [App/BUILD.md](App/BUILD.md) for XcodeGen generation and simulator builds.\n\n## Commands") : readme(name));
64
+ write(path.join(root, ".gitignore"), rootGitignore());
65
+ if (license === "MIT") {
66
+ write(path.join(root, "LICENSE"), mitLicense(now.getUTCFullYear()));
67
+ }
68
+ }
69
+ // Preflight all authored files, even under --force, before writing anything.
70
+ for (const target of [...planned.keys(), ...(!minimal ? [layout.config, layout.gitignore] : [])]) {
71
+ let candidate = target;
72
+ while (candidate !== path.dirname(root)) {
73
+ if (fs.existsSync(candidate) || fs.lstatSync(candidate, { throwIfNoEntry: false })) {
74
+ const stat = fs.lstatSync(candidate);
75
+ if (candidate === target || stat.isSymbolicLink() || !stat.isDirectory()) {
76
+ throw new ScaffoldError(`Refusing to overwrite or follow existing path: ${candidate}`);
77
+ }
78
+ }
79
+ candidate = path.dirname(candidate);
80
+ }
81
+ }
82
+ if (!minimal && fs.existsSync(layout.config))
83
+ throw new ScaffoldError(`Refusing to overwrite ${layout.config}`);
84
+ for (const [target, contents] of planned) {
85
+ fs.mkdirSync(path.dirname(target), { recursive: true });
86
+ fs.writeFileSync(target, contents, { encoding: "utf8", flag: "wx" });
87
+ created.push(target);
88
+ }
89
+ if (!minimal) {
90
+ for (const target of ensureInternal(layout)) {
91
+ created.push(target);
92
+ }
93
+ writeConfig(layout, defaultConfig(name, path.join(APP_DIR, name), now));
94
+ created.push(layout.config);
95
+ }
96
+ return { layout, created };
97
+ }
98
+ /**
99
+ * Create `.ios-agent/` and the entries marked eager, idempotently.
100
+ *
101
+ * Every command that writes calls this first, which is what makes the minimal
102
+ * scaffold honest: `MyApp/App/` alone is a real project, and the internal
103
+ * directory appears the first time there is something to put in it rather than
104
+ * sitting empty as a promise.
105
+ */
106
+ export function ensureInternal(layout) {
107
+ const created = [];
108
+ if (!fs.existsSync(layout.internal)) {
109
+ fs.mkdirSync(layout.internal, { recursive: true });
110
+ created.push(layout.internal);
111
+ }
112
+ // Regenerated every time: it is derived from INTERNAL_ENTRIES, so a build
113
+ // that adds a disposable directory fixes stale checkouts on next run.
114
+ fs.writeFileSync(layout.gitignore, gitignoreContents(), "utf8");
115
+ created.push(layout.gitignore);
116
+ for (const entry of INTERNAL_ENTRIES) {
117
+ if (!entry.eager || entry.kind !== "directory")
118
+ continue;
119
+ const target = path.join(layout.internal, entry.name);
120
+ if (!fs.existsSync(target)) {
121
+ fs.mkdirSync(target, { recursive: true });
122
+ created.push(target);
123
+ }
124
+ }
125
+ return created;
126
+ }
127
+ /** Create one internal directory on demand. Callers name it via the layout. */
128
+ export function ensureInternalDir(layout, target) {
129
+ ensureInternal(layout);
130
+ fs.mkdirSync(target, { recursive: true });
131
+ return target;
132
+ }
133
+ // MARK: - File contents
134
+ function appEntryPoint(name) {
135
+ return `import SwiftUI
136
+
137
+ @main
138
+ struct ${name}App: App {
139
+ var body: some Scene {
140
+ WindowGroup {
141
+ ContentView()
142
+ }
143
+ }
144
+ }
145
+ `;
146
+ }
147
+ function contentView(name) {
148
+ return `import SwiftUI
149
+
150
+ private enum StarterTokens {
151
+ static let spacing: CGFloat = 16
152
+ static let padding: CGFloat = 24
153
+ static let symbolSize: CGFloat = 48
154
+ }
155
+
156
+ struct ContentView: View {
157
+ var body: some View {
158
+ VStack(spacing: StarterTokens.spacing) {
159
+ Image(systemName: "swift")
160
+ .font(.system(size: StarterTokens.symbolSize))
161
+ .foregroundStyle(.tint)
162
+
163
+ Text("${name}")
164
+ .font(.largeTitle)
165
+ .fontWeight(.bold)
166
+ .foregroundStyle(Color(.label))
167
+
168
+ Text("Replace this view to get started.")
169
+ .font(.body)
170
+ .foregroundStyle(Color(.secondaryLabel))
171
+ .multilineTextAlignment(.center)
172
+ }
173
+ .padding(StarterTokens.padding)
174
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
175
+ .background(Color(.systemBackground))
176
+ }
177
+ }
178
+
179
+ #Preview("Light") {
180
+ ContentView()
181
+ }
182
+
183
+ #Preview("Dark") {
184
+ ContentView()
185
+ .preferredColorScheme(.dark)
186
+ }
187
+ `;
188
+ }
189
+ function testStub(name) {
190
+ return `import XCTest
191
+ @testable import \`${name}\`
192
+
193
+ final class ${name}Tests: XCTestCase {
194
+
195
+ func testPlaceholderIsReplacedBeforeShipping() {
196
+ // Replace this with a real assertion about real behaviour. A test that
197
+ // cannot fail reports success whether the app works or not.
198
+ XCTAssertTrue(true, "placeholder")
199
+ }
200
+ }
201
+ `;
202
+ }
203
+ function readme(name) {
204
+ return `# ${name}
205
+
206
+ ## Layout
207
+
208
+ \`\`\`
209
+ ${name}/
210
+ ├── App/ # your source — this is the part you edit
211
+ └── .ios-agent/ # tool-managed; safe to delete, regenerates on demand
212
+ \`\`\`
213
+
214
+ Everything outside \`App/\` is managed for you. \`.ios-agent/\` holds caches,
215
+ logs, state, and build artifacts; only \`.ios-agent/config.json\` is tracked in
216
+ git, and the generated \`.ios-agent/.gitignore\` handles the rest.
217
+
218
+ ## Opening this in Xcode
219
+
220
+ \`ios-agent\` generates Swift sources, not an Xcode project — an \`.xcodeproj\`
221
+ is a build-system artifact that Xcode should own.
222
+
223
+ 1. Xcode → File → New → Project → App (SwiftUI, Swift)
224
+ 2. Save it inside \`App/\`
225
+ 3. Right-click the project → Add Files, and add \`App/${name}/\`
226
+ 4. Build and run with \`Cmd + R\`
227
+
228
+ ## Commands
229
+
230
+ \`\`\`
231
+ ios-agent where Print resolved paths (add --json for tooling)
232
+ ios-agent info Summarise the project
233
+ ios-agent doctor Check the layout for problems
234
+ ios-agent clean Delete every disposable internal file
235
+ \`\`\`
236
+ `;
237
+ }
238
+ function rootGitignore() {
239
+ return `# macOS
240
+ .DS_Store
241
+
242
+ # Xcode
243
+ build/
244
+ DerivedData/
245
+ *.xcuserstate
246
+ *.xcuserdatad/
247
+ xcuserdata/
248
+ *.moved-aside
249
+
250
+ # Swift Package Manager
251
+ .build/
252
+ .swiftpm/
253
+ Package.resolved
254
+
255
+ # ios-agent internals are ignored by .ios-agent/.gitignore, which is generated
256
+ # and kept next to the files it governs. Nothing about them belongs here.
257
+ `;
258
+ }
259
+ function mitLicense(year) {
260
+ return `MIT License
261
+
262
+ Copyright (c) ${year}
263
+
264
+ Permission is hereby granted, free of charge, to any person obtaining a copy
265
+ of this software and associated documentation files (the "Software"), to deal
266
+ in the Software without restriction, including without limitation the rights
267
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
268
+ copies of the Software, and to permit persons to whom the Software is
269
+ furnished to do so, subject to the following conditions:
270
+
271
+ The above copyright notice and this permission notice shall be included in all
272
+ copies or substantial portions of the Software.
273
+
274
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
275
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
276
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
277
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
278
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
279
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
280
+ SOFTWARE.
281
+ `;
282
+ }
283
+ function implementationBrief(name, brief) {
284
+ return `# ${name} implementation brief
285
+
286
+ This is an editable handoff for your coding agent. The CLI saved your description;
287
+ it has not generated or implemented these features.
288
+
289
+ ## App description
290
+
291
+ ${brief}
292
+
293
+ ## Implementation checklist
294
+
295
+ - Translate the description into the primary user journey and a small first release.
296
+ - Define screens, navigation, data models, persistence, and loading/empty/error states.
297
+ - Choose semantic colors and reusable spacing/type tokens; support Dynamic Type and dark mode.
298
+ - Implement the app in SwiftUI, with offline previews and injected dependencies where needed.
299
+ - Create or customize separate SVG IconLayers, import the layers into Icon Composer, and validate the resulting icon in Xcode.
300
+ - Build and test on an available simulator; report actual results and remaining limitations.
301
+ `;
302
+ }
303
+ function projectSpec(name) {
304
+ // Names have already passed the Swift/filesystem allowlist; quote YAML scalars
305
+ // anyway so names such as Yes, Null, and On remain strings.
306
+ const quoted = JSON.stringify(name);
307
+ const bundle = name.toLowerCase().replace(/_/g, "-");
308
+ return `name: ${quoted}
309
+ options:
310
+ deploymentTarget:
311
+ iOS: "17.0"
312
+ settings:
313
+ base:
314
+ SWIFT_VERSION: "5.0"
315
+ GENERATE_INFOPLIST_FILE: YES
316
+ CURRENT_PROJECT_VERSION: "1"
317
+ MARKETING_VERSION: "1.0"
318
+ targets:
319
+ ${quoted}:
320
+ type: application
321
+ platform: iOS
322
+ sources:
323
+ - path: ${quoted}
324
+ excludes:
325
+ - IconLayers
326
+ settings:
327
+ base:
328
+ PRODUCT_BUNDLE_IDENTIFIER: "com.example.${bundle}"
329
+ INFOPLIST_KEY_UILaunchScreen_Generation: YES
330
+ INFOPLIST_KEY_UIApplicationSceneManifest_Generation: YES
331
+ TARGETED_DEVICE_FAMILY: "1,2"
332
+ "${name}Tests":
333
+ type: bundle.unit-test
334
+ platform: iOS
335
+ sources:
336
+ - path: "${name}Tests"
337
+ dependencies:
338
+ - target: ${quoted}
339
+ settings:
340
+ base:
341
+ PRODUCT_BUNDLE_IDENTIFIER: "com.example.${bundle}.tests"
342
+ schemes:
343
+ ${quoted}:
344
+ build:
345
+ targets:
346
+ ${quoted}: all
347
+ test:
348
+ targets:
349
+ - "${name}Tests"
350
+ `;
351
+ }
352
+ function buildInstructions(name) {
353
+ return `# Build ${name}
354
+
355
+ Prerequisites: macOS, Xcode 15 or newer with an installed iOS simulator runtime,
356
+ and XcodeGen installed separately. The CLI does not install or run these tools.
357
+ Icon Composer requires a compatible Xcode installation and is only needed for icon editing.
358
+
359
+ From this App directory:
360
+
361
+ \`\`\`sh
362
+ xcodegen generate --spec project.yml
363
+ open ${name}.xcodeproj
364
+ xcodebuild -project ${name}.xcodeproj -scheme ${name} -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath ../.ios-agent/build build CODE_SIGNING_ALLOWED=NO
365
+ xcodebuild -project ${name}.xcodeproj -scheme ${name} -showdestinations
366
+ \`\`\`
367
+
368
+ Choose an available simulator destination from that list to run tests in Xcode
369
+ or with xcodebuild test. The starter test is a placeholder: replace it with real
370
+ behavior assertions. Device builds require your own bundle identifier and signing team.
371
+ Edit project.yml and regenerate when changing targets or build settings.
372
+ No .xcodeproj is created until you run XcodeGen. The project has no shipping app
373
+ icon yet; see ${name}/IconLayers/README.md before distribution.
374
+ `;
375
+ }
376
+ function iconLayers() {
377
+ const svg = (body) => `<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024">${body}</svg>\n`;
378
+ return {
379
+ "background.svg": svg('<rect width="1024" height="1024" fill="#2457DB"/>'),
380
+ "foreground.svg": svg('<path d="M512 220 L804 512 L512 804 L220 512 Z" fill="#FFFFFF"/>'),
381
+ "accent.svg": svg('<circle cx="512" cy="512" r="96" fill="#90E8FF"/>'),
382
+ "manifest.json": JSON.stringify({ format: "ios-agent-svg-layer-starter", version: 1, canvas: { width: 1024, height: 1024 }, layers: ["background.svg", "foreground.svg", "accent.svg"], nativeIconCreated: false }, null, 2) + "\n",
383
+ "README.md": `# Editable icon layers
384
+
385
+ These are separate SVG starter assets, ordered background → foreground → accent.
386
+ Edit their paths and colors in a vector editor to fit your app. They are generic
387
+ placeholders, not finished branding or an Icon Composer document.
388
+
389
+ 1. Open Icon Composer from a compatible Xcode installation and create a new icon.
390
+ 2. Import each SVG as a separate layer, preserving the back-to-front order above.
391
+ 3. Adjust groups, materials, and appearances; preview at small sizes.
392
+ 4. Save the native .icon document under App/<Name>/ and add it to your Xcode target.
393
+ 5. Configure the app icon in Xcode and build to validate all required appearances.
394
+
395
+ manifest.json describes these source layers for humans and tooling; it is not
396
+ Apple's .icon format. No native .icon has been created or validated. The XcodeGen
397
+ spec excludes this folder from app resources. After adding a native icon, update
398
+ project.yml as required by your Xcode/XcodeGen versions and regenerate the project.
399
+ `,
400
+ };
401
+ }
402
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@nagarjuna2002/ios-agent",
3
+ "version": "0.2.0",
4
+ "description": "Project scaffolding and layout management for iOS work. Keeps tool-owned files out of the user's way.",
5
+ "type": "module",
6
+ "bin": {
7
+ "ios-agent": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc && node -e \"require('fs').chmodSync('dist/index.js', 0o755)\"",
15
+ "typecheck": "tsc --noEmit",
16
+ "test": "node --test test/*.test.js",
17
+ "prepublishOnly": "npm run build && npm test"
18
+ },
19
+ "engines": {
20
+ "node": ">=20"
21
+ },
22
+ "keywords": [
23
+ "ios",
24
+ "swift",
25
+ "scaffolding",
26
+ "cli"
27
+ ],
28
+ "license": "MIT",
29
+ "devDependencies": {
30
+ "@types/node": "^22.20.1",
31
+ "typescript": "^5.6.0"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/Nagarjuna2997/ios-agent-skill.git",
36
+ "directory": "cli"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ }
41
+ }