@factiii/stack 0.7.3 → 0.9.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/plugin-commands.d.ts.map +1 -1
- package/dist/cli/plugin-commands.js +20 -0
- package/dist/cli/plugin-commands.js.map +1 -1
- package/dist/plugins/pipelines/factiii/index.d.ts +24 -0
- package/dist/plugins/pipelines/factiii/index.d.ts.map +1 -1
- package/dist/plugins/pipelines/factiii/index.js +324 -32
- package/dist/plugins/pipelines/factiii/index.js.map +1 -1
- package/dist/plugins/pipelines/factiii/scanfix/claude-skills.d.ts +55 -0
- package/dist/plugins/pipelines/factiii/scanfix/claude-skills.d.ts.map +1 -0
- package/dist/plugins/pipelines/factiii/scanfix/claude-skills.js +474 -0
- package/dist/plugins/pipelines/factiii/scanfix/claude-skills.js.map +1 -0
- package/dist/types/plugin.d.ts +1 -1
- package/dist/types/plugin.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/plugins/pipelines/factiii/scanfix/prod-check-skill.d.ts +0 -34
- package/dist/plugins/pipelines/factiii/scanfix/prod-check-skill.d.ts.map +0 -1
- package/dist/plugins/pipelines/factiii/scanfix/prod-check-skill.js +0 -221
- package/dist/plugins/pipelines/factiii/scanfix/prod-check-skill.js.map +0 -1
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* prod-check skill scanfix for Factiii Pipeline plugin
|
|
4
|
-
*
|
|
5
|
-
* Ensures the per-user Claude Code skill at ~/.claude/skills/prod-check/SKILL.md
|
|
6
|
-
* exists on the developer's machine. The skill encodes the pre-production
|
|
7
|
-
* verification workflow (lint → check-types → tests → build → diff vs production
|
|
8
|
-
* → secret scan → audit) so any Claude Code session can run it consistently.
|
|
9
|
-
*
|
|
10
|
-
* Local-only (no SSH, no GITHUB_ACTIONS check). Stage: dev.
|
|
11
|
-
* Severity: warning — missing skill doesn't break deploys, but having it
|
|
12
|
-
* available is what enforces the pre-prod gates the team relies on.
|
|
13
|
-
*
|
|
14
|
-
* OPT-IN: This scanfix is a "host-machine fix" — it writes to ~/.claude/, which
|
|
15
|
-
* is the developer's personal Claude Code config, not project state. Per
|
|
16
|
-
* STANDARDS.md "Host-Machine Fixes", these are gated behind an explicit
|
|
17
|
-
* opt-in in stack.local.yml (`claude_skills: true`). When the flag is unset
|
|
18
|
-
* or false, scan returns "no issue" and fix is a no-op. This keeps devs who
|
|
19
|
-
* don't use Claude Code (or who curate their own skills) from being surprised
|
|
20
|
-
* by files appearing in their home directory.
|
|
21
|
-
*
|
|
22
|
-
* Split of concerns:
|
|
23
|
-
* - This scanfix owns the skill *workflow* (SKILL.md). Process lives here
|
|
24
|
-
* so it ships with stack and is identical on every dev machine that
|
|
25
|
-
* opts in.
|
|
26
|
-
* - The audit *override reference table* (which packages, why) lives in
|
|
27
|
-
* the consumer repo at .specs/audit.md so PR reviewers can see it.
|
|
28
|
-
*
|
|
29
|
-
* If the user edits their local SKILL.md, this scanfix won't clobber it —
|
|
30
|
-
* delete the file and re-run `npx stack fix --dev` to restore the canonical
|
|
31
|
-
* version.
|
|
32
|
-
*/
|
|
33
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
34
|
-
if (k2 === undefined) k2 = k;
|
|
35
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
36
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
37
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
38
|
-
}
|
|
39
|
-
Object.defineProperty(o, k2, desc);
|
|
40
|
-
}) : (function(o, m, k, k2) {
|
|
41
|
-
if (k2 === undefined) k2 = k;
|
|
42
|
-
o[k2] = m[k];
|
|
43
|
-
}));
|
|
44
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
45
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
46
|
-
}) : function(o, v) {
|
|
47
|
-
o["default"] = v;
|
|
48
|
-
});
|
|
49
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
50
|
-
var ownKeys = function(o) {
|
|
51
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
52
|
-
var ar = [];
|
|
53
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
54
|
-
return ar;
|
|
55
|
-
};
|
|
56
|
-
return ownKeys(o);
|
|
57
|
-
};
|
|
58
|
-
return function (mod) {
|
|
59
|
-
if (mod && mod.__esModule) return mod;
|
|
60
|
-
var result = {};
|
|
61
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
62
|
-
__setModuleDefault(result, mod);
|
|
63
|
-
return result;
|
|
64
|
-
};
|
|
65
|
-
})();
|
|
66
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
67
|
-
exports.prodCheckSkillFixes = void 0;
|
|
68
|
-
const fs = __importStar(require("fs"));
|
|
69
|
-
const os = __importStar(require("os"));
|
|
70
|
-
const path = __importStar(require("path"));
|
|
71
|
-
const config_helpers_js_1 = require("../../../../utils/config-helpers.js");
|
|
72
|
-
const SKILL_DIR = path.join(os.homedir(), '.claude', 'skills', 'prod-check');
|
|
73
|
-
const SKILL_FILE = path.join(SKILL_DIR, 'SKILL.md');
|
|
74
|
-
const SKILL_CONTENT = `---
|
|
75
|
-
name: prod-check
|
|
76
|
-
description: Pre-production verification for the factiii monorepo. Runs quality gates (lint, types, tests, build), diffs the current branch against origin/production for schema/migration/env/secret/API changes, and runs a security audit pass. TRIGGER when the user asks to check a branch against production, prepare a production push, run pre-merge checks, or audit dependencies before release.
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
# prod-check
|
|
80
|
-
|
|
81
|
-
Pre-production verification workflow for \`jon/factiii\`. Runs in two phases: **fix everything locally first**, then **diff against production** to surface anything risky. Report at the end groups findings as **BLOCKING** vs **INFORMATIONAL**.
|
|
82
|
-
|
|
83
|
-
The whole point: nothing should reach \`origin/production\` that hasn't passed local quality gates and been reviewed for schema, secret, and API-breaking changes.
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## Phase 1 — Local quality gates (fix before continuing)
|
|
88
|
-
|
|
89
|
-
Run in this order. Each step must be green before moving on. If a step fails, fix it (or report blockers and stop) — do not skip.
|
|
90
|
-
|
|
91
|
-
1. **Sync** — \`git fetch origin production\` and confirm the working tree is clean (\`git status\`). Stash or commit anything dirty before continuing; uncommitted state contaminates the diff in Phase 2.
|
|
92
|
-
2. **Auto-fix lint noise** — \`pnpm lint:fix\`. This cleans import order, unused imports, prettier, prefer-const so the type/test output isn't drowned in cosmetic churn. Per CLAUDE.md, ignore auto-fixable lint as a *finding*, but always run the fixer first.
|
|
93
|
-
3. **Type check** — \`pnpm check-types\`. Fix every error. No \`@ts-ignore\`, no \`any\` (use \`unknown\`). Type errors are blocking.
|
|
94
|
-
4. **Lint (real rules)** — \`pnpm lint\`. Focus on what matters per CLAUDE.md: promise handling, hooks rules, real type issues. Auto-fixable categories are noise — don't chase them.
|
|
95
|
-
5. **Server tests** — from \`apps/server/\`: \`pnpm seed:test\` first, then \`pnpm test\`. The seed step is required (see memory \`feedback_testing.md\`); skipping it produces misleading failures.
|
|
96
|
-
6. **Build all three apps** — \`pnpm build\`. Server, client, and mobile must all build. A green local dev does not imply a green build.
|
|
97
|
-
|
|
98
|
-
If any step in Phase 1 surfaces failures you can fix safely, fix them. If failures need user judgment (e.g. a failing test reflects intended behavior change), stop and report before continuing to Phase 2.
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## Phase 2 — Diff against production
|
|
103
|
-
|
|
104
|
-
Only run after Phase 1 is fully green. Use \`origin/production\` as the base (refresh with \`git fetch origin production\` if Phase 1 took a while).
|
|
105
|
-
|
|
106
|
-
1. **Overall diffstat** — \`git diff --stat origin/production...HEAD\` for orientation.
|
|
107
|
-
2. **Schema & migrations** — \`git diff origin/production...HEAD -- apps/server/prisma/schema.prisma 'apps/server/prisma/migrations/**'\`.
|
|
108
|
-
- Comment-only schema changes = informational.
|
|
109
|
-
- Field/model/index changes = blocking unless paired with a migration.
|
|
110
|
-
- **New migration files = blocking action**: they need to be applied to prod DB during deploy. Call this out explicitly with the migration name(s).
|
|
111
|
-
3. **Secrets scan** — search the diff for committed credentials. Patterns to grep: \`AKIA[0-9A-Z]{16}\` (AWS access key), \`-----BEGIN .* PRIVATE KEY-----\`, \`sk_live_\`, \`sk_test_\`, \`xox[baprs]-\`, \`ghp_\`, \`Bearer [A-Za-z0-9_\\-]{20,}\`, raw \`password\\s*[:=]\`, \`client_secret\`. Run against \`git diff origin/production...HEAD\`. Anything matching is **BLOCKING** — instruct the user to rotate the credential in its provider before merging, since git history is forever.
|
|
112
|
-
4. **Env / infra surface** — diff these paths and flag any change:
|
|
113
|
-
- \`stack.yml\`, \`docker-compose*.yml\`
|
|
114
|
-
- \`.github/workflows/**\`
|
|
115
|
-
- \`start.sh\`, \`apps/server/package.json\` (deps), root \`package.json\`
|
|
116
|
-
- \`pnpm-workspace.yaml\` catalog
|
|
117
|
-
Changes here often need a corresponding action on the prod host (env var added, image rebuilt, workflow secret set).
|
|
118
|
-
5. **Breaking API changes for mobile** — old mobile builds in the wild cannot be force-updated. Diff \`apps/server/src/routes/**\` and look for:
|
|
119
|
-
- Removed tRPC procedures
|
|
120
|
-
- Renamed/removed input or output fields
|
|
121
|
-
- Tightened Zod validators (new required fields, narrower enums)
|
|
122
|
-
- Changed HTTP status codes or error shapes
|
|
123
|
-
These are blocking unless the change is additive or behind a version gate.
|
|
124
|
-
6. **Shared validators** — diff \`shared/all/validators/**\`. Tightening a Zod schema is the most common silent break for old clients.
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
## Phase 3 — Security audit pass
|
|
129
|
-
|
|
130
|
-
**Always run** — even when \`pnpm-lock.yaml\` is unchanged. New CVEs get disclosed against packages already pinned in the lockfile, so a clean diff doesn't mean a clean audit. The whole point of this phase is to catch vulns introduced *upstream* that landed since the last prod push.
|
|
131
|
-
|
|
132
|
-
Start with a quick \`pnpm audit\` against the current lockfile. If it's clean and \`.specs/audit.md\` is current, you're done with Phase 3 in one command. If there are new findings, run the full process below to triage them.
|
|
133
|
-
|
|
134
|
-
The override **reference table** (what's pinned and *why*) lives in \`.specs/audit.md\` so it's reviewable in PRs alongside code. This skill owns the **process** for updating it.
|
|
135
|
-
|
|
136
|
-
### Audit process
|
|
137
|
-
|
|
138
|
-
1. Remove ALL overrides from \`package.json\` (security + Expo dedup).
|
|
139
|
-
2. \`pnpm install --no-frozen-lockfile\`.
|
|
140
|
-
3. \`cd apps/mobile && npx expo-doctor\` — check Expo SDK compatibility first.
|
|
141
|
-
4. Re-add Expo dedup overrides if still needed, \`pnpm install\`.
|
|
142
|
-
5. \`pnpm audit\` — note what's still vulnerable.
|
|
143
|
-
6. For each vuln: \`pnpm why <pkg>\` — if upstream fixed it, no override needed.
|
|
144
|
-
7. Add security overrides only for transitive deps where the fix is a semver-compatible bump.
|
|
145
|
-
8. \`pnpm install && pnpm audit\` — verify.
|
|
146
|
-
9. **Update \`.specs/audit.md\`** with the new override row(s), source chain, and the *reason* (CVE, behavior, or compatibility issue). A row without a reason is worse than no row.
|
|
147
|
-
|
|
148
|
-
**Don't override** if: major version jump required, dev-only with no prod exposure, or it's a direct dep (just upgrade it).
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
## Final report format
|
|
153
|
-
|
|
154
|
-
Group findings into two buckets. Be specific — name files, line numbers, migration filenames.
|
|
155
|
-
|
|
156
|
-
\`\`\`
|
|
157
|
-
BLOCKING (must resolve before merging to production):
|
|
158
|
-
- <finding> — <file:line> — <what to do>
|
|
159
|
-
|
|
160
|
-
INFORMATIONAL (no action needed, just FYI):
|
|
161
|
-
- <finding> — <file:line>
|
|
162
|
-
\`\`\`
|
|
163
|
-
|
|
164
|
-
If Phase 1 had failures the user must triage, surface those at the top before any Phase 2 findings.
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
## Notes
|
|
169
|
-
|
|
170
|
-
- This skill is installed by the \`prod-check-skill\` scanfix in \`@factiii/stack\` (factiii pipeline). Run \`npx stack fix --dev\` from the factiii repo to install or restore it.
|
|
171
|
-
- Workflow lives here in \`~/.claude/skills/\`; the audit override reference table lives in the factiii repo at \`.specs/audit.md\` so reasons are reviewable in PRs.
|
|
172
|
-
- Memory pointers: \`feedback_testing.md\` (server test seed requirement), \`reference_staging_access.md\` (staging server layout) may be useful context for related work but are not part of this skill's flow.
|
|
173
|
-
`;
|
|
174
|
-
/**
|
|
175
|
-
* Read the per-developer opt-in flag from stack.local.yml.
|
|
176
|
-
* Defaults to false: host-machine fixes never run unless explicitly enabled.
|
|
177
|
-
*/
|
|
178
|
-
function isOptedIn(rootDir) {
|
|
179
|
-
try {
|
|
180
|
-
const local = (0, config_helpers_js_1.loadLocalConfig)(rootDir);
|
|
181
|
-
return local.claude_skills === true;
|
|
182
|
-
}
|
|
183
|
-
catch {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
exports.prodCheckSkillFixes = [
|
|
188
|
-
{
|
|
189
|
-
id: 'prod-check-skill-installed',
|
|
190
|
-
stage: 'dev',
|
|
191
|
-
severity: 'warning',
|
|
192
|
-
description: 'Claude Code prod-check skill is missing at ~/.claude/skills/prod-check/SKILL.md — pre-prod gates (lint/types/tests/build + branch diff vs production + secret scan + audit) cannot be invoked consistently without it (enable with `claude_skills: true` in stack.local.yml)',
|
|
193
|
-
scan: async function (_config, rootDir) {
|
|
194
|
-
// Opt-in gate: if the dev hasn't enabled claude_skills in stack.local.yml,
|
|
195
|
-
// report no issue. This keeps the scanfix invisible to devs who don't
|
|
196
|
-
// want their ~/.claude/ touched.
|
|
197
|
-
if (!isOptedIn(rootDir))
|
|
198
|
-
return false;
|
|
199
|
-
// Returns true when there IS an issue (skill missing).
|
|
200
|
-
return !fs.existsSync(SKILL_FILE);
|
|
201
|
-
},
|
|
202
|
-
fix: async function (_config, rootDir) {
|
|
203
|
-
// Belt-and-braces: even if scan ever returned a stale result, fix
|
|
204
|
-
// re-checks the opt-in before touching the host filesystem.
|
|
205
|
-
if (!isOptedIn(rootDir))
|
|
206
|
-
return true;
|
|
207
|
-
// Local-only: write SKILL.md into the user's home dir.
|
|
208
|
-
// Idempotent: only writes if missing, so a user who has hand-edited
|
|
209
|
-
// their copy won't get clobbered. Delete the file to force a refresh.
|
|
210
|
-
if (!fs.existsSync(SKILL_DIR)) {
|
|
211
|
-
fs.mkdirSync(SKILL_DIR, { recursive: true });
|
|
212
|
-
}
|
|
213
|
-
if (!fs.existsSync(SKILL_FILE)) {
|
|
214
|
-
fs.writeFileSync(SKILL_FILE, SKILL_CONTENT, 'utf8');
|
|
215
|
-
}
|
|
216
|
-
return true;
|
|
217
|
-
},
|
|
218
|
-
manualFix: 'Set `claude_skills: true` in stack.local.yml and run `npx stack fix --dev`, or create ~/.claude/skills/prod-check/SKILL.md by hand.',
|
|
219
|
-
},
|
|
220
|
-
];
|
|
221
|
-
//# sourceMappingURL=prod-check-skill.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prod-check-skill.js","sourceRoot":"","sources":["../../../../../src/plugins/pipelines/factiii/scanfix/prod-check-skill.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,uCAAyB;AACzB,uCAAyB;AACzB,2CAA6B;AAE7B,2EAAsE;AAEtE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;AAC7E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAEpD,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmGrB,CAAC;AAEF;;;GAGG;AACH,SAAS,SAAS,CAAC,OAAe;IAChC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAA,mCAAe,EAAC,OAAO,CAAC,CAAC;QACvC,OAAO,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAEY,QAAA,mBAAmB,GAAU;IACxC;QACE,EAAE,EAAE,4BAA4B;QAChC,KAAK,EAAE,KAAK;QACZ,QAAQ,EAAE,SAAS;QACnB,WAAW,EACT,8QAA8Q;QAChR,IAAI,EAAE,KAAK,WAAW,OAAO,EAAE,OAAO;YACpC,2EAA2E;YAC3E,sEAAsE;YACtE,iCAAiC;YACjC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAAE,OAAO,KAAK,CAAC;YACtC,uDAAuD;YACvD,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;QACD,GAAG,EAAE,KAAK,WAAW,OAAO,EAAE,OAAO;YACnC,kEAAkE;YAClE,4DAA4D;YAC5D,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC;YACrC,uDAAuD;YACvD,oEAAoE;YACpE,sEAAsE;YACtE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/C,CAAC;YACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;YACtD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,SAAS,EACP,qIAAqI;KACxI;CACF,CAAC"}
|