arcane-cli 0.38.3 → 1.0.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 (176) hide show
  1. package/README.md +1 -1
  2. package/dist/assets/.agents/skills/spell-address-review/SKILL.md +6 -0
  3. package/dist/assets/.agents/skills/spell-adopt-docs/SKILL.md +6 -0
  4. package/dist/assets/.agents/skills/spell-arcane-version/SKILL.md +6 -0
  5. package/dist/assets/.agents/skills/spell-architect/SKILL.md +6 -0
  6. package/dist/assets/.agents/skills/spell-brainstorm/SKILL.md +6 -0
  7. package/dist/assets/.agents/skills/spell-bug/SKILL.md +6 -0
  8. package/dist/assets/.agents/skills/spell-bump/SKILL.md +6 -0
  9. package/dist/assets/.agents/skills/spell-check-drift/SKILL.md +6 -0
  10. package/dist/assets/.agents/skills/spell-close-session/SKILL.md +6 -0
  11. package/dist/assets/.agents/skills/spell-commit-work/SKILL.md +6 -0
  12. package/dist/assets/.agents/skills/spell-compliance/SKILL.md +6 -0
  13. package/dist/assets/.agents/skills/spell-create-pull-request/SKILL.md +6 -0
  14. package/dist/assets/.agents/skills/spell-document/SKILL.md +6 -0
  15. package/dist/assets/.agents/skills/spell-dotnet-expert/SKILL.md +6 -0
  16. package/dist/assets/.agents/skills/spell-eas-store-deploy/SKILL.md +6 -0
  17. package/dist/assets/.agents/skills/spell-enchant/SKILL.md +6 -0
  18. package/dist/assets/.agents/skills/spell-explain-concept/SKILL.md +6 -0
  19. package/dist/assets/.agents/skills/spell-feedback/SKILL.md +6 -0
  20. package/dist/assets/.agents/skills/spell-full-cycle/SKILL.md +6 -0
  21. package/dist/assets/.agents/skills/spell-generate-bot-icons/SKILL.md +6 -0
  22. package/dist/assets/.agents/skills/spell-implement/SKILL.md +6 -0
  23. package/dist/assets/.agents/skills/spell-make-discoverable/SKILL.md +6 -0
  24. package/dist/assets/.agents/skills/spell-manifest/SKILL.md +6 -0
  25. package/dist/assets/.agents/skills/spell-open-session/SKILL.md +6 -0
  26. package/dist/assets/.agents/skills/spell-plan/SKILL.md +6 -0
  27. package/dist/assets/.agents/skills/spell-present-arcane/SKILL.md +6 -0
  28. package/dist/assets/.agents/skills/spell-product-review/SKILL.md +6 -0
  29. package/dist/assets/.agents/skills/spell-review/SKILL.md +6 -0
  30. package/dist/assets/.agents/skills/spell-review-batch/SKILL.md +6 -0
  31. package/dist/assets/.agents/skills/spell-save-idea/SKILL.md +6 -0
  32. package/dist/assets/.agents/skills/spell-scope/SKILL.md +6 -0
  33. package/dist/assets/.agents/skills/spell-scry/SKILL.md +6 -0
  34. package/dist/assets/.agents/skills/spell-security-review/SKILL.md +6 -0
  35. package/dist/assets/.agents/skills/spell-ship/SKILL.md +6 -0
  36. package/dist/assets/.agents/skills/spell-status/SKILL.md +6 -0
  37. package/dist/assets/.agents/skills/spell-suggest-feature/SKILL.md +6 -0
  38. package/dist/assets/.agents/skills/spell-summon-venture/SKILL.md +6 -0
  39. package/dist/assets/.agents/skills/spell-sync-pull-request/SKILL.md +6 -0
  40. package/dist/assets/.agents/skills/spell-test/SKILL.md +6 -0
  41. package/dist/assets/.agents/skills/spell-todo/SKILL.md +6 -0
  42. package/dist/assets/.agents/skills/spell-verification-ledger/SKILL.md +6 -0
  43. package/dist/assets/.arcane/governance/development-methodology.md +6 -6
  44. package/dist/assets/.arcane/governance/git-conventions.md +2 -2
  45. package/dist/assets/.arcane/governance/portable-bootstrap.md +1 -0
  46. package/dist/assets/.arcane/governance/product-excellence-standards.md +1 -1
  47. package/dist/assets/.arcane/governance/spell-authoring-standards.md +9 -1
  48. package/dist/assets/.arcane/governance/universal-agent-rules.md +7 -0
  49. package/dist/assets/.arcane/spells/spell-address-review.md +115 -0
  50. package/dist/assets/.arcane/spells/spell-adopt-docs.md +158 -0
  51. package/dist/assets/.arcane/spells/spell-arcane-version.md +87 -0
  52. package/dist/assets/.arcane/spells/spell-architect.md +117 -0
  53. package/dist/assets/.arcane/spells/spell-brainstorm.md +125 -0
  54. package/dist/assets/.arcane/spells/spell-bug.md +123 -0
  55. package/dist/assets/.arcane/spells/spell-bump.md +82 -0
  56. package/dist/assets/.arcane/spells/spell-check-drift.md +118 -0
  57. package/dist/assets/.arcane/spells/spell-close-session.md +266 -0
  58. package/dist/assets/.arcane/spells/spell-commit-work.md +279 -0
  59. package/dist/assets/.arcane/spells/spell-compliance.md +130 -0
  60. package/dist/assets/.arcane/spells/spell-create-pull-request.md +224 -0
  61. package/dist/assets/.arcane/spells/spell-document.md +84 -0
  62. package/dist/assets/.arcane/spells/spell-dotnet-expert.md +118 -0
  63. package/dist/assets/.arcane/spells/spell-eas-store-deploy.md +254 -0
  64. package/dist/assets/.arcane/spells/spell-enchant.md +386 -0
  65. package/dist/assets/.arcane/spells/spell-explain-concept.md +70 -0
  66. package/dist/assets/.arcane/spells/spell-feedback.md +138 -0
  67. package/dist/assets/.arcane/spells/spell-full-cycle.md +253 -0
  68. package/dist/assets/.arcane/spells/spell-generate-bot-icons.md +85 -0
  69. package/dist/assets/.arcane/spells/spell-implement.md +109 -0
  70. package/dist/assets/.arcane/spells/spell-make-discoverable.md +293 -0
  71. package/dist/assets/.arcane/spells/spell-manifest.md +148 -0
  72. package/dist/assets/.arcane/spells/spell-open-session.md +154 -0
  73. package/dist/assets/.arcane/spells/spell-plan.md +160 -0
  74. package/dist/assets/.arcane/spells/spell-present-arcane.md +189 -0
  75. package/dist/assets/.arcane/spells/spell-product-review.md +98 -0
  76. package/dist/assets/.arcane/spells/spell-review-batch.md +113 -0
  77. package/dist/assets/.arcane/spells/spell-review.md +142 -0
  78. package/dist/assets/.arcane/spells/spell-save-idea.md +117 -0
  79. package/dist/assets/.arcane/spells/spell-scope.md +266 -0
  80. package/dist/assets/.arcane/spells/spell-scry.md +124 -0
  81. package/dist/assets/.arcane/spells/spell-security-review.md +152 -0
  82. package/dist/assets/.arcane/spells/spell-ship.md +106 -0
  83. package/dist/assets/.arcane/spells/spell-status.md +86 -0
  84. package/dist/assets/.arcane/spells/spell-suggest-feature.md +122 -0
  85. package/dist/assets/.arcane/spells/spell-summon-venture.md +110 -0
  86. package/dist/assets/.arcane/spells/spell-sync-pull-request.md +161 -0
  87. package/dist/assets/.arcane/spells/spell-test.md +88 -0
  88. package/dist/assets/.arcane/spells/spell-todo.md +166 -0
  89. package/dist/assets/.arcane/spells/spell-verification-ledger.md +102 -0
  90. package/dist/assets/.claude/commands/spell-address-review.md +2 -2
  91. package/dist/assets/.claude/commands/spell-adopt-docs.md +2 -2
  92. package/dist/assets/.claude/commands/spell-arcane-version.md +2 -2
  93. package/dist/assets/.claude/commands/spell-architect.md +2 -2
  94. package/dist/assets/.claude/commands/spell-brainstorm.md +2 -2
  95. package/dist/assets/.claude/commands/spell-bug.md +2 -2
  96. package/dist/assets/.claude/commands/spell-bump.md +2 -2
  97. package/dist/assets/.claude/commands/spell-check-drift.md +2 -2
  98. package/dist/assets/.claude/commands/spell-close-session.md +2 -2
  99. package/dist/assets/.claude/commands/spell-commit-work.md +2 -2
  100. package/dist/assets/.claude/commands/spell-compliance.md +2 -2
  101. package/dist/assets/.claude/commands/spell-create-pull-request.md +2 -2
  102. package/dist/assets/.claude/commands/spell-document.md +2 -2
  103. package/dist/assets/.claude/commands/spell-dotnet-expert.md +2 -2
  104. package/dist/assets/.claude/commands/spell-eas-store-deploy.md +2 -2
  105. package/dist/assets/.claude/commands/spell-enchant.md +2 -2
  106. package/dist/assets/.claude/commands/spell-explain-concept.md +2 -2
  107. package/dist/assets/.claude/commands/spell-feedback.md +2 -2
  108. package/dist/assets/.claude/commands/spell-full-cycle.md +2 -2
  109. package/dist/assets/.claude/commands/spell-generate-bot-icons.md +2 -2
  110. package/dist/assets/.claude/commands/spell-implement.md +2 -2
  111. package/dist/assets/.claude/commands/spell-make-discoverable.md +2 -2
  112. package/dist/assets/.claude/commands/spell-manifest.md +2 -2
  113. package/dist/assets/.claude/commands/spell-open-session.md +2 -2
  114. package/dist/assets/.claude/commands/spell-plan.md +2 -2
  115. package/dist/assets/.claude/commands/spell-present-arcane.md +2 -2
  116. package/dist/assets/.claude/commands/spell-product-review.md +2 -2
  117. package/dist/assets/.claude/commands/spell-review-batch.md +2 -2
  118. package/dist/assets/.claude/commands/spell-review.md +2 -2
  119. package/dist/assets/.claude/commands/spell-save-idea.md +2 -2
  120. package/dist/assets/.claude/commands/spell-scope.md +2 -2
  121. package/dist/assets/.claude/commands/spell-scry.md +2 -2
  122. package/dist/assets/.claude/commands/spell-security-review.md +2 -2
  123. package/dist/assets/.claude/commands/spell-ship.md +2 -2
  124. package/dist/assets/.claude/commands/spell-status.md +2 -2
  125. package/dist/assets/.claude/commands/spell-suggest-feature.md +2 -2
  126. package/dist/assets/.claude/commands/spell-summon-venture.md +2 -2
  127. package/dist/assets/.claude/commands/spell-sync-pull-request.md +2 -2
  128. package/dist/assets/.claude/commands/spell-test.md +2 -2
  129. package/dist/assets/.claude/commands/spell-todo.md +2 -2
  130. package/dist/assets/.claude/commands/spell-verification-ledger.md +2 -2
  131. package/dist/assets/.github/instructions/agent-output.instructions.md +14 -13
  132. package/dist/assets/.github/prompts/spell-address-review.prompt.md +1 -107
  133. package/dist/assets/.github/prompts/spell-adopt-docs.prompt.md +1 -150
  134. package/dist/assets/.github/prompts/spell-arcane-version.prompt.md +1 -79
  135. package/dist/assets/.github/prompts/spell-architect.prompt.md +1 -109
  136. package/dist/assets/.github/prompts/spell-brainstorm.prompt.md +1 -117
  137. package/dist/assets/.github/prompts/spell-bug.prompt.md +1 -115
  138. package/dist/assets/.github/prompts/spell-bump.prompt.md +1 -74
  139. package/dist/assets/.github/prompts/spell-check-drift.prompt.md +1 -110
  140. package/dist/assets/.github/prompts/spell-close-session.prompt.md +1 -258
  141. package/dist/assets/.github/prompts/spell-commit-work.prompt.md +1 -270
  142. package/dist/assets/.github/prompts/spell-compliance.prompt.md +1 -122
  143. package/dist/assets/.github/prompts/spell-create-pull-request.prompt.md +1 -215
  144. package/dist/assets/.github/prompts/spell-document.prompt.md +1 -76
  145. package/dist/assets/.github/prompts/spell-dotnet-expert.prompt.md +1 -110
  146. package/dist/assets/.github/prompts/spell-eas-store-deploy.prompt.md +1 -246
  147. package/dist/assets/.github/prompts/spell-enchant.prompt.md +1 -378
  148. package/dist/assets/.github/prompts/spell-explain-concept.prompt.md +1 -62
  149. package/dist/assets/.github/prompts/spell-feedback.prompt.md +1 -130
  150. package/dist/assets/.github/prompts/spell-full-cycle.prompt.md +1 -245
  151. package/dist/assets/.github/prompts/spell-generate-bot-icons.prompt.md +1 -77
  152. package/dist/assets/.github/prompts/spell-implement.prompt.md +1 -101
  153. package/dist/assets/.github/prompts/spell-make-discoverable.prompt.md +1 -285
  154. package/dist/assets/.github/prompts/spell-manifest.prompt.md +1 -140
  155. package/dist/assets/.github/prompts/spell-open-session.prompt.md +1 -146
  156. package/dist/assets/.github/prompts/spell-plan.prompt.md +1 -152
  157. package/dist/assets/.github/prompts/spell-present-arcane.prompt.md +1 -181
  158. package/dist/assets/.github/prompts/spell-product-review.prompt.md +1 -90
  159. package/dist/assets/.github/prompts/spell-review-batch.prompt.md +1 -105
  160. package/dist/assets/.github/prompts/spell-review.prompt.md +1 -134
  161. package/dist/assets/.github/prompts/spell-save-idea.prompt.md +1 -109
  162. package/dist/assets/.github/prompts/spell-scope.prompt.md +1 -258
  163. package/dist/assets/.github/prompts/spell-scry.prompt.md +1 -116
  164. package/dist/assets/.github/prompts/spell-security-review.prompt.md +1 -144
  165. package/dist/assets/.github/prompts/spell-ship.prompt.md +1 -98
  166. package/dist/assets/.github/prompts/spell-status.prompt.md +1 -78
  167. package/dist/assets/.github/prompts/spell-suggest-feature.prompt.md +1 -114
  168. package/dist/assets/.github/prompts/spell-summon-venture.prompt.md +1 -102
  169. package/dist/assets/.github/prompts/spell-sync-pull-request.prompt.md +1 -152
  170. package/dist/assets/.github/prompts/spell-test.prompt.md +1 -80
  171. package/dist/assets/.github/prompts/spell-todo.prompt.md +1 -158
  172. package/dist/assets/.github/prompts/spell-verification-ledger.prompt.md +1 -94
  173. package/dist/index.js +195 -49
  174. package/dist/index.js.map +1 -1
  175. package/package.json +4 -4
  176. /package/dist/assets/{.github/prompts → .arcane/spells}/_fragments/tracking-mode-declaration.md +0 -0
@@ -6,79 +6,4 @@ argument-hint: Topics and output paths (e.g., "capability inventory → docs/cap
6
6
  agent: agent
7
7
  ---
8
8
 
9
- ## Executive Summary
10
-
11
- - This spell extracts substantive analysis from the current conversation and structures it into formal, durable documents.
12
- - It bridges ephemeral chat context and lasting project documentation.
13
- - Use it when a session produces reference material that deserves a proper home (inventories, comparisons, rationale, guides).
14
- - For a quick one-line idea instead, use `spell-save-idea`. For session continuity, use `spell-close-session`.
15
-
16
- ---
17
-
18
- Capture conversation insights and formalize them into well-structured documents.
19
-
20
- The user's input describes what to capture and where. If no argument was provided, ask what they want to capture and stop until they answer.
21
-
22
- **Before doing anything else, check that there is durable material to formalize.** Scan the conversation for substantive analysis, decisions, comparisons, or reference data. If the session holds nothing beyond small talk or trivial exchanges, say so plainly, suggest `spell-save-idea` for a quick capture instead, and stop — do not manufacture content to fill a document.
23
-
24
- ## Step 1 — Parse the Request
25
-
26
- Identify:
27
-
28
- - **Topics** — what conversation insights to extract (e.g., "naming analysis", "architecture comparison").
29
- - **Target paths** — where to write (e.g., `docs/...`, `.arcane/governance/...`). If the user gives only topics, propose sensible paths from the project structure. For a research report specifically (cited investigation, competitive analysis, feasibility study), default to `docs/research/<topic-slug>.md` per `portable-bootstrap.md`'s Research Reports convention.
30
- - **Document type** — reference doc, decision record, analysis report, research report, inventory, or guide.
31
-
32
- ## Step 2 — Extract from Conversation
33
-
34
- Gather all relevant material from context: tables, structured data, analysis results, comparisons, conclusions, recommendations, metrics/counts, and reasoning chains. Do not leave valuable insight behind in the chat.
35
-
36
- ## Step 3 — Structure into Documents
37
-
38
- For each target, produce a polished structure:
39
-
40
- - Title + metadata (clear heading, date, one-line context). Get the real date from the system (e.g., run `date`) rather than guessing.
41
- - Table of contents for documents longer than ~3 sections.
42
- - Proper sections with headers and logical flow.
43
- - Tables and lists formatted for readability.
44
- - Cross-references to related project files where relevant.
45
- - A short provenance note (e.g., _"Captured from a development session on YYYY-MM-DD."_) so future readers know its origin.
46
-
47
- Match the tone, frontmatter, and structure of files already in the target directory before inventing your own format.
48
-
49
- ## Step 4 — Show Proposal
50
-
51
- Present before writing. For each target, check whether the file already exists and label it `(new)` or `(exists — will diff before writing)` so approval is informed, not blind:
52
-
53
- ```
54
- ## Document Proposal
55
-
56
- ### 1. <path/to/file.md> (new)
57
- - Type: <reference / analysis / inventory / guide>
58
- - Sections: <list>
59
- - Preview:
60
- <first 10–15 lines>
61
-
62
- ### 2. <another path> (exists — will diff before writing)
63
- ...
64
-
65
- Approve? (yes / edit / skip)
66
- ```
67
-
68
- ## Step 5 — Apply (after approval)
69
-
70
- 1. Write each new document to its target path.
71
- 2. If a target already exists, do not silently overwrite. Show a diff preview of the proposed change against the current file and confirm. Prefer merging the new content into the existing structure (append a section, update a table) over replacing the whole file, unless the user asked for a full rewrite. State which mode you are using before writing.
72
- 3. Do NOT commit — leave that to `spell-commit-work`.
73
- 4. Confirm what was written and where (path + new-vs-updated per file).
74
-
75
- ## Rules
76
-
77
- - Only formalize material actually present in the conversation — do not invent, infer, or pad content to fill a section.
78
- - If nothing substantive is in the conversation, stop and route to `spell-save-idea` rather than producing an empty document.
79
- - Follow existing documentation patterns in the target directory.
80
- - Never overwrite an existing file without an explicit diff confirmation; prefer merging over clobbering.
81
- - Never include secrets, tokens, or credentials in a document.
82
- - Do not commit the changes — that is `spell-commit-work`'s job.
83
-
84
- > **Tip:** Run `spell-close-session` afterward to log the session, or `spell-commit-work` to commit the new documents.
9
+ This prompt is the Arcane `spell-document` spell. Read [`.arcane/spells/spell-document.md`](../../.arcane/spells/spell-document.md) and follow it as the complete workflow.
@@ -6,113 +6,4 @@ argument-hint: Specific .NET topic or question (e.g., "Azure Functions isolated
6
6
  agent: agent
7
7
  ---
8
8
 
9
- ## Executive Summary
10
-
11
- - This prompt loads .NET expertise into any agent's context — no dedicated .NET agent needed, per your org's decision/security log if one exists.
12
- - Covers .NET 10, ASP.NET Core, Azure Functions (isolated worker), Entity Framework Core, and xUnit testing.
13
- - Use this when any dev agent is working on `{BUSINESS_NAME}` or other .NET projects. (`{BUSINESS_NAME}`: resolve from `.arcane.json` / the feature or PRD frontmatter; ask if unset.) For the dev-agent roster, reference [[agent-policies]] / [[naming-conventions]] rather than assuming specific personas.
14
- - Combines with `spell-implement` for .NET-specific autonomous development loops.
15
-
16
- ---
17
-
18
- Load .NET expert context and assist with the specified topic.
19
-
20
- Context to apply:
21
-
22
- ### .NET Project Standards
23
-
24
- - **Target Framework:** .NET 10 (latest LTS)
25
- - **API Pattern:** ASP.NET Core Minimal APIs (preferred) or Controllers (existing projects)
26
- - **Serverless:** Azure Functions v4 isolated worker model (NOT in-process)
27
- - **ORM:** Entity Framework Core with code-first migrations
28
- - **Testing:** xUnit + FluentAssertions + Moq (or NSubstitute)
29
- - **DI:** Built-in Microsoft.Extensions.DependencyInjection
30
- - **Logging:** Serilog with structured logging (JSON output)
31
- - **Configuration:** Options pattern (`IOptions<T>`) — never read config directly
32
-
33
- ### Code Patterns
34
-
35
- ```csharp
36
- // Minimal API pattern
37
- app.MapGet("/api/items/{id}", async (int id, IItemService service) =>
38
- {
39
- var item = await service.GetByIdAsync(id);
40
- return item is null ? Results.NotFound() : Results.Ok(item);
41
- });
42
-
43
- // Service registration
44
- builder.Services.AddScoped<IItemService, ItemService>();
45
- builder.Services.Configure<ItemOptions>(builder.Configuration.GetSection("Items"));
46
-
47
- // Azure Function (isolated worker)
48
- [Function("ProcessItem")]
49
- public async Task<HttpResponseData> Run(
50
- [HttpTrigger(AuthorizationLevel.Function, "post")] HttpRequestData req)
51
- {
52
- var item = await req.ReadFromJsonAsync<ItemRequest>();
53
- // Process...
54
- var response = req.CreateResponse(HttpStatusCode.OK);
55
- await response.WriteAsJsonAsync(result);
56
- return response;
57
- }
58
- ```
59
-
60
- ### Testing Patterns
61
-
62
- ```csharp
63
- // xUnit test with FluentAssertions
64
- public class ItemServiceTests
65
- {
66
- [Fact]
67
- public async Task GetById_WhenExists_ReturnsItem()
68
- {
69
- // Arrange
70
- var mockRepo = new Mock<IItemRepository>();
71
- mockRepo.Setup(r => r.GetByIdAsync(1))
72
- .ReturnsAsync(new Item { Id = 1, Name = "Test" });
73
- var service = new ItemService(mockRepo.Object);
74
-
75
- // Act
76
- var result = await service.GetByIdAsync(1);
77
-
78
- // Assert
79
- result.Should().NotBeNull();
80
- result!.Name.Should().Be("Test");
81
- }
82
- }
83
- ```
84
-
85
- ### Common Pitfalls to Avoid
86
-
87
- - **Don't use `HttpClient` directly** — use `IHttpClientFactory` with named/typed clients.
88
- - **Don't catch `Exception`** — catch specific types. Let unhandled exceptions bubble to middleware.
89
- - **Don't use `async void`** — always `async Task`. Exception: event handlers.
90
- - **Don't block on async** — never use `.Result` or `.Wait()`. Use `await`.
91
- - **Don't put business logic in controllers/endpoints** — use a service layer.
92
- - **Don't use `DateTime.Now`** — use `DateTimeOffset.UtcNow` or inject `TimeProvider`.
93
- - **Don't store secrets in appsettings.json** — use User Secrets (dev) or Azure Key Vault (prod).
94
-
95
- ### NuGet Package Standards
96
-
97
- Always pin exact versions. Preferred packages:
98
- - `Microsoft.EntityFrameworkCore` — ORM
99
- - `Serilog.AspNetCore` — logging
100
- - `FluentValidation` — input validation
101
- - `Polly` — resilience and retry policies
102
- - `Mapster` or `AutoMapper` — object mapping
103
- - `Swashbuckle.AspNetCore` — OpenAPI/Swagger
104
-
105
- ### Azure-Specific Patterns
106
-
107
- - Use Managed Identity for Azure service authentication (no connection strings with keys).
108
- - Use Azure Key Vault references in App Service/Functions configuration.
109
- - Use Application Insights for telemetry (`AddApplicationInsightsTelemetry()`).
110
- - Use Azure Storage Queue or Service Bus for async messaging (not HTTP callbacks).
111
-
112
- Workflow:
113
-
114
- 1. **Identify the .NET topic** — what does the developer need help with?
115
- 2. **Apply the patterns above** — use the standards as constraints.
116
- 3. **Provide implementation guidance** — specific code, not just concepts.
117
- 4. **Include tests** — every code suggestion includes corresponding xUnit tests.
118
- 5. **Flag deviations** — if the existing codebase doesn't follow these patterns, note it but don't refactor without approval.
9
+ This prompt is the Arcane `spell-dotnet-expert` spell. Read [`.arcane/spells/spell-dotnet-expert.md`](../../.arcane/spells/spell-dotnet-expert.md) and follow it as the complete workflow.
@@ -6,249 +6,4 @@ argument-hint: Which store(s) to deploy to (ios, android, or both) and whether t
6
6
  agent: agent
7
7
  ---
8
8
 
9
- ## Executive Summary
10
-
11
- - This spell documents the **EAS Build + EAS Submit** pipeline end to end for both the Apple App Store
12
- and Google Play — initial one-time setup, repeat deployments, and known pitfalls, in that order, for
13
- each store.
14
- - Roughly 80% of the material (credentials, `eas.json` profile shape, build-number handling, OTA rules)
15
- is shared between the two stores; only the store-console work genuinely diverges. Covered once in a
16
- shared preamble, then two store-specific sections.
17
- - **Deliberately scoped to EAS Build + EAS Submit** — no local Xcode, Xcode Cloud, or Fastlane coverage.
18
- That scope is what keeps every step concrete and copy-pasteable.
19
- - Every lesson here was hit for real across two dogfooding runs (a first-ever App Store submission, then
20
- a from-zero Google Play listing to a live production release) — none is general knowledge restated.
21
- - Durable, store-specific platform facts are documented once in
22
- [`mobile-release-standards.md`](../../.arcane/governance/mobile-release-standards.md) and cited here
23
- by `MR-nn` ID; verification discipline is documented once in
24
- [`external-verification-standards.md`](../../.arcane/governance/external-verification-standards.md)
25
- and cited by `EV-nn` ID. This spell does not restate either.
26
-
27
- ---
28
-
29
- ## Placeholders
30
-
31
- Every placeholder below follows the same resolution rule: pull it from `.arcane.json`, the invoking
32
- frontmatter, or the repo's own existing `app.json`/`eas.json`; if it is not resolvable from any of those,
33
- **ask** — never assume. A wrong guess here produces a rejected submission or a build tied to the wrong
34
- account, not a local mistake.
35
-
36
- | Placeholder | What it is | Resolution rule |
37
- | --- | --- | --- |
38
- | `{IOS_BUNDLE_ID}` | The iOS bundle identifier. | Resolve from `app.json`'s `expo.ios.bundleIdentifier`; if unset, ask. |
39
- | `{APPLE_TEAM_ID}` | The Apple Developer Team ID. | Resolve from `eas.json` or the Apple Developer account; if unset, ask. |
40
- | `{ASC_APP_ID}` | The App Store Connect App ID (`ascAppId`). | Resolve from `eas.json`'s `submit.production.ios` block, or App Store Connect's own app record; if unset, ask. |
41
- | `{APPLE_ID_EMAIL}` | The Apple ID email used to authenticate to App Store Connect. | Resolve from `eas.json`, or ask — never assume which Apple ID owns the account. |
42
- | `{EAS_PROJECT_SLUG}` | The EAS project ID/slug. | Resolve from `app.json`'s `expo.extra.eas.projectId` or `eas init` output; if unset, ask. |
43
- | `{ANDROID_PACKAGE}` | The Android application ID / package name. | Resolve from `app.json`'s `expo.android.package`; if unset, ask. |
44
- | `{ORG_NAME}` | The Expo/EAS organization name, if the project belongs to one. | Resolve from `eas.json` or the EAS dashboard; if not applicable, omit. |
45
-
46
- ## Context files
47
-
48
- - [governance/mobile-release-standards.md](../../.arcane/governance/mobile-release-standards.md) —
49
- every `MR-nn` rule cited below. Rules are **cited by ID only** in this spell, never restated. **If the
50
- file is not installed**, this spell still runs in full — findings just cite each check as `MR-nn
51
- (rationale unavailable — install the standards doc)` instead of linking to it.
52
- - [governance/external-verification-standards.md](../../.arcane/governance/external-verification-standards.md) —
53
- every `EV-nn` rule cited below, cited by ID only. **If the file is not installed**, this spell still
54
- runs, and still re-reads actual state rather than trusting a console's own success signal — it just
55
- cites those checks as `EV-nn (rationale unavailable — install the standards doc)`.
56
-
57
- ---
58
-
59
- ## Shared EAS Preamble (both stores)
60
-
61
- This section is common setup both stores' deployments depend on. Do it once.
62
-
63
- ### `eas.json` profile structure
64
-
65
- ```json
66
- {
67
- "build": {
68
- "production": {
69
- "autoIncrement": true
70
- }
71
- },
72
- "submit": {
73
- "production": {
74
- "ios": {
75
- "appleId": "{APPLE_ID_EMAIL}",
76
- "ascAppId": "{ASC_APP_ID}",
77
- "appleTeamId": "{APPLE_TEAM_ID}"
78
- },
79
- "android": {
80
- "serviceAccountKeyPath": "./path/to/service-account.json",
81
- "track": "production"
82
- }
83
- }
84
- }
85
- }
86
- ```
87
-
88
- - `appVersionSource: "local"` (in `app.json`'s `expo` block) plus `production.autoIncrement: true` means
89
- build numbers auto-increment on every build — no manual version bump needed for a routine release.
90
- - Credentials for both platforms can be **remote, EAS-managed** — no local Mac or Xcode required for iOS
91
- signing (Distribution Certificate, Provisioning Profile, Push Notifications key are all generated and
92
- held by EAS), and no local Android keystore file required either.
93
-
94
- ### Cross-platform lessons (apply to every release, either store)
95
-
96
- - **Never ship a native rebuild while a submission is in review** just to carry a JS-only change — it
97
- can cost the queue position. Hold the change and ship it as an OTA update after the verdict lands.
98
- - **A reviewer's first cold launch must already be correct.** A review build has to carry the work
99
- natively; it cannot rely on an OTA update being fetched, because of the next rule.
100
- - **OTA updates apply on the next launch, not the current one** — the client downloads in the background
101
- and swaps on relaunch. Do not diagnose a "stuck" update until after two full quit-and-reopen cycles.
102
- - **🔴 Bundler transform caches do not key on `EXPO_PUBLIC_*` env vars.** On a persistent (self-hosted)
103
- build runner, the cache survives between runs, so an update published to one channel can ship
104
- another channel's inlined config — for example, a production build silently pointing at a development
105
- API. Pass `--clear-cache` on the publish lane, and verify by comparing the published `launchAsset`
106
- hashes across channels: identical hashes for two channels that differ by at least one env var is proof
107
- of the defect. **A green publish/build step is not evidence here (`EV-02`)** — assert against the
108
- actual published asset.
109
- - **When a feature is removed or renamed, both stores' screenshots and descriptions are in the blast
110
- radius.** Store metadata outlives the code it depicts, and it's the first thing a reviewer opens.
111
-
112
- ---
113
-
114
- ## Apple App Store
115
-
116
- ### Initial one-time setup
117
-
118
- 1. Confirm Apple Developer Program enrollment is active.
119
- 2. Create the App Store Connect app record: name, `{IOS_BUNDLE_ID}`, SKU, and user access.
120
- 3. Set the `eas.json` build + submit profile structure shown in the preamble above, filling in
121
- `{APPLE_ID_EMAIL}`, `{ASC_APP_ID}`, and `{APPLE_TEAM_ID}`.
122
- 4. Generate remote, EAS-managed credentials (Distribution Certificate, Provisioning Profile, Push
123
- Notifications key) — no local Mac or Xcode needed.
124
- 5. Create an App Store Connect API key for non-interactive submits (choose EAS-managed vs.
125
- manually-uploaded per the operator's preference).
126
- 6. If App Store Connect already has this bundle ID linked and EAS's automatic capability sync fails
127
- against it, toggle the affected capabilities manually in the Apple Developer console's Identifiers
128
- page instead of retrying the automated sync.
129
-
130
- ### Repeat deployments
131
-
132
- ```bash
133
- eas build --platform ios --profile production
134
- eas submit --platform ios --profile production --latest
135
- ```
136
-
137
- Build numbers auto-increment per the preamble's `eas.json` config — no manual version bump needed.
138
- Realistic wait times: build ~10-20 minutes; Apple's binary processing ~5-10 minutes before the build is
139
- visible in TestFlight. A build not yet visible immediately after `eas submit` reports success is
140
- ordinarily processing lag, not a failed submission — verify by checking TestFlight directly before
141
- concluding otherwise (`EV-06`).
142
-
143
- ### Known pitfalls
144
-
145
- - **`Failed to patch capabilities: X ON, Y OFF`** — happens when an App Store Connect app is already
146
- linked to the bundle ID and Apple rejects EAS's automatic capability sync. Fix: `EXPO_NO_CAPABILITY_SYNC=1`
147
- as a build-time env var, combined with the manual capability toggle from setup step 6.
148
- - **`Command must be re-run to pick up new updates configuration`** — EAS auto-installs `expo-updates`
149
- mid-build the first time it's needed. Simply re-run the exact same `eas build` command; no
150
- configuration change is required on your end.
151
- - **A transient Apple "Internal Server Error" during App Store Connect API key creation** clears on a
152
- simple retry — no code or configuration change needed.
153
-
154
- ---
155
-
156
- ## Google Play
157
-
158
- Read this before anything else: **passing review on one Google Play track never promotes the binary to
159
- any other track** (`MR-01`) — internal testing has no review at all, while closed, open, and production
160
- each require one independently.
161
-
162
- ### Initial one-time setup
163
-
164
- 1. Create the Google Play Console app listing.
165
- 2. **Set the country/region list on every track you plan to release to, before building that release** —
166
- a fresh production track starts with zero countries and fails with a generic, un-actionable error
167
- otherwise (`MR-02`).
168
- 3. Reuse the App Store's listing copy and screenshots as a starting point — it keeps the two stores
169
- consistent — but re-review each asset against the actually shipped binary before publishing; a
170
- screenshot advertising a since-removed feature is a common miss from blind reuse. Image dimensions
171
- differ between stores, so assets need re-export, not re-invention.
172
- 4. Set up a Google Play service account and reference its key from `eas.json`'s
173
- `submit.production.android.serviceAccountKeyPath`.
174
- 5. Complete the IARC content-rating questionnaire one question at a time, and re-read the full form
175
- after any change to the app's category (`MR-04`).
176
- 6. Complete the data-safety declaration using "leaves the device" as the collection test, and confirm it
177
- agrees with the App Store's own App Privacy answers for the same app (`MR-05`).
178
- 7. Provide reviewer/demo-account access — one working account per app, described in prose for any
179
- additional account types (`MR-07`).
180
- 8. If Android developer verification is pending, correct the public developer address at its D-U-N-S
181
- source and let it propagate **before** confirming it in the Play console — confirming first locks in
182
- whatever address is currently on file (`MR-11`). Start this early: verification has a hard deadline,
183
- and D&B propagation can take days to weeks.
184
-
185
- ### Repeat deployments
186
-
187
- ```bash
188
- eas build --platform android --profile production
189
- eas submit --platform android --profile production --latest
190
- ```
191
-
192
- **Saving a console edit is not submitting it** — Google Play stages edits until an explicit "send
193
- changes for review" (or "save and publish") action, each with its own confirmation dialog (`MR-03`). A
194
- workflow that stops at "Save" ships nothing.
195
-
196
- Observed review latencies, for expectation-setting: internal testing is instant (no review); a first
197
- closed-testing review is roughly one day; production review is quoted as "typically within 7 days," and
198
- materially faster when the identical binary already cleared a closed-track review. Treat a release not
199
- yet visible immediately after submission as this ordinary review latency, not a failure, absent a
200
- console error stating otherwise (`EV-06`).
201
-
202
- ### Known pitfalls
203
-
204
- - **🔴 Play Console silently drops synthetic browser input.** Programmatic form input and coordinate
205
- clicks frequently do not register — the control appears set, the save succeeds, and nothing persists
206
- (seen on both app-access contact fields and country checkboxes). Before saving, read the page's own
207
- state readout (a "Targeted (N)" filter chip, "Release notes provided for N languages," a track's
208
- country-count summary); if the number disagrees with intent, hand the step to a human rather than
209
- retrying the same automated input (`EV-01`/`EV-03`).
210
- - **The "no deobfuscation file" warning** appears on every release and is benign and permanent until
211
- mapping-file upload is wired up — it is not a sign of a broken build (`MR-08`).
212
- - **🔴 The signing certificate an installed app presents can differ from every console page you'd
213
- naturally check.** Play App Signing plus "automatic protection" can make anything keyed to a
214
- `(package, SHA-1)` pair — Maps, Google Sign-In, App Links/`assetlinks.json` — fail on Play-delivered
215
- installs while working on sideloads. Never infer the SHA-1; read it from `adb logcat` against an
216
- actual Play-delivered install (`MR-09`, `EV-01`). Zero traffic in a provider's usage metrics is not
217
- evidence the app isn't calling it — an auth failure can occur before any billable request is logged —
218
- and a working browser-based OAuth flow proves nothing about certificate matching.
219
- - **Android OAuth clients are keyed to one `(package, SHA-1)` pair each** — a Play-signed install, an
220
- upload-signed sideload, and a `.dev` variant each need their own client. New clients also ship with
221
- "Enable custom URI scheme" off, which fails with a visible `Error 400: invalid_request` until toggled
222
- on (`MR-10`).
223
- - **Audit what the built artifact actually declares** (`aapt2 dump permissions`, or an equivalent
224
- manifest inspection) before submission — a dependency that's installed but no longer called still
225
- contributes its permissions, and removing one means removing the dependency, re-verified against a
226
- fresh build (`MR-12`).
227
- - **Android notification icons need a dedicated monochrome, white-on-transparent small icon**, shipped
228
- in a build — there's no OTA path for this. A "broken" icon symptom should be checked in the
229
- notification shade, not the heads-up banner, since some OEM skins legitimately omit the small icon
230
- from banners only (`MR-13`).
231
- - **Android's native `AlertDialog` caps at three buttons.** A menu built on `Alert.alert` past that cap
232
- silently loses the overflow — typically the *Cancel* row. Use a real bottom sheet instead for any menu
233
- that could exceed three options (`MR-14`).
234
- - **Locale lists differ between the stores.** Release notes are per-language; resolve locale coverage
235
- against each store's own catalogue rather than copying the other store's list (`MR-06`).
236
-
237
- ---
238
-
239
- ## Rules
240
-
241
- This spell defers entirely to
242
- [governance/mobile-release-standards.md](../../.arcane/governance/mobile-release-standards.md) for what
243
- each store-specific platform fact means and why, and to
244
- [governance/external-verification-standards.md](../../.arcane/governance/external-verification-standards.md)
245
- for how any claimed success is verified. Findings and steps in this spell cite rule IDs from both; they
246
- do not re-explain them. Where the two disagree with what this spell says to do, the governance docs win.
247
-
248
- ## Related
249
-
250
- - **Consumes from:** whatever workflow builds and versions the app before deployment (in this
251
- repository's own stack, `spell-implement`/`spell-ship`) — this spell deploys an already-built app to
252
- the stores, it does not build the app's features.
253
- - [Mobile Release Standards](../../.arcane/governance/mobile-release-standards.md)
254
- - [External Verification Standards](../../.arcane/governance/external-verification-standards.md)
9
+ This prompt is the Arcane `spell-eas-store-deploy` spell. Read [`.arcane/spells/spell-eas-store-deploy.md`](../../.arcane/spells/spell-eas-store-deploy.md) and follow it as the complete workflow.