@massu/core 1.2.0 → 1.3.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 +40 -0
- package/commands/README.md +122 -0
- package/commands/massu-deploy.python.md +200 -0
- package/commands/massu-scaffold-page.md +172 -59
- package/commands/massu-scaffold-page.swift.md +121 -0
- package/commands/massu-scaffold-router.python.md +143 -0
- package/dist/cli.js +562 -231
- package/dist/hooks/auto-learning-pipeline.js +8 -4
- package/dist/hooks/classify-failure.js +8 -4
- package/dist/hooks/cost-tracker.js +8 -4
- package/dist/hooks/fix-detector.js +8 -4
- package/dist/hooks/incident-pipeline.js +8 -4
- package/dist/hooks/post-edit-context.js +8 -4
- package/dist/hooks/post-tool-use.js +8 -4
- package/dist/hooks/pre-compact.js +8 -4
- package/dist/hooks/pre-delete-check.js +8 -4
- package/dist/hooks/quality-event.js +8 -4
- package/dist/hooks/rule-enforcement-pipeline.js +8 -4
- package/dist/hooks/session-end.js +8 -4
- package/dist/hooks/session-start.js +20 -7
- package/dist/hooks/user-prompt.js +8 -4
- package/package.json +1 -1
- package/src/cli.ts +6 -0
- package/src/commands/init.ts +89 -4
- package/src/commands/install-commands.ts +366 -42
- package/src/commands/show-template.ts +65 -0
- package/src/config.ts +11 -3
- package/src/detect/index.ts +10 -1
- package/src/detect/migrate.ts +52 -1
- package/src/detect/source-dir-detector.ts +28 -2
package/src/detect/migrate.ts
CHANGED
|
@@ -196,10 +196,21 @@ export function migrateV1ToV2(
|
|
|
196
196
|
preserveNestedSubkeys(v1Framework, framework);
|
|
197
197
|
|
|
198
198
|
// Paths: preserve user-set fields; fill `source` from detection if user had 'src' default.
|
|
199
|
+
// P1-003 (mirror of init.ts:367-390): when primary language has no source dir
|
|
200
|
+
// AND this is a monorepo, fall back to the common parent of workspace packages
|
|
201
|
+
// instead of leaving the nonexistent default 'src' in place.
|
|
199
202
|
let pathsSource: string = typeof v1Paths.source === 'string' ? v1Paths.source : 'src';
|
|
200
203
|
if (pathsSource === 'src' && primary) {
|
|
201
204
|
const primaryDirs = detection.sourceDirs[primary]?.source_dirs ?? [];
|
|
202
|
-
if (primaryDirs.length > 0)
|
|
205
|
+
if (primaryDirs.length > 0) {
|
|
206
|
+
pathsSource = primaryDirs[0];
|
|
207
|
+
} else if (
|
|
208
|
+
detection.monorepo?.type !== undefined &&
|
|
209
|
+
detection.monorepo.type !== 'single' &&
|
|
210
|
+
detection.monorepo.packages.length > 0
|
|
211
|
+
) {
|
|
212
|
+
pathsSource = monorepoCommonRootMigrate(detection.monorepo.packages);
|
|
213
|
+
}
|
|
203
214
|
}
|
|
204
215
|
const aliases = v1Paths.aliases && typeof v1Paths.aliases === 'object'
|
|
205
216
|
? (v1Paths.aliases as Record<string, string>)
|
|
@@ -208,6 +219,17 @@ export function migrateV1ToV2(
|
|
|
208
219
|
source: pathsSource,
|
|
209
220
|
aliases,
|
|
210
221
|
};
|
|
222
|
+
// P1-005 mirror: emit monorepo_roots for upgraded v2 configs (additive,
|
|
223
|
+
// only when monorepo + not already user-specified).
|
|
224
|
+
if (
|
|
225
|
+
detection.monorepo?.type !== undefined &&
|
|
226
|
+
detection.monorepo.type !== 'single' &&
|
|
227
|
+
detection.monorepo.packages.length > 0 &&
|
|
228
|
+
!('monorepo_roots' in v1Paths)
|
|
229
|
+
) {
|
|
230
|
+
const roots = monorepoDistinctRootsMigrate(detection.monorepo.packages);
|
|
231
|
+
if (roots.length > 0) paths.monorepo_roots = roots;
|
|
232
|
+
}
|
|
211
233
|
for (const k of ['routers', 'routerRoot', 'pages', 'middleware', 'schema', 'components', 'hooks']) {
|
|
212
234
|
if (typeof v1Paths[k] === 'string') paths[k] = v1Paths[k];
|
|
213
235
|
}
|
|
@@ -309,3 +331,32 @@ export function migrateV1ToV2(
|
|
|
309
331
|
|
|
310
332
|
return v2;
|
|
311
333
|
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Return the common top-level parent directory across every workspace
|
|
337
|
+
* package (mirror of init.ts:monorepoCommonRoot). Returns `'.'` when
|
|
338
|
+
* packages span multiple parents.
|
|
339
|
+
*/
|
|
340
|
+
function monorepoCommonRootMigrate(
|
|
341
|
+
packages: ReadonlyArray<{ path: string }>
|
|
342
|
+
): string {
|
|
343
|
+
const roots = monorepoDistinctRootsMigrate(packages);
|
|
344
|
+
return roots.length === 1 ? roots[0] : '.';
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Return the distinct top-level parent directories of every workspace
|
|
349
|
+
* package (mirror of init.ts:monorepoDistinctRoots). Sorted for determinism.
|
|
350
|
+
*/
|
|
351
|
+
function monorepoDistinctRootsMigrate(
|
|
352
|
+
packages: ReadonlyArray<{ path: string }>
|
|
353
|
+
): string[] {
|
|
354
|
+
const set = new Set<string>();
|
|
355
|
+
for (const p of packages) {
|
|
356
|
+
const parts = p.path.split('/');
|
|
357
|
+
if (parts.length > 1 && parts[0] !== '' && parts[0] !== '.') {
|
|
358
|
+
set.add(parts[0]);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return [...set].sort();
|
|
362
|
+
}
|
|
@@ -109,6 +109,25 @@ function extsFor(language: SupportedLanguage): string[] {
|
|
|
109
109
|
return EXTENSIONS[language] ?? [];
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Extensions for a language, with optional fallback for javascript-only repos
|
|
114
|
+
* that still contain `.ts`/`.tsx` files (no `typescript` manifest, no
|
|
115
|
+
* `tsconfig.json`). Fixes the bug where `apps/web/page.tsx` in a plain-JS
|
|
116
|
+
* monorepo is invisible to the javascript glob, causing `init --ci` to fall
|
|
117
|
+
* back to the nonexistent `src/`. See plan item P1-001 and incident
|
|
118
|
+
* `2026-04-20-massu-core-monorepo-paths-source.md`.
|
|
119
|
+
*/
|
|
120
|
+
function extsWithFallback(
|
|
121
|
+
language: SupportedLanguage,
|
|
122
|
+
fallbackTsForJs: boolean
|
|
123
|
+
): string[] {
|
|
124
|
+
const base = extsFor(language);
|
|
125
|
+
if (language === 'javascript' && fallbackTsForJs) {
|
|
126
|
+
return [...base, 'ts', 'tsx'];
|
|
127
|
+
}
|
|
128
|
+
return base;
|
|
129
|
+
}
|
|
130
|
+
|
|
112
131
|
function isTestPath(language: SupportedLanguage, path: string): boolean {
|
|
113
132
|
// Any dedicated test-dir keyword in the path segments
|
|
114
133
|
const segments = path.split('/');
|
|
@@ -144,14 +163,21 @@ function isInsideRoot(root: string, candidate: string): boolean {
|
|
|
144
163
|
*
|
|
145
164
|
* @param projectRoot absolute path to repo root
|
|
146
165
|
* @param languages list of languages to probe (derived from P1-001 manifests)
|
|
166
|
+
* @param opts optional flags:
|
|
167
|
+
* - `fallbackTsForJs`: when true AND the language is `javascript` AND no
|
|
168
|
+
* `typescript` manifest was discovered, also glob `.ts`/`.tsx`. This is
|
|
169
|
+
* the P1-001 fix for plain-JS monorepos (e.g. turbo with `next` in a
|
|
170
|
+
* package.json that lacks a typescript dep) that still use `.tsx`.
|
|
147
171
|
*/
|
|
148
172
|
export function detectSourceDirs(
|
|
149
173
|
projectRoot: string,
|
|
150
|
-
languages: SupportedLanguage[]
|
|
174
|
+
languages: SupportedLanguage[],
|
|
175
|
+
opts?: { fallbackTsForJs?: boolean }
|
|
151
176
|
): SourceDirMap {
|
|
177
|
+
const fallbackTsForJs = opts?.fallbackTsForJs ?? false;
|
|
152
178
|
const out: SourceDirMap = {};
|
|
153
179
|
for (const lang of languages) {
|
|
154
|
-
const exts =
|
|
180
|
+
const exts = extsWithFallback(lang, fallbackTsForJs);
|
|
155
181
|
if (exts.length === 0) continue;
|
|
156
182
|
const patterns = exts.map((e) => `**/*.${e}`);
|
|
157
183
|
let files: string[];
|