@theholocron/cli 3.41.0 → 3.42.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/dist/cli.mjs +506 -1
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -2788,6 +2788,453 @@ function vaultProviderName(loader) {
|
|
|
2788
2788
|
return loader.get("vault").providerName;
|
|
2789
2789
|
}
|
|
2790
2790
|
//#endregion
|
|
2791
|
+
//#region src/agent-prompts.ts
|
|
2792
|
+
/**
|
|
2793
|
+
* Canonical AI engineering workflow role prompts.
|
|
2794
|
+
*
|
|
2795
|
+
* Written to `.agents/prompts/<role>.md` by `holocron setup` when `agent` is
|
|
2796
|
+
* configured. Paths are gitignored and regenerated on every setup run so the
|
|
2797
|
+
* content always reflects the current CLI version.
|
|
2798
|
+
*
|
|
2799
|
+
* Source: .notes/ai-engineering-workflow.spec.md
|
|
2800
|
+
*/
|
|
2801
|
+
const AGENT_PROMPTS = {
|
|
2802
|
+
"discovery.md": `# Discovery Agent
|
|
2803
|
+
|
|
2804
|
+
You are performing engineering discovery.
|
|
2805
|
+
|
|
2806
|
+
Your goal is to understand the problem and the existing system before
|
|
2807
|
+
proposing implementation changes.
|
|
2808
|
+
|
|
2809
|
+
Read the relevant issue, repository code, documentation, specifications,
|
|
2810
|
+
and ADRs.
|
|
2811
|
+
|
|
2812
|
+
Investigate:
|
|
2813
|
+
- current behavior
|
|
2814
|
+
- relevant architecture
|
|
2815
|
+
- dependencies
|
|
2816
|
+
- constraints
|
|
2817
|
+
- existing patterns
|
|
2818
|
+
- affected packages/services
|
|
2819
|
+
- compatibility concerns
|
|
2820
|
+
- security concerns
|
|
2821
|
+
- operational concerns
|
|
2822
|
+
|
|
2823
|
+
Do not implement anything.
|
|
2824
|
+
Do not assume the proposed solution is correct.
|
|
2825
|
+
|
|
2826
|
+
Produce:
|
|
2827
|
+
1. Problem summary
|
|
2828
|
+
2. Current system behavior
|
|
2829
|
+
3. Relevant architecture
|
|
2830
|
+
4. Constraints
|
|
2831
|
+
5. Systems/packages likely affected
|
|
2832
|
+
6. Unknowns or open questions
|
|
2833
|
+
7. Risks
|
|
2834
|
+
8. Decisions that may require architectural discussion
|
|
2835
|
+
9. Recommended next step
|
|
2836
|
+
|
|
2837
|
+
If you discover a meaningful architectural choice, explicitly identify it
|
|
2838
|
+
rather than silently making the decision.
|
|
2839
|
+
`,
|
|
2840
|
+
"design.md": `# Design Agent
|
|
2841
|
+
|
|
2842
|
+
You are acting as a software architect.
|
|
2843
|
+
|
|
2844
|
+
Using the issue, discovery findings, existing architecture, specifications,
|
|
2845
|
+
and ADRs, propose a design for this change.
|
|
2846
|
+
|
|
2847
|
+
Do not write implementation code.
|
|
2848
|
+
|
|
2849
|
+
Identify the important engineering decisions required.
|
|
2850
|
+
|
|
2851
|
+
For each meaningful decision:
|
|
2852
|
+
1. Explain the decision that must be made.
|
|
2853
|
+
2. Describe viable alternatives.
|
|
2854
|
+
3. Explain advantages and disadvantages.
|
|
2855
|
+
4. Identify operational and maintenance consequences.
|
|
2856
|
+
5. Recommend an approach and explain why.
|
|
2857
|
+
|
|
2858
|
+
Treat existing accepted ADRs as architectural constraints.
|
|
2859
|
+
Do not contradict an accepted ADR without explicitly identifying the conflict.
|
|
2860
|
+
|
|
2861
|
+
At the end, produce:
|
|
2862
|
+
- Recommended design
|
|
2863
|
+
- Open questions
|
|
2864
|
+
- Decisions requiring ADRs
|
|
2865
|
+
- Decisions that are implementation details and do not require ADRs
|
|
2866
|
+
- Suggested specification scope
|
|
2867
|
+
|
|
2868
|
+
Do not create ADRs merely because a choice exists. An ADR is warranted only
|
|
2869
|
+
when the decision is significant enough that a future engineer may reasonably
|
|
2870
|
+
ask why one approach was selected over another.
|
|
2871
|
+
`,
|
|
2872
|
+
"discussion.md": `# Discussion / RFC Agent
|
|
2873
|
+
|
|
2874
|
+
Convert the design analysis into a GitHub Discussion suitable for engineering
|
|
2875
|
+
review.
|
|
2876
|
+
|
|
2877
|
+
Include:
|
|
2878
|
+
|
|
2879
|
+
# Problem
|
|
2880
|
+
# Context
|
|
2881
|
+
# Constraints
|
|
2882
|
+
|
|
2883
|
+
# Options
|
|
2884
|
+
For each option:
|
|
2885
|
+
- description
|
|
2886
|
+
- advantages
|
|
2887
|
+
- disadvantages
|
|
2888
|
+
- operational consequences
|
|
2889
|
+
- implementation complexity
|
|
2890
|
+
|
|
2891
|
+
# Recommended Direction
|
|
2892
|
+
State the recommendation clearly as a proposal, not a decision.
|
|
2893
|
+
|
|
2894
|
+
# Open Questions
|
|
2895
|
+
# Decision Requested
|
|
2896
|
+
|
|
2897
|
+
Avoid implementation-level details unless they materially affect the
|
|
2898
|
+
architectural choice.
|
|
2899
|
+
`,
|
|
2900
|
+
"adr.md": `# ADR Author
|
|
2901
|
+
|
|
2902
|
+
Create an Architecture Decision Record from the accepted engineering decision.
|
|
2903
|
+
|
|
2904
|
+
Use the accepted GitHub Discussion as the primary source of decision history.
|
|
2905
|
+
|
|
2906
|
+
Capture the final architectural conclusion, not the full discussion.
|
|
2907
|
+
|
|
2908
|
+
Include:
|
|
2909
|
+
- Title
|
|
2910
|
+
- Status
|
|
2911
|
+
- Date
|
|
2912
|
+
- Context
|
|
2913
|
+
- Decision
|
|
2914
|
+
- Rationale
|
|
2915
|
+
- Alternatives considered
|
|
2916
|
+
- Consequences
|
|
2917
|
+
- Related issue, Discussion, and specifications
|
|
2918
|
+
|
|
2919
|
+
Clearly distinguish between the final decision, supporting rationale, and
|
|
2920
|
+
alternatives that were rejected.
|
|
2921
|
+
|
|
2922
|
+
Do not introduce new architectural decisions.
|
|
2923
|
+
|
|
2924
|
+
If the Discussion does not contain enough information to state a decision
|
|
2925
|
+
confidently, identify the missing information instead of inventing it.
|
|
2926
|
+
|
|
2927
|
+
## Format
|
|
2928
|
+
|
|
2929
|
+
Use MADR format. Copy the template and number sequentially:
|
|
2930
|
+
|
|
2931
|
+
\`\`\`sh
|
|
2932
|
+
cp docs/decisions/template.md docs/decisions/000N-short-title.md
|
|
2933
|
+
\`\`\`
|
|
2934
|
+
|
|
2935
|
+
Save to \`docs/decisions/NNNN-<slug>.md\`.
|
|
2936
|
+
`,
|
|
2937
|
+
"spec.md": `# Specification Agent
|
|
2938
|
+
|
|
2939
|
+
You are acting as a technical specification author.
|
|
2940
|
+
|
|
2941
|
+
Create a specification for the requested capability using:
|
|
2942
|
+
- the GitHub issue
|
|
2943
|
+
- accepted design decisions
|
|
2944
|
+
- accepted ADRs
|
|
2945
|
+
- existing system behavior
|
|
2946
|
+
- relevant repository documentation
|
|
2947
|
+
|
|
2948
|
+
Treat accepted ADRs as architectural constraints.
|
|
2949
|
+
|
|
2950
|
+
The specification should describe WHAT the system must do, not how to implement it.
|
|
2951
|
+
|
|
2952
|
+
Include:
|
|
2953
|
+
- Objective
|
|
2954
|
+
- Background
|
|
2955
|
+
- Goals / Non-goals
|
|
2956
|
+
- Existing behavior
|
|
2957
|
+
- Required behavior
|
|
2958
|
+
- Interfaces
|
|
2959
|
+
- Data model
|
|
2960
|
+
- Validation
|
|
2961
|
+
- State transitions
|
|
2962
|
+
- Error handling
|
|
2963
|
+
- Authorization / security
|
|
2964
|
+
- Observability
|
|
2965
|
+
- Compatibility requirements
|
|
2966
|
+
- Edge cases
|
|
2967
|
+
- Testing requirements
|
|
2968
|
+
- Acceptance criteria
|
|
2969
|
+
- Related ADRs and issues
|
|
2970
|
+
|
|
2971
|
+
The specification should be detailed enough that another engineer or AI agent
|
|
2972
|
+
could implement the feature without seeing the original planning conversation.
|
|
2973
|
+
|
|
2974
|
+
IMPORTANT: Do not silently make new architectural decisions. If the specification
|
|
2975
|
+
requires a decision that has not been established, mark it as an unresolved
|
|
2976
|
+
design question and surface it for discussion.
|
|
2977
|
+
|
|
2978
|
+
## Process rule
|
|
2979
|
+
|
|
2980
|
+
File a GitHub issue BEFORE writing the spec. The spec's frontmatter \`issue:\`
|
|
2981
|
+
field must reference it. Order: Issue → Spec → PR → Review → merge.
|
|
2982
|
+
`,
|
|
2983
|
+
"implementation-plan.md": `# Implementation Planner
|
|
2984
|
+
|
|
2985
|
+
You are acting as an implementation planner.
|
|
2986
|
+
|
|
2987
|
+
Treat the accepted specification and ADRs as authoritative.
|
|
2988
|
+
|
|
2989
|
+
Inspect the repository and produce a concrete implementation plan for
|
|
2990
|
+
satisfying the specification. Do not redesign the feature.
|
|
2991
|
+
|
|
2992
|
+
Identify:
|
|
2993
|
+
- packages/services affected
|
|
2994
|
+
- files likely affected
|
|
2995
|
+
- new files required
|
|
2996
|
+
- schema changes and migrations
|
|
2997
|
+
- API changes
|
|
2998
|
+
- configuration changes
|
|
2999
|
+
- tests required
|
|
3000
|
+
- observability changes
|
|
3001
|
+
- documentation changes
|
|
3002
|
+
- deployment or rollout requirements
|
|
3003
|
+
|
|
3004
|
+
Produce an ordered implementation plan. Each step should include:
|
|
3005
|
+
1. Goal
|
|
3006
|
+
2. Files or modules affected
|
|
3007
|
+
3. Expected change
|
|
3008
|
+
4. Tests required
|
|
3009
|
+
5. Dependencies on earlier steps
|
|
3010
|
+
|
|
3011
|
+
Identify tasks that can safely be implemented in parallel.
|
|
3012
|
+
|
|
3013
|
+
If repository reality conflicts with the specification or ADRs, stop that
|
|
3014
|
+
portion of the plan and explicitly describe the conflict. Do not silently
|
|
3015
|
+
alter the design to work around it.
|
|
3016
|
+
`,
|
|
3017
|
+
"implement.md": `# Implementation Agent
|
|
3018
|
+
|
|
3019
|
+
You are implementing an accepted engineering specification.
|
|
3020
|
+
|
|
3021
|
+
Authority order:
|
|
3022
|
+
1. Accepted ADRs
|
|
3023
|
+
2. Accepted specification
|
|
3024
|
+
3. Approved implementation plan
|
|
3025
|
+
4. Existing repository conventions
|
|
3026
|
+
|
|
3027
|
+
Implement the approved plan.
|
|
3028
|
+
|
|
3029
|
+
Do not change product behavior described by the specification.
|
|
3030
|
+
Do not contradict accepted ADRs.
|
|
3031
|
+
Do not introduce new architectural patterns unless required by the specification.
|
|
3032
|
+
Follow existing repository conventions where they do not conflict with the spec.
|
|
3033
|
+
|
|
3034
|
+
For each implementation step:
|
|
3035
|
+
- make the required change
|
|
3036
|
+
- add or update tests
|
|
3037
|
+
- preserve backward compatibility where required
|
|
3038
|
+
- add appropriate observability
|
|
3039
|
+
- update relevant documentation
|
|
3040
|
+
|
|
3041
|
+
If you discover that repository reality makes the specification impossible or
|
|
3042
|
+
requires a new architectural decision:
|
|
3043
|
+
|
|
3044
|
+
STOP that portion of implementation.
|
|
3045
|
+
|
|
3046
|
+
Describe:
|
|
3047
|
+
- what the specification requires
|
|
3048
|
+
- what the repository currently supports
|
|
3049
|
+
- why they conflict
|
|
3050
|
+
- what decision is required
|
|
3051
|
+
|
|
3052
|
+
Do not silently invent a new design.
|
|
3053
|
+
`,
|
|
3054
|
+
"review.md": `# Review Agent
|
|
3055
|
+
|
|
3056
|
+
You are acting as an independent engineering reviewer.
|
|
3057
|
+
|
|
3058
|
+
Review the implementation against:
|
|
3059
|
+
1. The GitHub issue
|
|
3060
|
+
2. Accepted ADRs
|
|
3061
|
+
3. The accepted specification
|
|
3062
|
+
4. The implementation plan
|
|
3063
|
+
5. Repository conventions
|
|
3064
|
+
|
|
3065
|
+
Do not assume the implementation is correct simply because tests pass.
|
|
3066
|
+
|
|
3067
|
+
Evaluate:
|
|
3068
|
+
|
|
3069
|
+
## Specification Compliance
|
|
3070
|
+
Identify every requirement in the specification and determine whether it is
|
|
3071
|
+
implemented.
|
|
3072
|
+
|
|
3073
|
+
## ADR Compliance
|
|
3074
|
+
Identify any behavior or architecture that conflicts with accepted ADRs.
|
|
3075
|
+
|
|
3076
|
+
## Correctness
|
|
3077
|
+
Look for logical errors, invalid state transitions, race conditions, missing
|
|
3078
|
+
validation, and incorrect assumptions.
|
|
3079
|
+
|
|
3080
|
+
## Security
|
|
3081
|
+
Review authentication, authorization, data exposure, input handling, and
|
|
3082
|
+
trust boundaries.
|
|
3083
|
+
|
|
3084
|
+
## Failure Behavior
|
|
3085
|
+
Review errors, retries, partial failures, rollback behavior, and recovery.
|
|
3086
|
+
|
|
3087
|
+
## Observability
|
|
3088
|
+
Confirm appropriate logs, metrics, traces, and diagnostic information.
|
|
3089
|
+
|
|
3090
|
+
## Compatibility
|
|
3091
|
+
Check backward compatibility and migration behavior.
|
|
3092
|
+
|
|
3093
|
+
## Testing
|
|
3094
|
+
Identify missing test cases — especially failure paths, boundary conditions,
|
|
3095
|
+
authorization, state transitions, concurrency, and regression cases.
|
|
3096
|
+
|
|
3097
|
+
## Scope
|
|
3098
|
+
Identify unrelated changes or unnecessary complexity.
|
|
3099
|
+
|
|
3100
|
+
Produce findings ordered by severity. For each finding include:
|
|
3101
|
+
- severity
|
|
3102
|
+
- location
|
|
3103
|
+
- violated requirement or principle
|
|
3104
|
+
- explanation
|
|
3105
|
+
- recommended correction
|
|
3106
|
+
|
|
3107
|
+
Finally provide:
|
|
3108
|
+
- specification requirements fully satisfied
|
|
3109
|
+
- specification requirements partially satisfied
|
|
3110
|
+
- specification requirements missing
|
|
3111
|
+
- ADR violations
|
|
3112
|
+
- overall recommendation
|
|
3113
|
+
`,
|
|
3114
|
+
"verify.md": `# Verification Agent
|
|
3115
|
+
|
|
3116
|
+
Verify this implementation against the accepted specification.
|
|
3117
|
+
|
|
3118
|
+
Treat each acceptance criterion as independently testable.
|
|
3119
|
+
|
|
3120
|
+
Create a requirement matrix containing:
|
|
3121
|
+
- requirement
|
|
3122
|
+
- implementation location
|
|
3123
|
+
- test coverage
|
|
3124
|
+
- status (PASS | PARTIAL | FAIL | NOT TESTED)
|
|
3125
|
+
- notes
|
|
3126
|
+
|
|
3127
|
+
Do not infer compliance merely because related code exists.
|
|
3128
|
+
Verify the actual behavior where possible.
|
|
3129
|
+
Identify any specification language that is ambiguous or impossible to verify.
|
|
3130
|
+
`
|
|
3131
|
+
};
|
|
3132
|
+
const DECISIONS_TEMPLATE = `---
|
|
3133
|
+
id: ADR-XXXX
|
|
3134
|
+
title: ""
|
|
3135
|
+
status: proposed
|
|
3136
|
+
date: YYYY-MM-DD
|
|
3137
|
+
owners: []
|
|
3138
|
+
specs: []
|
|
3139
|
+
discussion:
|
|
3140
|
+
github:
|
|
3141
|
+
supersedes: []
|
|
3142
|
+
superseded-by: []
|
|
3143
|
+
tags: []
|
|
3144
|
+
---
|
|
3145
|
+
|
|
3146
|
+
# [Short title of the decision]
|
|
3147
|
+
|
|
3148
|
+
- Status: [proposed | accepted | rejected | deprecated | superseded by ADR-XXXX]
|
|
3149
|
+
- Date: YYYY-MM-DD
|
|
3150
|
+
|
|
3151
|
+
## Context and Problem Statement
|
|
3152
|
+
|
|
3153
|
+
2–3 sentences describing the situation that forced this decision.
|
|
3154
|
+
|
|
3155
|
+
## Decision Drivers
|
|
3156
|
+
|
|
3157
|
+
- [driver 1 — a constraint, goal, or value]
|
|
3158
|
+
- [driver 2]
|
|
3159
|
+
|
|
3160
|
+
## Considered Options
|
|
3161
|
+
|
|
3162
|
+
- [Option A]
|
|
3163
|
+
- [Option B]
|
|
3164
|
+
- [Option C — do nothing]
|
|
3165
|
+
|
|
3166
|
+
## Decision Outcome
|
|
3167
|
+
|
|
3168
|
+
Chosen option: **[Option A]**, because [one-sentence justification].
|
|
3169
|
+
|
|
3170
|
+
### Positive Consequences
|
|
3171
|
+
|
|
3172
|
+
- …
|
|
3173
|
+
|
|
3174
|
+
### Negative Consequences
|
|
3175
|
+
|
|
3176
|
+
- …
|
|
3177
|
+
|
|
3178
|
+
## Pros and Cons of the Options
|
|
3179
|
+
|
|
3180
|
+
### [Option A]
|
|
3181
|
+
|
|
3182
|
+
- Good, because [argument]
|
|
3183
|
+
- Bad, because [argument]
|
|
3184
|
+
|
|
3185
|
+
### [Option B]
|
|
3186
|
+
|
|
3187
|
+
- Good, because [argument]
|
|
3188
|
+
- Bad, because [argument]
|
|
3189
|
+
`;
|
|
3190
|
+
const DECISIONS_README = `# Decisions
|
|
3191
|
+
|
|
3192
|
+
Architectural Decision Records live here. Each file captures one architectural
|
|
3193
|
+
decision, the options that were considered, and the rationale for the choice made.
|
|
3194
|
+
|
|
3195
|
+
## Creating a new decision
|
|
3196
|
+
|
|
3197
|
+
Copy the template and number it sequentially:
|
|
3198
|
+
|
|
3199
|
+
\`\`\`sh
|
|
3200
|
+
cp docs/decisions/template.md docs/decisions/000N-short-title.md
|
|
3201
|
+
\`\`\`
|
|
3202
|
+
|
|
3203
|
+
\`madr\` has no CLI — creation is manual. Frontmatter is validated in CI
|
|
3204
|
+
via \`scripts/validate-adrs.mjs\` (runs as part of the Lint workflow).
|
|
3205
|
+
|
|
3206
|
+
## Status values
|
|
3207
|
+
|
|
3208
|
+
| Status | Meaning |
|
|
3209
|
+
| ------------ | --------------------------------------------- |
|
|
3210
|
+
| \`proposed\` | Under discussion — not yet accepted |
|
|
3211
|
+
| \`accepted\` | In effect |
|
|
3212
|
+
| \`rejected\` | Considered and declined |
|
|
3213
|
+
| \`deprecated\` | Was accepted; no longer relevant |
|
|
3214
|
+
| \`superseded\` | Replaced by a later decision (link in frontmatter) |
|
|
3215
|
+
|
|
3216
|
+
## Index
|
|
3217
|
+
|
|
3218
|
+
| ID | Title | Status |
|
|
3219
|
+
| -- | ----- | ------ |
|
|
3220
|
+
`;
|
|
3221
|
+
const ENGINEERING_README = `# Engineering
|
|
3222
|
+
|
|
3223
|
+
Internal engineering knowledge. This subtree is the source for the
|
|
3224
|
+
password-protected internal docs site.
|
|
3225
|
+
|
|
3226
|
+
## Contents
|
|
3227
|
+
|
|
3228
|
+
| Directory | Purpose |
|
|
3229
|
+
| --------- | ------- |
|
|
3230
|
+
| \`specifications/\` | Accepted specs (graduated from \`.notes/\`) |
|
|
3231
|
+
| \`standards/\` | Org-wide engineering standards |
|
|
3232
|
+
| \`runbooks/\` | Operational runbooks |
|
|
3233
|
+
|
|
3234
|
+
> **Drafts** live in \`.notes/*.spec.md\` until accepted, then graduate here.
|
|
3235
|
+
> **Architectural decisions** live in \`docs/decisions/\` and may be public-facing.
|
|
3236
|
+
`;
|
|
3237
|
+
//#endregion
|
|
2791
3238
|
//#region src/commands/dependabot.yml
|
|
2792
3239
|
var dependabot_default = "version: 2\nupdates:\n - package-ecosystem: npm\n directory: /\n schedule:\n interval: weekly\n commit-message:\n prefix: \"chore(deps)\"\n prefix-development: \"chore(deps-dev)\"\n groups:\n security-patches:\n applies-to: security-updates\n patterns:\n - \"*\"\n all-dependencies:\n update-types:\n - minor\n - patch\n\n - package-ecosystem: github-actions\n directory: /\n schedule:\n interval: weekly\n commit-message:\n prefix: \"chore(deps)\"\n groups:\n all-actions:\n patterns:\n - \"*\"\n";
|
|
2793
3240
|
//#endregion
|
|
@@ -3939,6 +4386,20 @@ async function runSetup(input) {
|
|
|
3939
4386
|
}));
|
|
3940
4387
|
print(formatStep(steps[steps.length - 1]));
|
|
3941
4388
|
}
|
|
4389
|
+
if (config.agent) {
|
|
4390
|
+
print(style.step("prompts"));
|
|
4391
|
+
steps.push(await runStep("prompts", "install agent prompts", dryRun, async () => {
|
|
4392
|
+
return await installAgentPrompts({ repoRoot: input.context.repoRoot });
|
|
4393
|
+
}));
|
|
4394
|
+
print(formatStep(steps[steps.length - 1]));
|
|
4395
|
+
}
|
|
4396
|
+
if (config.docs) {
|
|
4397
|
+
print(style.step("engineering"));
|
|
4398
|
+
steps.push(await runStep("engineering", "provision engineering structure", dryRun, async () => {
|
|
4399
|
+
return await installEngineeringStructure({ repoRoot: input.context.repoRoot });
|
|
4400
|
+
}));
|
|
4401
|
+
print(formatStep(steps[steps.length - 1]));
|
|
4402
|
+
}
|
|
3942
4403
|
const summary = steps.reduce((acc, s) => {
|
|
3943
4404
|
if (s.status === "ok") acc.ok += 1;
|
|
3944
4405
|
else if (s.status === "fail") acc.fail += 1;
|
|
@@ -4144,6 +4605,50 @@ async function updateSkillsGitignore(gitignorePath, existingContent, skills, sym
|
|
|
4144
4605
|
} else content = (existingContent.trimEnd() ? existingContent.trimEnd() + "\n\n" : "") + block + "\n";
|
|
4145
4606
|
await writeFile(gitignorePath, content, "utf8");
|
|
4146
4607
|
}
|
|
4608
|
+
const AGENTS_PROMPTS_ROOT = ".agents/prompts";
|
|
4609
|
+
const PROMPTS_GITIGNORE_START = "# managed by holocron setup — prompts";
|
|
4610
|
+
const PROMPTS_GITIGNORE_END = "# end managed by holocron setup — prompts";
|
|
4611
|
+
async function installAgentPrompts({ repoRoot }) {
|
|
4612
|
+
const promptsDir = join(repoRoot, AGENTS_PROMPTS_ROOT);
|
|
4613
|
+
await mkdir(promptsDir, { recursive: true });
|
|
4614
|
+
for (const [filename, content] of Object.entries(AGENT_PROMPTS)) await writeFile(join(promptsDir, filename), content, "utf8");
|
|
4615
|
+
const gitignorePath = join(repoRoot, ".gitignore");
|
|
4616
|
+
const existing = await readFile(gitignorePath, "utf8").catch(() => "");
|
|
4617
|
+
const block = [
|
|
4618
|
+
PROMPTS_GITIGNORE_START,
|
|
4619
|
+
`/${AGENTS_PROMPTS_ROOT}/`,
|
|
4620
|
+
PROMPTS_GITIGNORE_END
|
|
4621
|
+
].join("\n");
|
|
4622
|
+
let updated;
|
|
4623
|
+
if (existing.includes(PROMPTS_GITIGNORE_START)) {
|
|
4624
|
+
const start = existing.indexOf(PROMPTS_GITIGNORE_START);
|
|
4625
|
+
const end = existing.indexOf(PROMPTS_GITIGNORE_END, start);
|
|
4626
|
+
const afterBlock = end !== -1 ? existing.slice(end + 41) : "\n";
|
|
4627
|
+
updated = existing.slice(0, start) + block + afterBlock;
|
|
4628
|
+
} else updated = (existing.trimEnd() ? existing.trimEnd() + "\n\n" : "") + block + "\n";
|
|
4629
|
+
await writeFile(gitignorePath, updated, "utf8");
|
|
4630
|
+
return `wrote ${Object.keys(AGENT_PROMPTS).length} prompt files to ${AGENTS_PROMPTS_ROOT}/`;
|
|
4631
|
+
}
|
|
4632
|
+
async function writeIfAbsent(filePath, content) {
|
|
4633
|
+
try {
|
|
4634
|
+
await access(filePath);
|
|
4635
|
+
return false;
|
|
4636
|
+
} catch {
|
|
4637
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
4638
|
+
await writeFile(filePath, content, "utf8");
|
|
4639
|
+
return true;
|
|
4640
|
+
}
|
|
4641
|
+
}
|
|
4642
|
+
async function installEngineeringStructure({ repoRoot }) {
|
|
4643
|
+
const results = [];
|
|
4644
|
+
const writes = [
|
|
4645
|
+
[join(repoRoot, "docs/decisions/template.md"), DECISIONS_TEMPLATE],
|
|
4646
|
+
[join(repoRoot, "docs/decisions/README.md"), DECISIONS_README],
|
|
4647
|
+
[join(repoRoot, "docs/engineering/README.md"), ENGINEERING_README]
|
|
4648
|
+
];
|
|
4649
|
+
for (const [path, content] of writes) if (await writeIfAbsent(path, content)) results.push(path.replace(repoRoot + "/", ""));
|
|
4650
|
+
return results.length > 0 ? `created: ${results.join(", ")}` : "all files already exist — nothing to write";
|
|
4651
|
+
}
|
|
4147
4652
|
async function runStep(capability, step, dryRun, body, opts = {}) {
|
|
4148
4653
|
if (dryRun) return {
|
|
4149
4654
|
capability,
|
|
@@ -4821,7 +5326,7 @@ var deploy_preview_default = "name: Deploy Preview\n\non: # yamllint disable-lin
|
|
|
4821
5326
|
var greetings_default = "name: Greetings\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n\njobs:\n greeting:\n name: Greet first-time contributors\n permissions:\n issues: write\n pull-requests: write\n runs-on: ubuntu-latest\n timeout-minutes: 5\n # Group by the issue/PR number so duplicate events don't race each other.\n steps:\n - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0\n name: Greet on first contribution\n with:\n script: |\n // Only greet on the initial open — ignore synchronize, reopened, etc.\n if (context.payload.action !== 'opened') return;\n\n const actor = context.actor;\n const { owner, repo } = context.repo;\n\n // Payload inspection is more reliable than context.eventName for detecting\n // whether this is an issue vs. PR event — works regardless of how GitHub\n // propagates event names through workflow_call chains.\n const isIssue = !!context.payload.issue && !context.payload.pull_request;\n // listForRepo returns both issues and PRs (GitHub treats PRs as issues),\n // sorted newest-first. Filter by type to track first-issue and first-PR\n // independently, and avoid search-index eventual-consistency lag.\n const { data: recent } = await github.rest.issues.listForRepo({\n owner, repo,\n creator: actor,\n state: 'all',\n per_page: 100\n });\n\n const sameType = recent.filter(item =>\n isIssue ? !item.pull_request : !!item.pull_request\n );\n\n if (sameType.length !== 1) return;\n const body = isIssue\n ? `Hey @${actor}!\\n\\nWe really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we are a limited number of volunteers, so it is possible that this will not be addressed as swiftly.\\n\\nYour patience is much appreciated and we will get back to you as quickly as possible.`\n : `Hey @${actor}!\\n\\nWe really appreciate you taking the time to help out with this PR. The collaborators on this project attempt to help as many people as possible, but we are a limited number of volunteers, so it is possible that this will not be addressed as swiftly.\\n\\nYour patience is much appreciated and we will get back to you as quickly as possible.`;\n\n await github.rest.issues.createComment({\n owner,\n repo,\n issue_number: context.issue.number,\n body\n });\n";
|
|
4822
5327
|
//#endregion
|
|
4823
5328
|
//#region src/templates/workflows/lint.yml
|
|
4824
|
-
var lint_default = "name: Lint\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n eslint-config:\n description: >\n Filename for the ESLint flat config used by super-linter for\n JavaScript, JSX, TSX, and TypeScript (ES) files. Defaults to\n eslint.config.ts (the org standard). Note: ESLint 9 requires\n --flag unstable_ts_config to load .ts configs; if super-linter\n cannot load it, override with eslint.config.mjs or eslint.config.js.\n type: string\n required: false\n default: eslint.config.ts\n prettier-config:\n description: >\n Filename for the Prettier config. Defaults to prettier.config.ts\n (the org standard). Prettier 3.x loads .ts configs natively.\n type: string\n required: false\n default: prettier.config.ts\n yaml-config:\n description: >\n Filename for the yamllint config. Defaults to yamllint.config.yml.\n type: string\n required: false\n default: yamllint.config.yml\n enable-auto-commit:\n description: >\n Auto-commit super-linter fixes as a verified commit via a GitHub App.\n Requires SUPER_LINTER_APP_ID and SUPER_LINTER_PRIVATE_KEY secrets.\n type: boolean\n required: false\n default: false\n secrets:\n SUPER_LINTER_APP_ID:\n required: false\n SUPER_LINTER_PRIVATE_KEY:\n required: false\n\njobs:\n super-lint:\n name: Lint entire codebase\n permissions:\n contents: write\n issues: write\n statuses: write\n runs-on: ubuntu-latest\n timeout-minutes: 30\n env:\n APP_ID_SET: ${{ secrets.SUPER_LINTER_APP_ID != '' }}\n steps:\n - name: Generate GitHub App token\n id: app-token\n # Runs before checkout so the token is used as the checkout credential,\n # which makes the subsequent push go through the App and produce a\n # Verified commit. Skipped when auto-commit is disabled or secrets unset.\n if: >\n inputs.enable-auto-commit == true &&\n github.event.pull_request != null &&\n github.event.pull_request.head.repo.full_name == github.repository &&\n github.ref_name != github.event.repository.default_branch &&\n env.APP_ID_SET == 'true'\n uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0\n with:\n app-id: ${{ secrets.SUPER_LINTER_APP_ID }}\n private-key: ${{ secrets.SUPER_LINTER_PRIVATE_KEY }}\n\n - name: Resolve App bot identity\n id: app-bot\n # GitHub marks commits as Verified when the author email matches the\n # App bot's noreply address (<numeric-id>+<slug>[bot]@users.noreply.github.com).\n # The numeric ID must be fetched via the API — it differs from the App ID.\n # app-slug is passed via env rather than interpolated into the script to\n # prevent code injection (CWE-78).\n if: steps.app-token.conclusion == 'success'\n run: |\n BOT_SLUG=\"${APP_SLUG}[bot]\"\n BOT_ID=$(gh api \"/users/${BOT_SLUG}\" --jq .id)\n echo \"name=${BOT_SLUG}\" >> \"$GITHUB_OUTPUT\"\n echo \"email=${BOT_ID}+${BOT_SLUG}@users.noreply.github.com\" >> \"$GITHUB_OUTPUT\"\n env:\n GH_TOKEN: ${{ steps.app-token.outputs.token }}\n APP_SLUG: ${{ steps.app-token.outputs.app-slug }}\n\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n fetch-depth: 0\n # Use the App token when available so the push credential is the App\n # bot — GitHub marks those commits as Verified automatically.\n token: ${{ steps.app-token.outputs.token || github.token }}\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n if: ${{ hashFiles('pnpm-lock.yaml') != '' }}\n\n - name: Detect project features\n # Writes VALIDATE_*/FIX_* to GITHUB_ENV only when the feature exists.\n # Also writes step outputs for values referenced in expression context\n # (GITHUB_ENV is not readable via steps.*.outputs — they need GITHUB_OUTPUT).\n # All values written are hardcoded 'true' — no user input in the script.\n # Config file paths (inputs.*) stay in GH Actions expression context in\n # the super-linter env: block below, never shell-evaluated (CWE-78).\n id: detect\n run: |\n has() { find . -not -path '*/node_modules/*' -name \"$1\" -print -quit 2>/dev/null | grep -q .; }\n\n if { has 'eslint.config.ts' || has 'eslint.config.mjs' || has 'eslint.config.js' || has '.eslintrc.json' || has '.eslintrc.yml'; }; then\n {\n echo \"VALIDATE_JAVASCRIPT_ES=true\"\n echo \"VALIDATE_TYPESCRIPT_ES=true\"\n } >> \"$GITHUB_ENV\"\n echo \"eslint=true\" >> \"$GITHUB_OUTPUT\"\n fi\n\n if { has '*.js' || has '*.jsx' || has '*.mjs' || has '*.cjs' || has '*.ts' || has '*.tsx'; }; then\n {\n echo \"VALIDATE_JAVASCRIPT_PRETTIER=true\"\n echo \"VALIDATE_JSX_PRETTIER=true\"\n echo \"VALIDATE_TYPESCRIPT_PRETTIER=true\"\n echo \"VALIDATE_TSX=true\"\n echo \"FIX_JAVASCRIPT_PRETTIER=true\"\n echo \"FIX_JSX_PRETTIER=true\"\n echo \"FIX_TYPESCRIPT_PRETTIER=true\"\n echo \"FIX_TSX=true\"\n } >> \"$GITHUB_ENV\"\n fi\n\n if { has '*.css' || has '*.scss' || has 'stylelint.config.ts' || has 'stylelint.config.mjs' || has 'stylelint.config.js'; }; then\n {\n echo \"VALIDATE_CSS=true\"\n echo \"STYLELINT_CONFIG_FILE=stylelint.config.ts\"\n } >> \"$GITHUB_ENV\"\n fi\n\n if { has '*.graphql' || has '*.gql'; }; then\n {\n echo \"VALIDATE_GRAPHQL_PRETTIER=true\"\n echo \"FIX_GRAPHQL_PRETTIER=true\"\n } >> \"$GITHUB_ENV\"\n fi\n\n if { has '*.html' || has '*.htm'; }; then\n {\n echo \"VALIDATE_HTML_PRETTIER=true\"\n echo \"FIX_HTML_PRETTIER=true\"\n } >> \"$GITHUB_ENV\"\n fi\n\n if { has '.env' || has '.env.example' || has '.env.local'; }; then\n {\n echo \"VALIDATE_ENV=true\"\n echo \"FIX_ENV=true\"\n } >> \"$GITHUB_ENV\"\n fi\n\n if { has 'Dockerfile' || has '*.Dockerfile'; }; then\n echo \"VALIDATE_DOCKERFILE=true\" >> \"$GITHUB_ENV\"\n fi\n\n - uses: super-linter/super-linter/slim@4ce20838b8ab83717e78138c5b3a1407148e0918 # v8.7.0\n name: Run Super Linter\n env:\n GITHUB_TOKEN: ${{ github.token }}\n DEFAULT_BRANCH: ${{ github.event.pull_request.base.ref || github.event.repository.default_branch }}\n ANNOTATE_ONLY: true\n DISABLE_COMMENTS: false\n IGNORE_GITIGNORED_FILES: true\n LINTER_RULES_PATH: /\n EDITORCONFIG_FILE_NAME: \".editorconfig-checker.json\"\n # Config file paths — inputs stay in expression context, never shell-evaluated.\n # When VALIDATE_JAVASCRIPT_ES is not set by detect, ESLint doesn't run so\n # the empty-string fallback (→ eslint.config.mjs in container) is safe.\n JAVASCRIPT_ES_CONFIG_FILE: ${{ steps.detect.outputs.eslint == 'true' && inputs.eslint-config || '' }}\n TYPESCRIPT_ES_CONFIG_FILE: ${{ steps.detect.outputs.eslint == 'true' && inputs.eslint-config || '' }}\n PRETTIER_CONFIG: ${{ inputs.prettier-config }}\n YAML_CONFIG_FILE: ${{ inputs.yaml-config }}\n # Always-on linters\n FIX_MARKDOWN_PRETTIER: true\n VALIDATE_EDITORCONFIG: true\n VALIDATE_GIT_COMMITLINT: true\n VALIDATE_GIT_MERGE_CONFLICT_MARKERS: true\n VALIDATE_GITHUB_ACTIONS: true\n VALIDATE_GITLEAKS: true\n VALIDATE_MARKDOWN_PRETTIER: true\n VALIDATE_YAML: true\n\n - name: Validate ADR and spec frontmatter\n if: hashFiles('scripts/validate-adrs.mjs') != ''\n run: |\n mapfile -t changed < <(git diff --name-only \"$BASE_SHA\" HEAD -- \\\n 'docs/architecture/adr/*.md' '.notes/*.spec.md' 2>/dev/null || true)\n if [ \"${#changed[@]}\" -eq 0 ]; then\n node scripts/validate-adrs.mjs\n else\n node scripts/validate-adrs.mjs \"${changed[@]}\"\n fi\n env:\n BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}\n\n - uses: theholocron/.github/.github/actions/auto-commit@main\n name: Commit and push linting fixes\n if: >\n inputs.enable-auto-commit == true &&\n github.event.pull_request != null &&\n github.event.pull_request.head.repo.full_name == github.repository &&\n github.ref_name != github.event.repository.default_branch &&\n env.APP_ID_SET == 'true'\n with:\n token: ${{ steps.app-token.outputs.token }}\n branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }}\n commit-message: \"chore: fix linting issues\\n\\nSigned-off-by: ${{ steps.app-bot.outputs.name }} <${{ steps.app-bot.outputs.email }}>\"\n commit-options: \"--no-verify\"\n commit-user-name: ${{ steps.app-bot.outputs.name }}\n commit-user-email: ${{ steps.app-bot.outputs.email }}\n commit-author: \"${{ steps.app-bot.outputs.name }} <${{ steps.app-bot.outputs.email }}>\"\n\n\n conclusion:\n name: Conclusion\n runs-on: ubuntu-latest\n if: always()\n needs: [super-lint]\n steps:\n - name: Check job statuses\n run: |\n if [[ \"$RESULTS\" == *\"failure\"* ]] || [[ \"$RESULTS\" == *\"cancelled\"* ]]; then\n exit 1\n fi\n env:\n RESULTS: ${{ join(needs.*.result, ',') }}\n";
|
|
5329
|
+
var lint_default = "name: Lint\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n inputs:\n eslint-config:\n description: >\n Filename for the ESLint flat config used by super-linter for\n JavaScript, JSX, TSX, and TypeScript (ES) files. Defaults to\n eslint.config.ts (the org standard). Note: ESLint 9 requires\n --flag unstable_ts_config to load .ts configs; if super-linter\n cannot load it, override with eslint.config.mjs or eslint.config.js.\n type: string\n required: false\n default: eslint.config.ts\n prettier-config:\n description: >\n Filename for the Prettier config. Defaults to prettier.config.ts\n (the org standard). Prettier 3.x loads .ts configs natively.\n type: string\n required: false\n default: prettier.config.ts\n yaml-config:\n description: >\n Filename for the yamllint config. Defaults to yamllint.config.yml.\n type: string\n required: false\n default: yamllint.config.yml\n enable-auto-commit:\n description: >\n Auto-commit super-linter fixes as a verified commit via a GitHub App.\n Requires SUPER_LINTER_APP_ID and SUPER_LINTER_PRIVATE_KEY secrets.\n type: boolean\n required: false\n default: false\n secrets:\n SUPER_LINTER_APP_ID:\n required: false\n SUPER_LINTER_PRIVATE_KEY:\n required: false\n\njobs:\n super-lint:\n name: Lint entire codebase\n permissions:\n contents: write\n issues: write\n statuses: write\n runs-on: ubuntu-latest\n timeout-minutes: 30\n env:\n APP_ID_SET: ${{ secrets.SUPER_LINTER_APP_ID != '' }}\n steps:\n - name: Generate GitHub App token\n id: app-token\n # Runs before checkout so the token is used as the checkout credential,\n # which makes the subsequent push go through the App and produce a\n # Verified commit. Skipped when auto-commit is disabled or secrets unset.\n if: >\n inputs.enable-auto-commit == true &&\n github.event.pull_request != null &&\n github.event.pull_request.head.repo.full_name == github.repository &&\n github.ref_name != github.event.repository.default_branch &&\n env.APP_ID_SET == 'true'\n uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0\n with:\n app-id: ${{ secrets.SUPER_LINTER_APP_ID }}\n private-key: ${{ secrets.SUPER_LINTER_PRIVATE_KEY }}\n\n - name: Resolve App bot identity\n id: app-bot\n # GitHub marks commits as Verified when the author email matches the\n # App bot's noreply address (<numeric-id>+<slug>[bot]@users.noreply.github.com).\n # The numeric ID must be fetched via the API — it differs from the App ID.\n # app-slug is passed via env rather than interpolated into the script to\n # prevent code injection (CWE-78).\n if: steps.app-token.conclusion == 'success'\n run: |\n BOT_SLUG=\"${APP_SLUG}[bot]\"\n BOT_ID=$(gh api \"/users/${BOT_SLUG}\" --jq .id)\n echo \"name=${BOT_SLUG}\" >> \"$GITHUB_OUTPUT\"\n echo \"email=${BOT_ID}+${BOT_SLUG}@users.noreply.github.com\" >> \"$GITHUB_OUTPUT\"\n env:\n GH_TOKEN: ${{ steps.app-token.outputs.token }}\n APP_SLUG: ${{ steps.app-token.outputs.app-slug }}\n\n - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0\n name: Checkout repository\n with:\n fetch-depth: 0\n # Use the App token when available so the push credential is the App\n # bot — GitHub marks those commits as Verified automatically.\n token: ${{ steps.app-token.outputs.token || github.token }}\n\n - uses: theholocron/.github/.github/actions/setup@main\n name: Setup\n if: ${{ hashFiles('pnpm-lock.yaml') != '' }}\n\n - name: Detect project features\n # Writes VALIDATE_*/FIX_* to GITHUB_ENV only when the feature exists.\n # Also writes step outputs for values referenced in expression context\n # (GITHUB_ENV is not readable via steps.*.outputs — they need GITHUB_OUTPUT).\n # All values written are hardcoded 'true' — no user input in the script.\n # Config file paths (inputs.*) stay in GH Actions expression context in\n # the super-linter env: block below, never shell-evaluated (CWE-78).\n id: detect\n run: |\n has() { find . -not -path '*/node_modules/*' -name \"$1\" -print -quit 2>/dev/null | grep -q .; }\n\n if { has 'eslint.config.ts' || has 'eslint.config.mjs' || has 'eslint.config.js' || has '.eslintrc.json' || has '.eslintrc.yml'; }; then\n {\n echo \"VALIDATE_JAVASCRIPT_ES=true\"\n echo \"VALIDATE_TYPESCRIPT_ES=true\"\n } >> \"$GITHUB_ENV\"\n echo \"eslint=true\" >> \"$GITHUB_OUTPUT\"\n fi\n\n if { has '*.js' || has '*.jsx' || has '*.mjs' || has '*.cjs' || has '*.ts' || has '*.tsx'; }; then\n {\n echo \"VALIDATE_JAVASCRIPT_PRETTIER=true\"\n echo \"VALIDATE_JSX_PRETTIER=true\"\n echo \"VALIDATE_TYPESCRIPT_PRETTIER=true\"\n echo \"VALIDATE_TSX=true\"\n echo \"FIX_JAVASCRIPT_PRETTIER=true\"\n echo \"FIX_JSX_PRETTIER=true\"\n echo \"FIX_TYPESCRIPT_PRETTIER=true\"\n echo \"FIX_TSX=true\"\n } >> \"$GITHUB_ENV\"\n fi\n\n if { has '*.css' || has '*.scss' || has 'stylelint.config.ts' || has 'stylelint.config.mjs' || has 'stylelint.config.js'; }; then\n {\n echo \"VALIDATE_CSS=true\"\n echo \"STYLELINT_CONFIG_FILE=stylelint.config.ts\"\n } >> \"$GITHUB_ENV\"\n fi\n\n if { has '*.graphql' || has '*.gql'; }; then\n {\n echo \"VALIDATE_GRAPHQL_PRETTIER=true\"\n echo \"FIX_GRAPHQL_PRETTIER=true\"\n } >> \"$GITHUB_ENV\"\n fi\n\n if { has '*.html' || has '*.htm'; }; then\n {\n echo \"VALIDATE_HTML_PRETTIER=true\"\n echo \"FIX_HTML_PRETTIER=true\"\n } >> \"$GITHUB_ENV\"\n fi\n\n if { has '.env' || has '.env.example' || has '.env.local'; }; then\n {\n echo \"VALIDATE_ENV=true\"\n echo \"FIX_ENV=true\"\n } >> \"$GITHUB_ENV\"\n fi\n\n if { has 'Dockerfile' || has '*.Dockerfile'; }; then\n echo \"VALIDATE_DOCKERFILE=true\" >> \"$GITHUB_ENV\"\n fi\n\n - uses: super-linter/super-linter/slim@4ce20838b8ab83717e78138c5b3a1407148e0918 # v8.7.0\n name: Run Super Linter\n env:\n GITHUB_TOKEN: ${{ github.token }}\n DEFAULT_BRANCH: ${{ github.event.pull_request.base.ref || github.event.repository.default_branch }}\n ANNOTATE_ONLY: true\n DISABLE_COMMENTS: false\n IGNORE_GITIGNORED_FILES: true\n LINTER_RULES_PATH: /\n EDITORCONFIG_FILE_NAME: \".editorconfig-checker.json\"\n # Config file paths — inputs stay in expression context, never shell-evaluated.\n # When VALIDATE_JAVASCRIPT_ES is not set by detect, ESLint doesn't run so\n # the empty-string fallback (→ eslint.config.mjs in container) is safe.\n JAVASCRIPT_ES_CONFIG_FILE: ${{ steps.detect.outputs.eslint == 'true' && inputs.eslint-config || '' }}\n TYPESCRIPT_ES_CONFIG_FILE: ${{ steps.detect.outputs.eslint == 'true' && inputs.eslint-config || '' }}\n PRETTIER_CONFIG: ${{ inputs.prettier-config }}\n YAML_CONFIG_FILE: ${{ inputs.yaml-config }}\n # Always-on linters\n FIX_MARKDOWN_PRETTIER: true\n VALIDATE_EDITORCONFIG: true\n VALIDATE_GIT_COMMITLINT: true\n VALIDATE_GIT_MERGE_CONFLICT_MARKERS: true\n VALIDATE_GITHUB_ACTIONS: true\n VALIDATE_GITLEAKS: true\n VALIDATE_MARKDOWN_PRETTIER: true\n VALIDATE_YAML: true\n\n - name: Validate ADR and spec frontmatter\n if: hashFiles('scripts/validate-adrs.mjs') != ''\n run: |\n mapfile -t changed < <(git diff --name-only \"$BASE_SHA\" HEAD -- \\\n 'docs/decisions/*.md' '.notes/*.spec.md' 2>/dev/null || true)\n if [ \"${#changed[@]}\" -eq 0 ]; then\n node scripts/validate-adrs.mjs\n else\n node scripts/validate-adrs.mjs \"${changed[@]}\"\n fi\n env:\n BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }}\n\n - uses: theholocron/.github/.github/actions/auto-commit@main\n name: Commit and push linting fixes\n if: >\n inputs.enable-auto-commit == true &&\n github.event.pull_request != null &&\n github.event.pull_request.head.repo.full_name == github.repository &&\n github.ref_name != github.event.repository.default_branch &&\n env.APP_ID_SET == 'true'\n with:\n token: ${{ steps.app-token.outputs.token }}\n branch: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref }}\n commit-message: \"chore: fix linting issues\\n\\nSigned-off-by: ${{ steps.app-bot.outputs.name }} <${{ steps.app-bot.outputs.email }}>\"\n commit-options: \"--no-verify\"\n commit-user-name: ${{ steps.app-bot.outputs.name }}\n commit-user-email: ${{ steps.app-bot.outputs.email }}\n commit-author: \"${{ steps.app-bot.outputs.name }} <${{ steps.app-bot.outputs.email }}>\"\n\n\n conclusion:\n name: Conclusion\n runs-on: ubuntu-latest\n if: always()\n needs: [super-lint]\n steps:\n - name: Check job statuses\n run: |\n if [[ \"$RESULTS\" == *\"failure\"* ]] || [[ \"$RESULTS\" == *\"cancelled\"* ]]; then\n exit 1\n fi\n env:\n RESULTS: ${{ join(needs.*.result, ',') }}\n";
|
|
4825
5330
|
//#endregion
|
|
4826
5331
|
//#region src/templates/workflows/post-release.yml
|
|
4827
5332
|
var post_release_default = "name: Post-release Sync\n\non: # yamllint disable-line rule:truthy\n workflow_call:\n secrets:\n HOLOCRON_SYNC_TOKEN:\n required: false\n GH_TOKEN:\n description: >\n Generic GitHub token fallback for gh CLI calls. Used when\n HOLOCRON_SYNC_TOKEN is not set.\n required: false\n\njobs:\n broadcast:\n name: Broadcast readme sync\n runs-on: ubuntu-latest\n timeout-minutes: 5\n steps:\n - name: Trigger broadcast readme sync\n run: |\n gh workflow run sync-broadcast.yml \\\n --repo theholocron/.github \\\n --field \"steps=readme\"\n env:\n GH_TOKEN: ${{ secrets.HOLOCRON_SYNC_TOKEN || secrets.GH_TOKEN }}\n";
|