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.
- package/README.md +1 -1
- package/dist/assets/.agents/skills/spell-address-review/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-adopt-docs/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-arcane-version/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-architect/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-brainstorm/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-bug/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-bump/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-check-drift/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-close-session/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-commit-work/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-compliance/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-create-pull-request/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-document/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-dotnet-expert/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-eas-store-deploy/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-enchant/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-explain-concept/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-feedback/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-full-cycle/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-generate-bot-icons/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-implement/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-make-discoverable/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-manifest/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-open-session/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-plan/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-present-arcane/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-product-review/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-review/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-review-batch/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-save-idea/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-scope/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-scry/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-security-review/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-ship/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-status/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-suggest-feature/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-summon-venture/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-sync-pull-request/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-test/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-todo/SKILL.md +6 -0
- package/dist/assets/.agents/skills/spell-verification-ledger/SKILL.md +6 -0
- package/dist/assets/.arcane/governance/development-methodology.md +6 -6
- package/dist/assets/.arcane/governance/git-conventions.md +2 -2
- package/dist/assets/.arcane/governance/portable-bootstrap.md +1 -0
- package/dist/assets/.arcane/governance/product-excellence-standards.md +1 -1
- package/dist/assets/.arcane/governance/spell-authoring-standards.md +9 -1
- package/dist/assets/.arcane/governance/universal-agent-rules.md +7 -0
- package/dist/assets/.arcane/spells/spell-address-review.md +115 -0
- package/dist/assets/.arcane/spells/spell-adopt-docs.md +158 -0
- package/dist/assets/.arcane/spells/spell-arcane-version.md +87 -0
- package/dist/assets/.arcane/spells/spell-architect.md +117 -0
- package/dist/assets/.arcane/spells/spell-brainstorm.md +125 -0
- package/dist/assets/.arcane/spells/spell-bug.md +123 -0
- package/dist/assets/.arcane/spells/spell-bump.md +82 -0
- package/dist/assets/.arcane/spells/spell-check-drift.md +118 -0
- package/dist/assets/.arcane/spells/spell-close-session.md +266 -0
- package/dist/assets/.arcane/spells/spell-commit-work.md +279 -0
- package/dist/assets/.arcane/spells/spell-compliance.md +130 -0
- package/dist/assets/.arcane/spells/spell-create-pull-request.md +224 -0
- package/dist/assets/.arcane/spells/spell-document.md +84 -0
- package/dist/assets/.arcane/spells/spell-dotnet-expert.md +118 -0
- package/dist/assets/.arcane/spells/spell-eas-store-deploy.md +254 -0
- package/dist/assets/.arcane/spells/spell-enchant.md +386 -0
- package/dist/assets/.arcane/spells/spell-explain-concept.md +70 -0
- package/dist/assets/.arcane/spells/spell-feedback.md +138 -0
- package/dist/assets/.arcane/spells/spell-full-cycle.md +253 -0
- package/dist/assets/.arcane/spells/spell-generate-bot-icons.md +85 -0
- package/dist/assets/.arcane/spells/spell-implement.md +109 -0
- package/dist/assets/.arcane/spells/spell-make-discoverable.md +293 -0
- package/dist/assets/.arcane/spells/spell-manifest.md +148 -0
- package/dist/assets/.arcane/spells/spell-open-session.md +154 -0
- package/dist/assets/.arcane/spells/spell-plan.md +160 -0
- package/dist/assets/.arcane/spells/spell-present-arcane.md +189 -0
- package/dist/assets/.arcane/spells/spell-product-review.md +98 -0
- package/dist/assets/.arcane/spells/spell-review-batch.md +113 -0
- package/dist/assets/.arcane/spells/spell-review.md +142 -0
- package/dist/assets/.arcane/spells/spell-save-idea.md +117 -0
- package/dist/assets/.arcane/spells/spell-scope.md +266 -0
- package/dist/assets/.arcane/spells/spell-scry.md +124 -0
- package/dist/assets/.arcane/spells/spell-security-review.md +152 -0
- package/dist/assets/.arcane/spells/spell-ship.md +106 -0
- package/dist/assets/.arcane/spells/spell-status.md +86 -0
- package/dist/assets/.arcane/spells/spell-suggest-feature.md +122 -0
- package/dist/assets/.arcane/spells/spell-summon-venture.md +110 -0
- package/dist/assets/.arcane/spells/spell-sync-pull-request.md +161 -0
- package/dist/assets/.arcane/spells/spell-test.md +88 -0
- package/dist/assets/.arcane/spells/spell-todo.md +166 -0
- package/dist/assets/.arcane/spells/spell-verification-ledger.md +102 -0
- package/dist/assets/.claude/commands/spell-address-review.md +2 -2
- package/dist/assets/.claude/commands/spell-adopt-docs.md +2 -2
- package/dist/assets/.claude/commands/spell-arcane-version.md +2 -2
- package/dist/assets/.claude/commands/spell-architect.md +2 -2
- package/dist/assets/.claude/commands/spell-brainstorm.md +2 -2
- package/dist/assets/.claude/commands/spell-bug.md +2 -2
- package/dist/assets/.claude/commands/spell-bump.md +2 -2
- package/dist/assets/.claude/commands/spell-check-drift.md +2 -2
- package/dist/assets/.claude/commands/spell-close-session.md +2 -2
- package/dist/assets/.claude/commands/spell-commit-work.md +2 -2
- package/dist/assets/.claude/commands/spell-compliance.md +2 -2
- package/dist/assets/.claude/commands/spell-create-pull-request.md +2 -2
- package/dist/assets/.claude/commands/spell-document.md +2 -2
- package/dist/assets/.claude/commands/spell-dotnet-expert.md +2 -2
- package/dist/assets/.claude/commands/spell-eas-store-deploy.md +2 -2
- package/dist/assets/.claude/commands/spell-enchant.md +2 -2
- package/dist/assets/.claude/commands/spell-explain-concept.md +2 -2
- package/dist/assets/.claude/commands/spell-feedback.md +2 -2
- package/dist/assets/.claude/commands/spell-full-cycle.md +2 -2
- package/dist/assets/.claude/commands/spell-generate-bot-icons.md +2 -2
- package/dist/assets/.claude/commands/spell-implement.md +2 -2
- package/dist/assets/.claude/commands/spell-make-discoverable.md +2 -2
- package/dist/assets/.claude/commands/spell-manifest.md +2 -2
- package/dist/assets/.claude/commands/spell-open-session.md +2 -2
- package/dist/assets/.claude/commands/spell-plan.md +2 -2
- package/dist/assets/.claude/commands/spell-present-arcane.md +2 -2
- package/dist/assets/.claude/commands/spell-product-review.md +2 -2
- package/dist/assets/.claude/commands/spell-review-batch.md +2 -2
- package/dist/assets/.claude/commands/spell-review.md +2 -2
- package/dist/assets/.claude/commands/spell-save-idea.md +2 -2
- package/dist/assets/.claude/commands/spell-scope.md +2 -2
- package/dist/assets/.claude/commands/spell-scry.md +2 -2
- package/dist/assets/.claude/commands/spell-security-review.md +2 -2
- package/dist/assets/.claude/commands/spell-ship.md +2 -2
- package/dist/assets/.claude/commands/spell-status.md +2 -2
- package/dist/assets/.claude/commands/spell-suggest-feature.md +2 -2
- package/dist/assets/.claude/commands/spell-summon-venture.md +2 -2
- package/dist/assets/.claude/commands/spell-sync-pull-request.md +2 -2
- package/dist/assets/.claude/commands/spell-test.md +2 -2
- package/dist/assets/.claude/commands/spell-todo.md +2 -2
- package/dist/assets/.claude/commands/spell-verification-ledger.md +2 -2
- package/dist/assets/.github/instructions/agent-output.instructions.md +14 -13
- package/dist/assets/.github/prompts/spell-address-review.prompt.md +1 -107
- package/dist/assets/.github/prompts/spell-adopt-docs.prompt.md +1 -150
- package/dist/assets/.github/prompts/spell-arcane-version.prompt.md +1 -79
- package/dist/assets/.github/prompts/spell-architect.prompt.md +1 -109
- package/dist/assets/.github/prompts/spell-brainstorm.prompt.md +1 -117
- package/dist/assets/.github/prompts/spell-bug.prompt.md +1 -115
- package/dist/assets/.github/prompts/spell-bump.prompt.md +1 -74
- package/dist/assets/.github/prompts/spell-check-drift.prompt.md +1 -110
- package/dist/assets/.github/prompts/spell-close-session.prompt.md +1 -258
- package/dist/assets/.github/prompts/spell-commit-work.prompt.md +1 -270
- package/dist/assets/.github/prompts/spell-compliance.prompt.md +1 -122
- package/dist/assets/.github/prompts/spell-create-pull-request.prompt.md +1 -215
- package/dist/assets/.github/prompts/spell-document.prompt.md +1 -76
- package/dist/assets/.github/prompts/spell-dotnet-expert.prompt.md +1 -110
- package/dist/assets/.github/prompts/spell-eas-store-deploy.prompt.md +1 -246
- package/dist/assets/.github/prompts/spell-enchant.prompt.md +1 -378
- package/dist/assets/.github/prompts/spell-explain-concept.prompt.md +1 -62
- package/dist/assets/.github/prompts/spell-feedback.prompt.md +1 -130
- package/dist/assets/.github/prompts/spell-full-cycle.prompt.md +1 -245
- package/dist/assets/.github/prompts/spell-generate-bot-icons.prompt.md +1 -77
- package/dist/assets/.github/prompts/spell-implement.prompt.md +1 -101
- package/dist/assets/.github/prompts/spell-make-discoverable.prompt.md +1 -285
- package/dist/assets/.github/prompts/spell-manifest.prompt.md +1 -140
- package/dist/assets/.github/prompts/spell-open-session.prompt.md +1 -146
- package/dist/assets/.github/prompts/spell-plan.prompt.md +1 -152
- package/dist/assets/.github/prompts/spell-present-arcane.prompt.md +1 -181
- package/dist/assets/.github/prompts/spell-product-review.prompt.md +1 -90
- package/dist/assets/.github/prompts/spell-review-batch.prompt.md +1 -105
- package/dist/assets/.github/prompts/spell-review.prompt.md +1 -134
- package/dist/assets/.github/prompts/spell-save-idea.prompt.md +1 -109
- package/dist/assets/.github/prompts/spell-scope.prompt.md +1 -258
- package/dist/assets/.github/prompts/spell-scry.prompt.md +1 -116
- package/dist/assets/.github/prompts/spell-security-review.prompt.md +1 -144
- package/dist/assets/.github/prompts/spell-ship.prompt.md +1 -98
- package/dist/assets/.github/prompts/spell-status.prompt.md +1 -78
- package/dist/assets/.github/prompts/spell-suggest-feature.prompt.md +1 -114
- package/dist/assets/.github/prompts/spell-summon-venture.prompt.md +1 -102
- package/dist/assets/.github/prompts/spell-sync-pull-request.prompt.md +1 -152
- package/dist/assets/.github/prompts/spell-test.prompt.md +1 -80
- package/dist/assets/.github/prompts/spell-todo.prompt.md +1 -158
- package/dist/assets/.github/prompts/spell-verification-ledger.prompt.md +1 -94
- package/dist/index.js +195 -49
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- /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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|