@geekyants/think-before 0.1.0 → 0.2.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 +48 -3
- package/dist/cli.js +122 -8
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +14 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +47 -0
- package/dist/config.js.map +1 -0
- package/dist/detect.d.ts +12 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +371 -0
- package/dist/detect.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/prompt.d.ts +6 -0
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +47 -0
- package/dist/prompt.js.map +1 -1
- package/dist/stack.d.ts +8 -0
- package/dist/stack.d.ts.map +1 -0
- package/dist/stack.js +119 -0
- package/dist/stack.js.map +1 -0
- package/dist/types.d.ts +28 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -49,6 +49,41 @@ think-before full --role engineer
|
|
|
49
49
|
think-before full --role developer
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
## Smart, stack-aware questions
|
|
53
|
+
|
|
54
|
+
Before each run, `think-before` does a quick **read-only scan of your working directory** and figures out whether it's **frontend**, **backend**, or **full-stack** — by recognizing common frameworks and tooling:
|
|
55
|
+
|
|
56
|
+
- **Frontend:** React, Vue, Angular, Svelte, SolidJS, Preact, React Native, Expo, Vite, Tailwind …
|
|
57
|
+
- **Backend:** Express, NestJS, Fastify, Koa, Django, Flask, FastAPI, Laravel, Symfony, Rails, Spring Boot, Go (Gin/Echo/Fiber), Actix/Axum, .NET …
|
|
58
|
+
- **Full-stack meta-frameworks:** Next.js, Nuxt, Remix, SvelteKit, Astro
|
|
59
|
+
- It also notices a **database/ORM** (Prisma, TypeORM, Sequelize, Mongoose, `pg`/`mysql`/`mongodb`, migrations), **Docker**, **monorepos**, and whether **tests** exist.
|
|
60
|
+
|
|
61
|
+
Based on what it finds, it appends a **Stack-specific** section with the questions that actually apply — API-contract and migration-safety questions for a backend, breakpoint/accessibility/shared-component questions for a frontend, deploy-ordering for full-stack, and so on.
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
Detected full-stack · Next.js, React · role: engineer
|
|
65
|
+
|
|
66
|
+
Stack-specific — full-stack (Next.js, React)
|
|
67
|
+
22/31 Does this change a request/response shape, field, or status code a client depends on? [y/n] …
|
|
68
|
+
26/31 Is the schema/migration reversible and backward-compatible with the running code? [y/n] …
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Skip the scan anytime with `--no-detect`.
|
|
72
|
+
|
|
73
|
+
## Your role & saved config
|
|
74
|
+
|
|
75
|
+
The first time you run it in a project, it asks **what your role is** (designer / engineer / developer) and tailors the stack questions to you. Your answer — plus the detected stack — is remembered per project in:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
~/.config/think-before/config.json # honors $XDG_CONFIG_HOME
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
So next time it doesn't ask again. To change it: `--role <r>` to set explicitly, or `--reset-role` to be asked again. See everything that's stored with:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
think-before config
|
|
85
|
+
```
|
|
86
|
+
|
|
52
87
|
## How to answer
|
|
53
88
|
|
|
54
89
|
Single keypress, no Enter needed:
|
|
@@ -68,7 +103,9 @@ Answers that point at risk get **flagged** with a one-line reason. At the end yo
|
|
|
68
103
|
## Options
|
|
69
104
|
|
|
70
105
|
```
|
|
71
|
-
--role <r>
|
|
106
|
+
--role <r> Set your role: designer | engineer | developer (remembered per project)
|
|
107
|
+
--reset-role Forget the saved role and ask again
|
|
108
|
+
--no-detect Skip the project scan and stack-specific questions
|
|
72
109
|
--save [file] Save a Markdown report (optionally to <file>) without asking
|
|
73
110
|
--no-save Don't save and don't ask
|
|
74
111
|
--list Print the checklist and exit (no prompts)
|
|
@@ -77,14 +114,22 @@ Answers that point at risk get **flagged** with a one-line reason. At the end yo
|
|
|
77
114
|
-h, --help Show this help
|
|
78
115
|
```
|
|
79
116
|
|
|
117
|
+
There's also a `config` mode (`think-before config`) that prints where your config lives, your saved role, and what was detected in the current directory.
|
|
118
|
+
|
|
80
119
|
The report is plain Markdown — drop it into a PR description, a ticket, or your design doc.
|
|
81
120
|
|
|
82
121
|
## Use as a library
|
|
83
122
|
|
|
84
123
|
```ts
|
|
85
|
-
import {
|
|
124
|
+
import {
|
|
125
|
+
quick, full, filterSections, runSession, buildMarkdown,
|
|
126
|
+
detectProject, stackSection,
|
|
127
|
+
} from "@geekyants/think-before";
|
|
128
|
+
|
|
129
|
+
const detection = detectProject(process.cwd()); // { kind: "fullstack", frameworks: [...] }
|
|
130
|
+
const extra = stackSection(detection, "engineer");
|
|
86
131
|
|
|
87
|
-
const sections = filterSections(full, "engineer");
|
|
132
|
+
const sections = [...filterSections(full, "engineer"), ...(extra ? [extra] : [])];
|
|
88
133
|
const result = await runSession(full, sections);
|
|
89
134
|
const markdown = buildMarkdown(full, result, new Date());
|
|
90
135
|
```
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,10 @@ import fs from "node:fs";
|
|
|
3
3
|
import { checklists } from "./checklists.js";
|
|
4
4
|
import { filterSections, runSession } from "./session.js";
|
|
5
5
|
import { buildMarkdown, defaultReportName, printList, printSummary, saveReport } from "./report.js";
|
|
6
|
-
import { askYesNo, closeInput } from "./prompt.js";
|
|
6
|
+
import { askChoice, askYesNo, closeInput } from "./prompt.js";
|
|
7
|
+
import { kindLabel, safeDetect } from "./detect.js";
|
|
8
|
+
import { configPath, loadConfig, saveConfig, setProjectRecord } from "./config.js";
|
|
9
|
+
import { stackSection } from "./stack.js";
|
|
7
10
|
import { bold, cyan, dim, green, setColor, yellow } from "./colors.js";
|
|
8
11
|
const VALID_ROLES = ["designer", "engineer", "developer", "shared"];
|
|
9
12
|
function readVersion() {
|
|
@@ -26,9 +29,12 @@ ${b("Usage")}
|
|
|
26
29
|
${b("Modes")}
|
|
27
30
|
quick Blast-radius check for a small change ${dim("(default)")}
|
|
28
31
|
full Full pre-development discovery checklist
|
|
32
|
+
config Show stored config + what was detected here
|
|
29
33
|
|
|
30
34
|
${b("Options")}
|
|
31
|
-
--role <r>
|
|
35
|
+
--role <r> Set your role: designer | engineer | developer (remembered per project)
|
|
36
|
+
--reset-role Forget the saved role and ask again
|
|
37
|
+
--no-detect Skip the project scan and stack-specific questions
|
|
32
38
|
--save [file] Save a Markdown report (optionally to <file>) without asking
|
|
33
39
|
--no-save Don't save and don't ask
|
|
34
40
|
--list Print the checklist and exit (no prompts)
|
|
@@ -36,6 +42,13 @@ ${b("Options")}
|
|
|
36
42
|
-v, --version Print version
|
|
37
43
|
-h, --help Show this help
|
|
38
44
|
|
|
45
|
+
${b("Smart questions")}
|
|
46
|
+
think-before scans the working directory, detects whether it's frontend,
|
|
47
|
+
backend, or full-stack (React, Next, Express, Django, Rails, …), and adds
|
|
48
|
+
stack-relevant questions. Your role + the detection are saved to
|
|
49
|
+
${dim(configPath())}
|
|
50
|
+
so you're not asked again next time.
|
|
51
|
+
|
|
39
52
|
${b("Keys during a session")}
|
|
40
53
|
${cyan("y")} yes · ${cyan("n")} no · ${cyan("s")} skip · ${cyan("?")} why this matters · ${cyan("q")} quit
|
|
41
54
|
|
|
@@ -44,10 +57,18 @@ ${b("Examples")}
|
|
|
44
57
|
npx @geekyants/think-before full
|
|
45
58
|
npx @geekyants/think-before full --role engineer
|
|
46
59
|
npx @geekyants/think-before quick --save
|
|
60
|
+
npx @geekyants/think-before config
|
|
47
61
|
`);
|
|
48
62
|
}
|
|
49
63
|
function parseArgs(argv) {
|
|
50
|
-
const opts = {
|
|
64
|
+
const opts = {
|
|
65
|
+
mode: "quick",
|
|
66
|
+
saveMode: "prompt",
|
|
67
|
+
list: false,
|
|
68
|
+
color: true,
|
|
69
|
+
detect: true,
|
|
70
|
+
resetRole: false,
|
|
71
|
+
};
|
|
51
72
|
for (let i = 0; i < argv.length; i++) {
|
|
52
73
|
const arg = argv[i];
|
|
53
74
|
switch (arg) {
|
|
@@ -67,6 +88,12 @@ function parseArgs(argv) {
|
|
|
67
88
|
case "--no-color":
|
|
68
89
|
opts.color = false;
|
|
69
90
|
break;
|
|
91
|
+
case "--no-detect":
|
|
92
|
+
opts.detect = false;
|
|
93
|
+
break;
|
|
94
|
+
case "--reset-role":
|
|
95
|
+
opts.resetRole = true;
|
|
96
|
+
break;
|
|
70
97
|
case "--no-save":
|
|
71
98
|
opts.saveMode = "off";
|
|
72
99
|
break;
|
|
@@ -104,19 +131,106 @@ function fail(message) {
|
|
|
104
131
|
console.error(dim("Run `think-before --help` for usage."));
|
|
105
132
|
process.exit(1);
|
|
106
133
|
}
|
|
134
|
+
const ROLE_CHOICES = [
|
|
135
|
+
{ key: "1", label: "Designer", value: "designer" },
|
|
136
|
+
{ key: "2", label: "Engineer / Architect", value: "engineer" },
|
|
137
|
+
{ key: "3", label: "Developer", value: "developer" },
|
|
138
|
+
];
|
|
139
|
+
async function askRole() {
|
|
140
|
+
console.log();
|
|
141
|
+
console.log(bold("What's your role on this project?"));
|
|
142
|
+
console.log(" " +
|
|
143
|
+
ROLE_CHOICES.map((c) => cyan(c.key) + dim(" " + c.label)).join(" "));
|
|
144
|
+
process.stdout.write(dim("Pick 1–3 (or q to skip) "));
|
|
145
|
+
const key = await askChoice(ROLE_CHOICES.map((c) => c.key));
|
|
146
|
+
process.stdout.write("\n");
|
|
147
|
+
return ROLE_CHOICES.find((c) => c.key === key)?.value;
|
|
148
|
+
}
|
|
149
|
+
function printDetection(detection, role) {
|
|
150
|
+
const parts = [cyan(kindLabel(detection.kind))];
|
|
151
|
+
if (detection.frameworks.length)
|
|
152
|
+
parts.push(dim(detection.frameworks.join(", ")));
|
|
153
|
+
let line = dim("Detected ") + parts.join(dim(" · "));
|
|
154
|
+
if (role)
|
|
155
|
+
line += dim(" · role: ") + cyan(role);
|
|
156
|
+
console.log();
|
|
157
|
+
console.log(line);
|
|
158
|
+
}
|
|
159
|
+
function printConfig(cwd) {
|
|
160
|
+
const cfg = loadConfig();
|
|
161
|
+
const rec = cfg.projects[cwd];
|
|
162
|
+
const detection = safeDetect(cwd);
|
|
163
|
+
console.log();
|
|
164
|
+
console.log(bold("think-before config"));
|
|
165
|
+
console.log(dim(" file: ") + configPath());
|
|
166
|
+
console.log(dim(" default role: ") + (cfg.defaultRole ?? dim("—")));
|
|
167
|
+
console.log(dim(" projects saved: ") + Object.keys(cfg.projects).length);
|
|
168
|
+
console.log();
|
|
169
|
+
console.log(bold("This project") + dim(" " + cwd));
|
|
170
|
+
if (detection) {
|
|
171
|
+
const fw = detection.frameworks.length ? ` (${detection.frameworks.join(", ")})` : "";
|
|
172
|
+
console.log(dim(" detected: ") + kindLabel(detection.kind) + fw);
|
|
173
|
+
console.log(dim(" signals: ") + (detection.signals.join(", ") || dim("none")));
|
|
174
|
+
console.log(dim(" flags: ") +
|
|
175
|
+
`database: ${detection.hasDatabase}, tests: ${detection.hasTests}, docker: ${detection.hasDocker}, monorepo: ${detection.isMonorepo}`);
|
|
176
|
+
}
|
|
177
|
+
console.log(dim(" saved role: ") + (rec?.role ?? dim("—")));
|
|
178
|
+
console.log();
|
|
179
|
+
}
|
|
107
180
|
async function main() {
|
|
108
181
|
const opts = parseArgs(process.argv.slice(2));
|
|
109
182
|
if (!opts.color)
|
|
110
183
|
setColor(false);
|
|
184
|
+
const cwd = process.cwd();
|
|
185
|
+
if (opts.mode === "config") {
|
|
186
|
+
printConfig(cwd);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
111
189
|
const checklist = checklists[opts.mode];
|
|
112
190
|
if (!checklist) {
|
|
113
|
-
fail(`Unknown mode: ${opts.mode}. Try "quick" or "
|
|
191
|
+
fail(`Unknown mode: ${opts.mode}. Try "quick", "full", or "config".`);
|
|
192
|
+
}
|
|
193
|
+
const detection = opts.detect ? safeDetect(cwd) : undefined;
|
|
194
|
+
// Resolve role: explicit flag > saved (unless resetting) > ask interactively.
|
|
195
|
+
const cfg = loadConfig();
|
|
196
|
+
const saved = cfg.projects[cwd];
|
|
197
|
+
let role = opts.role;
|
|
198
|
+
if (!role && !opts.resetRole)
|
|
199
|
+
role = saved?.role ?? cfg.defaultRole;
|
|
200
|
+
const interactive = Boolean(process.stdin.isTTY) && !opts.list;
|
|
201
|
+
let askedRole = false;
|
|
202
|
+
if (!role && interactive) {
|
|
203
|
+
role = await askRole();
|
|
204
|
+
askedRole = true;
|
|
205
|
+
}
|
|
206
|
+
else if (opts.resetRole && interactive) {
|
|
207
|
+
role = await askRole();
|
|
208
|
+
askedRole = true;
|
|
209
|
+
}
|
|
210
|
+
// Persist role + detection for next time (best effort — never block on it).
|
|
211
|
+
setProjectRecord(cfg, cwd, {
|
|
212
|
+
role,
|
|
213
|
+
kind: detection?.kind,
|
|
214
|
+
frameworks: detection?.frameworks,
|
|
215
|
+
updatedAt: new Date().toISOString(),
|
|
216
|
+
});
|
|
217
|
+
try {
|
|
218
|
+
saveConfig(cfg);
|
|
219
|
+
if (askedRole && role) {
|
|
220
|
+
console.log(dim("Saved to " + configPath() + " — change later with --reset-role."));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
/* read-only home; carry on without persistence */
|
|
114
225
|
}
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
-
|
|
226
|
+
if (detection)
|
|
227
|
+
printDetection(detection, role);
|
|
228
|
+
let sections = filterSections(checklist, role);
|
|
229
|
+
if (detection) {
|
|
230
|
+
const extra = stackSection(detection, role);
|
|
231
|
+
if (extra)
|
|
232
|
+
sections = [...sections, extra];
|
|
118
233
|
}
|
|
119
|
-
const sections = filterSections(checklist, opts.role);
|
|
120
234
|
if (opts.list) {
|
|
121
235
|
printList(checklist, sections);
|
|
122
236
|
return;
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Config, ProjectRecord } from "./types.js";
|
|
2
|
+
/** The directory we store user-level config in. Honors $XDG_CONFIG_HOME. */
|
|
3
|
+
export declare function configDir(): string;
|
|
4
|
+
/** The path to the config file itself. */
|
|
5
|
+
export declare function configPath(): string;
|
|
6
|
+
/** Load the user config, returning a fresh empty one if missing/corrupt. */
|
|
7
|
+
export declare function loadConfig(): Config;
|
|
8
|
+
/** Persist the config. Throws only if the directory can't be created/written. */
|
|
9
|
+
export declare function saveConfig(config: Config): void;
|
|
10
|
+
/** Look up what we remember about a project by absolute path. */
|
|
11
|
+
export declare function getProjectRecord(config: Config, projectPath: string): ProjectRecord | undefined;
|
|
12
|
+
/** Merge new facts about a project into the config (does not save). */
|
|
13
|
+
export declare function setProjectRecord(config: Config, projectPath: string, record: ProjectRecord): void;
|
|
14
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIxD,4EAA4E;AAC5E,wBAAgB,SAAS,IAAI,MAAM,CAIlC;AAED,0CAA0C;AAC1C,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAMD,4EAA4E;AAC5E,wBAAgB,UAAU,IAAI,MAAM,CAWnC;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAG/C;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAE/F;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAGjG"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const CONFIG_VERSION = 1;
|
|
5
|
+
/** The directory we store user-level config in. Honors $XDG_CONFIG_HOME. */
|
|
6
|
+
export function configDir() {
|
|
7
|
+
const xdg = process.env["XDG_CONFIG_HOME"];
|
|
8
|
+
const base = xdg && xdg.trim() ? xdg : path.join(os.homedir(), ".config");
|
|
9
|
+
return path.join(base, "think-before");
|
|
10
|
+
}
|
|
11
|
+
/** The path to the config file itself. */
|
|
12
|
+
export function configPath() {
|
|
13
|
+
return path.join(configDir(), "config.json");
|
|
14
|
+
}
|
|
15
|
+
function emptyConfig() {
|
|
16
|
+
return { version: CONFIG_VERSION, projects: {} };
|
|
17
|
+
}
|
|
18
|
+
/** Load the user config, returning a fresh empty one if missing/corrupt. */
|
|
19
|
+
export function loadConfig() {
|
|
20
|
+
try {
|
|
21
|
+
const raw = JSON.parse(fs.readFileSync(configPath(), "utf8"));
|
|
22
|
+
return {
|
|
23
|
+
version: typeof raw.version === "number" ? raw.version : CONFIG_VERSION,
|
|
24
|
+
defaultRole: raw.defaultRole,
|
|
25
|
+
projects: raw.projects ?? {},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return emptyConfig();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Persist the config. Throws only if the directory can't be created/written. */
|
|
33
|
+
export function saveConfig(config) {
|
|
34
|
+
fs.mkdirSync(configDir(), { recursive: true });
|
|
35
|
+
fs.writeFileSync(configPath(), JSON.stringify(config, null, 2) + "\n", "utf8");
|
|
36
|
+
}
|
|
37
|
+
/** Look up what we remember about a project by absolute path. */
|
|
38
|
+
export function getProjectRecord(config, projectPath) {
|
|
39
|
+
return config.projects[projectPath];
|
|
40
|
+
}
|
|
41
|
+
/** Merge new facts about a project into the config (does not save). */
|
|
42
|
+
export function setProjectRecord(config, projectPath, record) {
|
|
43
|
+
config.projects[projectPath] = { ...config.projects[projectPath], ...record };
|
|
44
|
+
if (record.role)
|
|
45
|
+
config.defaultRole = record.role;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,4EAA4E;AAC5E,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC1E,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;AACzC,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,WAAW;IAClB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AACnD,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,EAAE,MAAM,CAAC,CAAoB,CAAC;QACjF,OAAO;YACL,OAAO,EAAE,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc;YACvE,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE;SAC7B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AACjF,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,WAAmB;IAClE,OAAO,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACtC,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,WAAmB,EAAE,MAAqB;IACzF,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC;IAC9E,IAAI,MAAM,CAAC,IAAI;QAAE,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC;AACpD,CAAC"}
|
package/dist/detect.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Detection, ProjectKind } from "./types.js";
|
|
2
|
+
/** A friendly label for a project kind. */
|
|
3
|
+
export declare function kindLabel(kind: ProjectKind): string;
|
|
4
|
+
/**
|
|
5
|
+
* Scan a directory for common framework/tooling signals and classify it as
|
|
6
|
+
* frontend, backend, full-stack, or unknown. Read-only and quick: it reads a
|
|
7
|
+
* handful of manifest files and checks for a few marker folders. Never throws.
|
|
8
|
+
*/
|
|
9
|
+
export declare function detectProject(root?: string): Detection;
|
|
10
|
+
/** detectProject wrapped so detection failures never break a run. */
|
|
11
|
+
export declare function safeDetect(root?: string): Detection | undefined;
|
|
12
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAkFzD,2CAA2C;AAC3C,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAWnD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,GAAE,MAAsB,GAAG,SAAS,CA8OrE;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CAAC,IAAI,GAAE,MAAsB,GAAG,SAAS,GAAG,SAAS,CAM9E"}
|
package/dist/detect.js
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
// Dependency → human label maps. Matched against package.json deps. These cover
|
|
4
|
+
// the common frameworks on the market; add more as needed — it degrades to
|
|
5
|
+
// "unknown" gracefully when nothing matches.
|
|
6
|
+
const FRONTEND_DEPS = {
|
|
7
|
+
react: "React",
|
|
8
|
+
"react-dom": "React",
|
|
9
|
+
vue: "Vue",
|
|
10
|
+
"@angular/core": "Angular",
|
|
11
|
+
svelte: "Svelte",
|
|
12
|
+
"solid-js": "SolidJS",
|
|
13
|
+
preact: "Preact",
|
|
14
|
+
"@stencil/core": "Stencil",
|
|
15
|
+
gatsby: "Gatsby",
|
|
16
|
+
"react-native": "React Native",
|
|
17
|
+
expo: "Expo",
|
|
18
|
+
"@ionic/react": "Ionic",
|
|
19
|
+
"@ionic/angular": "Ionic",
|
|
20
|
+
};
|
|
21
|
+
// Meta-frameworks that ship a server as well as a client → count as both.
|
|
22
|
+
const FULLSTACK_DEPS = {
|
|
23
|
+
next: "Next.js",
|
|
24
|
+
nuxt: "Nuxt",
|
|
25
|
+
"@remix-run/react": "Remix",
|
|
26
|
+
"@remix-run/node": "Remix",
|
|
27
|
+
"@sveltejs/kit": "SvelteKit",
|
|
28
|
+
astro: "Astro",
|
|
29
|
+
};
|
|
30
|
+
const BACKEND_DEPS = {
|
|
31
|
+
express: "Express",
|
|
32
|
+
koa: "Koa",
|
|
33
|
+
fastify: "Fastify",
|
|
34
|
+
"@nestjs/core": "NestJS",
|
|
35
|
+
"@hapi/hapi": "hapi",
|
|
36
|
+
hapi: "hapi",
|
|
37
|
+
restify: "Restify",
|
|
38
|
+
"@apollo/server": "Apollo Server",
|
|
39
|
+
"apollo-server": "Apollo Server",
|
|
40
|
+
"@trpc/server": "tRPC",
|
|
41
|
+
"socket.io": "Socket.IO",
|
|
42
|
+
};
|
|
43
|
+
const DB_DEPS = new Set([
|
|
44
|
+
"prisma", "@prisma/client", "typeorm", "sequelize", "mongoose", "knex",
|
|
45
|
+
"drizzle-orm", "@mikro-orm/core", "pg", "mysql", "mysql2", "mongodb",
|
|
46
|
+
"redis", "ioredis", "better-sqlite3",
|
|
47
|
+
]);
|
|
48
|
+
const TEST_DEPS = new Set([
|
|
49
|
+
"jest", "vitest", "mocha", "@playwright/test", "cypress", "ava", "jasmine",
|
|
50
|
+
"supertest", "@testing-library/react", "@testing-library/vue",
|
|
51
|
+
]);
|
|
52
|
+
function readJson(p) {
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(fs.readFileSync(p, "utf8"));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function readText(p) {
|
|
61
|
+
try {
|
|
62
|
+
return fs.readFileSync(p, "utf8");
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return "";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function exists(p) {
|
|
69
|
+
try {
|
|
70
|
+
fs.accessSync(p);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** A friendly label for a project kind. */
|
|
78
|
+
export function kindLabel(kind) {
|
|
79
|
+
switch (kind) {
|
|
80
|
+
case "fullstack":
|
|
81
|
+
return "full-stack";
|
|
82
|
+
case "frontend":
|
|
83
|
+
return "frontend";
|
|
84
|
+
case "backend":
|
|
85
|
+
return "backend";
|
|
86
|
+
default:
|
|
87
|
+
return "unknown";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Scan a directory for common framework/tooling signals and classify it as
|
|
92
|
+
* frontend, backend, full-stack, or unknown. Read-only and quick: it reads a
|
|
93
|
+
* handful of manifest files and checks for a few marker folders. Never throws.
|
|
94
|
+
*/
|
|
95
|
+
export function detectProject(root = process.cwd()) {
|
|
96
|
+
const signals = new Set();
|
|
97
|
+
const frameworks = new Set();
|
|
98
|
+
let hasFrontend = false;
|
|
99
|
+
let hasBackend = false;
|
|
100
|
+
let hasDatabase = false;
|
|
101
|
+
let hasTests = false;
|
|
102
|
+
let hasDocker = false;
|
|
103
|
+
let isMonorepo = false;
|
|
104
|
+
const collectDeps = (pkg) => {
|
|
105
|
+
if (!pkg)
|
|
106
|
+
return;
|
|
107
|
+
const deps = {
|
|
108
|
+
...pkg["dependencies"],
|
|
109
|
+
...pkg["devDependencies"],
|
|
110
|
+
...pkg["peerDependencies"],
|
|
111
|
+
...pkg["optionalDependencies"],
|
|
112
|
+
};
|
|
113
|
+
for (const name of Object.keys(deps)) {
|
|
114
|
+
const fe = FRONTEND_DEPS[name];
|
|
115
|
+
if (fe) {
|
|
116
|
+
hasFrontend = true;
|
|
117
|
+
frameworks.add(fe);
|
|
118
|
+
}
|
|
119
|
+
const fs2 = FULLSTACK_DEPS[name];
|
|
120
|
+
if (fs2) {
|
|
121
|
+
hasFrontend = true;
|
|
122
|
+
hasBackend = true;
|
|
123
|
+
frameworks.add(fs2);
|
|
124
|
+
}
|
|
125
|
+
const be = BACKEND_DEPS[name];
|
|
126
|
+
if (be) {
|
|
127
|
+
hasBackend = true;
|
|
128
|
+
frameworks.add(be);
|
|
129
|
+
}
|
|
130
|
+
if (DB_DEPS.has(name))
|
|
131
|
+
hasDatabase = true;
|
|
132
|
+
if (TEST_DEPS.has(name))
|
|
133
|
+
hasTests = true;
|
|
134
|
+
}
|
|
135
|
+
if (pkg["workspaces"])
|
|
136
|
+
isMonorepo = true;
|
|
137
|
+
};
|
|
138
|
+
// --- Node / JS ecosystem ---
|
|
139
|
+
const rootPkg = readJson(path.join(root, "package.json"));
|
|
140
|
+
if (rootPkg) {
|
|
141
|
+
signals.add("package.json");
|
|
142
|
+
collectDeps(rootPkg);
|
|
143
|
+
}
|
|
144
|
+
for (const m of ["pnpm-workspace.yaml", "lerna.json", "turbo.json", "nx.json"]) {
|
|
145
|
+
if (exists(path.join(root, m))) {
|
|
146
|
+
isMonorepo = true;
|
|
147
|
+
signals.add(m);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// In a monorepo, peek one level into the usual group folders.
|
|
151
|
+
if (isMonorepo || exists(path.join(root, "apps")) || exists(path.join(root, "packages"))) {
|
|
152
|
+
for (const group of ["apps", "packages", "services"]) {
|
|
153
|
+
const gp = path.join(root, group);
|
|
154
|
+
if (!exists(gp))
|
|
155
|
+
continue;
|
|
156
|
+
let entries = [];
|
|
157
|
+
try {
|
|
158
|
+
entries = fs.readdirSync(gp);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
entries = [];
|
|
162
|
+
}
|
|
163
|
+
for (const entry of entries.slice(0, 30)) {
|
|
164
|
+
collectDeps(readJson(path.join(gp, entry, "package.json")));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// --- Python ---
|
|
169
|
+
const py = [
|
|
170
|
+
readText(path.join(root, "requirements.txt")),
|
|
171
|
+
readText(path.join(root, "pyproject.toml")),
|
|
172
|
+
readText(path.join(root, "Pipfile")),
|
|
173
|
+
].join("\n").toLowerCase();
|
|
174
|
+
if (py.trim()) {
|
|
175
|
+
signals.add("python deps");
|
|
176
|
+
let matched = false;
|
|
177
|
+
if (py.includes("django")) {
|
|
178
|
+
hasBackend = true;
|
|
179
|
+
frameworks.add("Django");
|
|
180
|
+
matched = true;
|
|
181
|
+
}
|
|
182
|
+
if (py.includes("flask")) {
|
|
183
|
+
hasBackend = true;
|
|
184
|
+
frameworks.add("Flask");
|
|
185
|
+
matched = true;
|
|
186
|
+
}
|
|
187
|
+
if (py.includes("fastapi")) {
|
|
188
|
+
hasBackend = true;
|
|
189
|
+
frameworks.add("FastAPI");
|
|
190
|
+
matched = true;
|
|
191
|
+
}
|
|
192
|
+
if (!matched) {
|
|
193
|
+
hasBackend = true;
|
|
194
|
+
frameworks.add("Python");
|
|
195
|
+
}
|
|
196
|
+
if (py.includes("pytest"))
|
|
197
|
+
hasTests = true;
|
|
198
|
+
}
|
|
199
|
+
if (exists(path.join(root, "manage.py"))) {
|
|
200
|
+
hasBackend = true;
|
|
201
|
+
frameworks.add("Django");
|
|
202
|
+
signals.add("manage.py");
|
|
203
|
+
}
|
|
204
|
+
// --- PHP ---
|
|
205
|
+
const composer = readJson(path.join(root, "composer.json"));
|
|
206
|
+
if (composer) {
|
|
207
|
+
signals.add("composer.json");
|
|
208
|
+
hasBackend = true;
|
|
209
|
+
const req = {
|
|
210
|
+
...composer["require"],
|
|
211
|
+
...composer["require-dev"],
|
|
212
|
+
};
|
|
213
|
+
const keys = Object.keys(req).join(" ").toLowerCase();
|
|
214
|
+
if (keys.includes("laravel/framework"))
|
|
215
|
+
frameworks.add("Laravel");
|
|
216
|
+
else if (keys.includes("symfony/"))
|
|
217
|
+
frameworks.add("Symfony");
|
|
218
|
+
else
|
|
219
|
+
frameworks.add("PHP");
|
|
220
|
+
if (keys.includes("phpunit"))
|
|
221
|
+
hasTests = true;
|
|
222
|
+
}
|
|
223
|
+
// --- Ruby ---
|
|
224
|
+
const gemfile = readText(path.join(root, "Gemfile")).toLowerCase();
|
|
225
|
+
if (gemfile.trim()) {
|
|
226
|
+
signals.add("Gemfile");
|
|
227
|
+
hasBackend = true;
|
|
228
|
+
if (gemfile.includes("rails"))
|
|
229
|
+
frameworks.add("Rails");
|
|
230
|
+
else
|
|
231
|
+
frameworks.add("Ruby");
|
|
232
|
+
if (gemfile.includes("rspec") || gemfile.includes("minitest"))
|
|
233
|
+
hasTests = true;
|
|
234
|
+
}
|
|
235
|
+
// --- Go ---
|
|
236
|
+
const gomod = readText(path.join(root, "go.mod")).toLowerCase();
|
|
237
|
+
if (gomod.trim()) {
|
|
238
|
+
signals.add("go.mod");
|
|
239
|
+
hasBackend = true;
|
|
240
|
+
if (gomod.includes("gin-gonic"))
|
|
241
|
+
frameworks.add("Gin");
|
|
242
|
+
else if (gomod.includes("labstack/echo"))
|
|
243
|
+
frameworks.add("Echo");
|
|
244
|
+
else if (gomod.includes("gofiber/fiber"))
|
|
245
|
+
frameworks.add("Fiber");
|
|
246
|
+
else if (gomod.includes("go-chi/chi"))
|
|
247
|
+
frameworks.add("chi");
|
|
248
|
+
else
|
|
249
|
+
frameworks.add("Go");
|
|
250
|
+
}
|
|
251
|
+
// --- Java / Kotlin ---
|
|
252
|
+
const jvm = (readText(path.join(root, "pom.xml")) +
|
|
253
|
+
readText(path.join(root, "build.gradle")) +
|
|
254
|
+
readText(path.join(root, "build.gradle.kts"))).toLowerCase();
|
|
255
|
+
if (jvm.trim()) {
|
|
256
|
+
signals.add(jvm.includes("<project") ? "pom.xml" : "build.gradle");
|
|
257
|
+
hasBackend = true;
|
|
258
|
+
if (jvm.includes("spring-boot") || jvm.includes("springframework"))
|
|
259
|
+
frameworks.add("Spring Boot");
|
|
260
|
+
else if (jvm.includes("ktor"))
|
|
261
|
+
frameworks.add("Ktor");
|
|
262
|
+
else
|
|
263
|
+
frameworks.add("JVM");
|
|
264
|
+
}
|
|
265
|
+
// --- Rust ---
|
|
266
|
+
const cargo = readText(path.join(root, "Cargo.toml")).toLowerCase();
|
|
267
|
+
if (cargo.trim()) {
|
|
268
|
+
signals.add("Cargo.toml");
|
|
269
|
+
hasBackend = true;
|
|
270
|
+
if (cargo.includes("actix-web"))
|
|
271
|
+
frameworks.add("Actix");
|
|
272
|
+
else if (cargo.includes("axum"))
|
|
273
|
+
frameworks.add("Axum");
|
|
274
|
+
else if (cargo.includes("rocket"))
|
|
275
|
+
frameworks.add("Rocket");
|
|
276
|
+
else
|
|
277
|
+
frameworks.add("Rust");
|
|
278
|
+
}
|
|
279
|
+
// --- .NET ---
|
|
280
|
+
try {
|
|
281
|
+
if (fs.readdirSync(root).some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
|
|
282
|
+
hasBackend = true;
|
|
283
|
+
frameworks.add(".NET");
|
|
284
|
+
signals.add(".csproj");
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
/* ignore unreadable dir */
|
|
289
|
+
}
|
|
290
|
+
// --- Frontend file/folder heuristics ---
|
|
291
|
+
const feMarkers = [
|
|
292
|
+
["angular.json", "Angular"],
|
|
293
|
+
["next.config.js", "Next.js"],
|
|
294
|
+
["next.config.mjs", "Next.js"],
|
|
295
|
+
["next.config.ts", "Next.js"],
|
|
296
|
+
["nuxt.config.ts", "Nuxt"],
|
|
297
|
+
["svelte.config.js", "Svelte"],
|
|
298
|
+
["vite.config.ts", "Vite"],
|
|
299
|
+
["vite.config.js", "Vite"],
|
|
300
|
+
["tailwind.config.js", "Tailwind"],
|
|
301
|
+
["tailwind.config.ts", "Tailwind"],
|
|
302
|
+
["astro.config.mjs", "Astro"],
|
|
303
|
+
];
|
|
304
|
+
for (const [file, label] of feMarkers) {
|
|
305
|
+
if (exists(path.join(root, file))) {
|
|
306
|
+
hasFrontend = true;
|
|
307
|
+
frameworks.add(label);
|
|
308
|
+
signals.add(file);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (exists(path.join(root, "index.html")) || exists(path.join(root, "public", "index.html"))) {
|
|
312
|
+
hasFrontend = true;
|
|
313
|
+
signals.add("index.html");
|
|
314
|
+
}
|
|
315
|
+
if (exists(path.join(root, "src", "components")) || exists(path.join(root, "src", "pages"))) {
|
|
316
|
+
hasFrontend = true;
|
|
317
|
+
}
|
|
318
|
+
// --- Backend folder heuristics ---
|
|
319
|
+
if (exists(path.join(root, "prisma")) || exists(path.join(root, "migrations"))) {
|
|
320
|
+
hasBackend = true;
|
|
321
|
+
hasDatabase = true;
|
|
322
|
+
signals.add("migrations");
|
|
323
|
+
}
|
|
324
|
+
for (const d of ["controllers", "routes", path.join("src", "controllers"), path.join("src", "routes"), "api"]) {
|
|
325
|
+
if (exists(path.join(root, d)))
|
|
326
|
+
hasBackend = true;
|
|
327
|
+
}
|
|
328
|
+
if (exists(path.join(root, "serverless.yml"))) {
|
|
329
|
+
hasBackend = true;
|
|
330
|
+
signals.add("serverless.yml");
|
|
331
|
+
}
|
|
332
|
+
// --- Cross-cutting ---
|
|
333
|
+
if (exists(path.join(root, "Dockerfile")) ||
|
|
334
|
+
exists(path.join(root, "docker-compose.yml")) ||
|
|
335
|
+
exists(path.join(root, "docker-compose.yaml"))) {
|
|
336
|
+
hasDocker = true;
|
|
337
|
+
signals.add("Docker");
|
|
338
|
+
}
|
|
339
|
+
for (const t of ["test", "tests", "__tests__", "e2e"]) {
|
|
340
|
+
if (exists(path.join(root, t)))
|
|
341
|
+
hasTests = true;
|
|
342
|
+
}
|
|
343
|
+
let kind;
|
|
344
|
+
if (hasFrontend && hasBackend)
|
|
345
|
+
kind = "fullstack";
|
|
346
|
+
else if (hasFrontend)
|
|
347
|
+
kind = "frontend";
|
|
348
|
+
else if (hasBackend)
|
|
349
|
+
kind = "backend";
|
|
350
|
+
else
|
|
351
|
+
kind = "unknown";
|
|
352
|
+
return {
|
|
353
|
+
kind,
|
|
354
|
+
frameworks: [...frameworks],
|
|
355
|
+
hasDatabase,
|
|
356
|
+
hasTests,
|
|
357
|
+
hasDocker,
|
|
358
|
+
isMonorepo,
|
|
359
|
+
signals: [...signals],
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
/** detectProject wrapped so detection failures never break a run. */
|
|
363
|
+
export function safeDetect(root = process.cwd()) {
|
|
364
|
+
try {
|
|
365
|
+
return detectProject(root);
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
return undefined;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export * from "./types.js";
|
|
2
2
|
export { quick, full, checklists } from "./checklists.js";
|
|
3
3
|
export { filterSections, runSession } from "./session.js";
|
|
4
|
-
export { askYesNo, closeInput } from "./prompt.js";
|
|
4
|
+
export { askYesNo, askChoice, closeInput } from "./prompt.js";
|
|
5
5
|
export { buildMarkdown, defaultReportName, printSummary, printList, saveReport } from "./report.js";
|
|
6
|
+
export { detectProject, safeDetect, kindLabel } from "./detect.js";
|
|
7
|
+
export { stackSection } from "./stack.js";
|
|
8
|
+
export { loadConfig, saveConfig, configDir, configPath, getProjectRecord, setProjectRecord, } from "./config.js";
|
|
6
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACL,UAAU,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
// Public API — import
|
|
1
|
+
// Public API — import `@geekyants/think-before` programmatically as a library.
|
|
2
2
|
//
|
|
3
|
-
// import { quick, full, runSession,
|
|
3
|
+
// import { quick, full, runSession, detectProject, stackSection } from "@geekyants/think-before";
|
|
4
4
|
export * from "./types.js";
|
|
5
5
|
export { quick, full, checklists } from "./checklists.js";
|
|
6
6
|
export { filterSections, runSession } from "./session.js";
|
|
7
|
-
export { askYesNo, closeInput } from "./prompt.js";
|
|
7
|
+
export { askYesNo, askChoice, closeInput } from "./prompt.js";
|
|
8
8
|
export { buildMarkdown, defaultReportName, printSummary, printList, saveReport } from "./report.js";
|
|
9
|
+
export { detectProject, safeDetect, kindLabel } from "./detect.js";
|
|
10
|
+
export { stackSection } from "./stack.js";
|
|
11
|
+
export { loadConfig, saveConfig, configDir, configPath, getProjectRecord, setProjectRecord, } from "./config.js";
|
|
9
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,oGAAoG;AAEpG,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACL,UAAU,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC"}
|
package/dist/prompt.d.ts
CHANGED
|
@@ -11,6 +11,12 @@ export type AnswerOrQuit = AnswerValue | "quit";
|
|
|
11
11
|
* still works in non-interactive contexts.
|
|
12
12
|
*/
|
|
13
13
|
export declare function askYesNo(why?: string): Promise<AnswerOrQuit>;
|
|
14
|
+
/**
|
|
15
|
+
* Ask the user to pick one of a set of single-character keys (e.g. ["1","2","3"]).
|
|
16
|
+
* Resolves the chosen key, or "quit" on q/Esc/Ctrl-C/EOF. Non-TTY input reads a
|
|
17
|
+
* line and matches its first relevant character.
|
|
18
|
+
*/
|
|
19
|
+
export declare function askChoice(keys: string[]): Promise<string | "quit">;
|
|
14
20
|
/** Release the shared line reader so the process can exit (non-TTY only). */
|
|
15
21
|
export declare function closeInput(): void;
|
|
16
22
|
//# sourceMappingURL=prompt.d.ts.map
|
package/dist/prompt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,MAAM,CAAC;AAEhD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAyC5D;
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,MAAM,CAAC;AAEhD;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAyC5D;AA+BD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,CA2ClE;AAaD,6EAA6E;AAC7E,wBAAgB,UAAU,IAAI,IAAI,CAKjC"}
|
package/dist/prompt.js
CHANGED
|
@@ -83,6 +83,53 @@ function readLineOnce() {
|
|
|
83
83
|
return Promise.resolve(queued);
|
|
84
84
|
return new Promise((resolve) => waiters.push(resolve));
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Ask the user to pick one of a set of single-character keys (e.g. ["1","2","3"]).
|
|
88
|
+
* Resolves the chosen key, or "quit" on q/Esc/Ctrl-C/EOF. Non-TTY input reads a
|
|
89
|
+
* line and matches its first relevant character.
|
|
90
|
+
*/
|
|
91
|
+
export function askChoice(keys) {
|
|
92
|
+
const allowed = keys.map((k) => k.toLowerCase());
|
|
93
|
+
const stdin = process.stdin;
|
|
94
|
+
if (!stdin.isTTY) {
|
|
95
|
+
return readLineOnce().then((line) => {
|
|
96
|
+
if (line === null)
|
|
97
|
+
return "quit";
|
|
98
|
+
const text = line.trim().toLowerCase();
|
|
99
|
+
if (text.startsWith("q"))
|
|
100
|
+
return "quit";
|
|
101
|
+
const hit = [...text].find((ch) => allowed.includes(ch));
|
|
102
|
+
return hit ?? "quit";
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return new Promise((resolve) => {
|
|
106
|
+
readline.emitKeypressEvents(stdin);
|
|
107
|
+
stdin.setRawMode(true);
|
|
108
|
+
stdin.resume();
|
|
109
|
+
const cleanup = () => {
|
|
110
|
+
stdin.removeListener("keypress", onKey);
|
|
111
|
+
stdin.setRawMode(false);
|
|
112
|
+
stdin.pause();
|
|
113
|
+
};
|
|
114
|
+
const onKey = (str, key) => {
|
|
115
|
+
if (key && key.ctrl && key.name === "c") {
|
|
116
|
+
cleanup();
|
|
117
|
+
resolve("quit");
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const k = (str || "").toLowerCase();
|
|
121
|
+
if (k === "q" || (key && key.name === "escape")) {
|
|
122
|
+
cleanup();
|
|
123
|
+
resolve("quit");
|
|
124
|
+
}
|
|
125
|
+
else if (allowed.includes(k)) {
|
|
126
|
+
cleanup();
|
|
127
|
+
resolve(k);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
stdin.on("keypress", onKey);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
86
133
|
function askLine() {
|
|
87
134
|
return readLineOnce().then((line) => {
|
|
88
135
|
if (line === null)
|
package/dist/prompt.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"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"}
|
package/dist/stack.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Detection, Role, Section } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Build a stack-tailored Section from a detection result, filtered to the
|
|
4
|
+
* user's role when known. Returns null when there's nothing relevant to add
|
|
5
|
+
* (e.g. an unknown stack).
|
|
6
|
+
*/
|
|
7
|
+
export declare function stackSection(detection: Detection, role?: Role): Section | null;
|
|
8
|
+
//# sourceMappingURL=stack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../src/stack.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAY,IAAI,EAAe,OAAO,EAAE,MAAM,YAAY,CAAC;AAsIlF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,GAAG,IAAI,CAgB9E"}
|
package/dist/stack.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { kindLabel } from "./detect.js";
|
|
2
|
+
const ALL_ROLES = ["designer", "engineer", "developer"];
|
|
3
|
+
const TECH_ROLES = ["engineer", "developer"];
|
|
4
|
+
const isFrontend = (d) => d.kind === "frontend" || d.kind === "fullstack";
|
|
5
|
+
const isBackend = (d) => d.kind === "backend" || d.kind === "fullstack";
|
|
6
|
+
const hasDb = (d) => isBackend(d) && d.hasDatabase;
|
|
7
|
+
const isFullstack = (d) => d.kind === "fullstack";
|
|
8
|
+
function q(id, text, risky, why) {
|
|
9
|
+
return { id, text, risky, why };
|
|
10
|
+
}
|
|
11
|
+
const CANDIDATES = [
|
|
12
|
+
// --- Frontend ---
|
|
13
|
+
{
|
|
14
|
+
when: isFrontend,
|
|
15
|
+
roles: ALL_ROLES,
|
|
16
|
+
q: q("fe-breakpoints", "Have you checked this across the breakpoints, devices, and viewports the app supports?", "no", "Layout side-effects love to hide on the screen sizes you didn't open."),
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
when: isFrontend,
|
|
20
|
+
roles: ALL_ROLES,
|
|
21
|
+
q: q("fe-a11y", "Will keyboard navigation, focus order, and screen-reader output still work after this?", "no", "Accessibility regressions are invisible until someone who relies on them hits them."),
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
when: isFrontend,
|
|
25
|
+
roles: ALL_ROLES,
|
|
26
|
+
q: q("fe-shared-ui", "Is this a shared component, style, or design token reused across many screens?", "yes", "One tweak to a shared UI primitive re-renders everywhere it's used."),
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
when: isFrontend,
|
|
30
|
+
roles: TECH_ROLES,
|
|
31
|
+
q: q("fe-state", "Could this change shared client state, context, or a global store other views read?", "yes", "Global state is a hidden contract between unrelated screens."),
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
when: isFrontend,
|
|
35
|
+
roles: TECH_ROLES,
|
|
36
|
+
q: q("fe-bundle", "Could this noticeably grow the bundle or block the main thread (heavy dep, sync work)?", "yes", "A small import can drag a large dependency — and the user's first paint — with it."),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
when: isFrontend,
|
|
40
|
+
roles: TECH_ROLES,
|
|
41
|
+
q: q("fe-cache", "Could cached assets, a service worker, or localStorage from the old version conflict with this?", "yes", "Returning users run a mix of old and new code until caches clear."),
|
|
42
|
+
},
|
|
43
|
+
// --- Backend ---
|
|
44
|
+
{
|
|
45
|
+
when: isBackend,
|
|
46
|
+
roles: TECH_ROLES,
|
|
47
|
+
q: q("be-api-contract", "Does this change a request/response shape, field, or status code a client depends on?", "yes", "Clients you can't see — web, mobile, integrations — break the moment the contract shifts."),
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
when: isBackend,
|
|
51
|
+
roles: TECH_ROLES,
|
|
52
|
+
q: q("be-authz", "Does this touch authentication, authorization, or tenant/data isolation?", "yes", "Authz mistakes are high-severity and rarely caught by happy-path testing."),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
when: isBackend,
|
|
56
|
+
roles: TECH_ROLES,
|
|
57
|
+
q: q("be-idempotent", "Are retries and duplicate requests safe (idempotent), with failures handled cleanly?", "no", "Networks retry. Non-idempotent handlers double-charge, double-send, double-write."),
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
when: isBackend,
|
|
61
|
+
roles: TECH_ROLES,
|
|
62
|
+
q: q("be-external", "Does this add a call to an external service with rate limits, latency, or per-call cost?", "yes", "Their outage, throttle, or bill becomes your outage, throttle, or bill."),
|
|
63
|
+
},
|
|
64
|
+
// --- Database (backend + a data layer detected) ---
|
|
65
|
+
{
|
|
66
|
+
when: hasDb,
|
|
67
|
+
roles: TECH_ROLES,
|
|
68
|
+
q: q("db-migration", "Is the schema/migration reversible and backward-compatible with the running code?", "no", "Deploys aren't atomic — old code runs against the new schema for a window."),
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
when: hasDb,
|
|
72
|
+
roles: TECH_ROLES,
|
|
73
|
+
q: q("db-transaction", "Do multi-step writes run in a transaction so a partial failure can't corrupt data?", "no", "A crash between two writes is the bug you only find in production."),
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
when: hasDb,
|
|
77
|
+
roles: TECH_ROLES,
|
|
78
|
+
q: q("db-nplus1", "Could this introduce an N+1 query or an unindexed scan on a hot path?", "yes", "Fine on your seed data; a table scan at production scale."),
|
|
79
|
+
},
|
|
80
|
+
// --- Full-stack boundary ---
|
|
81
|
+
{
|
|
82
|
+
when: isFullstack,
|
|
83
|
+
roles: TECH_ROLES,
|
|
84
|
+
q: q("fs-deploy-order", "If both API and client change, can they deploy independently without breaking each other?", "no", "Front end and back end rarely deploy in the same instant — plan for the gap."),
|
|
85
|
+
},
|
|
86
|
+
// --- Detection-driven ---
|
|
87
|
+
{
|
|
88
|
+
when: (d) => !d.hasTests,
|
|
89
|
+
roles: TECH_ROLES,
|
|
90
|
+
q: q("no-tests", "No test setup was detected here — will you add a test or a written manual check for this change?", "no", "Untested changes to an unfamiliar codebase are how 'small' becomes 'incident'."),
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
when: (d) => d.hasDocker,
|
|
94
|
+
roles: TECH_ROLES,
|
|
95
|
+
q: q("docker-parity", "Will this still work in the container / deploy environment, not just your local machine?", "no", "Env vars, file paths, and timezones differ between your laptop and the container."),
|
|
96
|
+
},
|
|
97
|
+
];
|
|
98
|
+
/**
|
|
99
|
+
* Build a stack-tailored Section from a detection result, filtered to the
|
|
100
|
+
* user's role when known. Returns null when there's nothing relevant to add
|
|
101
|
+
* (e.g. an unknown stack).
|
|
102
|
+
*/
|
|
103
|
+
export function stackSection(detection, role) {
|
|
104
|
+
if (detection.kind === "unknown")
|
|
105
|
+
return null;
|
|
106
|
+
const questions = CANDIDATES.filter((c) => c.when(detection))
|
|
107
|
+
.filter((c) => !role || c.roles.includes(role))
|
|
108
|
+
.map((c) => c.q);
|
|
109
|
+
if (questions.length === 0)
|
|
110
|
+
return null;
|
|
111
|
+
const fw = detection.frameworks.length ? ` (${detection.frameworks.join(", ")})` : "";
|
|
112
|
+
return {
|
|
113
|
+
id: "stack",
|
|
114
|
+
title: `Stack-specific — ${kindLabel(detection.kind)}${fw}`,
|
|
115
|
+
roles: ["shared"],
|
|
116
|
+
questions,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack.js","sourceRoot":"","sources":["../src/stack.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -44,4 +44,32 @@ export interface SessionResult {
|
|
|
44
44
|
/** True if the user quit before answering every question. */
|
|
45
45
|
aborted: boolean;
|
|
46
46
|
}
|
|
47
|
+
/** What kind of project the working directory looks like. */
|
|
48
|
+
export type ProjectKind = "frontend" | "backend" | "fullstack" | "unknown";
|
|
49
|
+
/** The result of scanning the working directory for stack signals. */
|
|
50
|
+
export interface Detection {
|
|
51
|
+
kind: ProjectKind;
|
|
52
|
+
/** Human-readable frameworks/tools found, e.g. ["React", "Express"]. */
|
|
53
|
+
frameworks: string[];
|
|
54
|
+
hasDatabase: boolean;
|
|
55
|
+
hasTests: boolean;
|
|
56
|
+
hasDocker: boolean;
|
|
57
|
+
isMonorepo: boolean;
|
|
58
|
+
/** The marker files/folders that drove the detection (for transparency). */
|
|
59
|
+
signals: string[];
|
|
60
|
+
}
|
|
61
|
+
/** What we remember about one project between runs. */
|
|
62
|
+
export interface ProjectRecord {
|
|
63
|
+
role?: Role;
|
|
64
|
+
kind?: ProjectKind;
|
|
65
|
+
frameworks?: string[];
|
|
66
|
+
updatedAt?: string;
|
|
67
|
+
}
|
|
68
|
+
/** The user-level config persisted under ~/.config/think-before. */
|
|
69
|
+
export interface Config {
|
|
70
|
+
version: number;
|
|
71
|
+
defaultRole?: Role;
|
|
72
|
+
/** Keyed by absolute project path. */
|
|
73
|
+
projects: Record<string, ProjectRecord>;
|
|
74
|
+
}
|
|
47
75
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,CAAC;AAEvC,yCAAyC;AACzC,MAAM,WAAW,QAAQ;IACvB,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,KAAK,EAAE,WAAW,CAAC;IACnB,wFAAwF;IACxF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,sEAAsE;AACtE,MAAM,MAAM,IAAI,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;AAEpE,2CAA2C;AAC3C,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,yCAAyC;AACzC,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,uCAAuC;AACvC,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC;AAEhD,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,+DAA+D;IAC/D,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,6DAA6D;IAC7D,OAAO,EAAE,OAAO,CAAC;CAClB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,CAAC;AAEvC,yCAAyC;AACzC,MAAM,WAAW,QAAQ;IACvB,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IACX,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,KAAK,EAAE,WAAW,CAAC;IACnB,wFAAwF;IACxF,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,sEAAsE;AACtE,MAAM,MAAM,IAAI,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;AAEpE,2CAA2C;AAC3C,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;CACvB;AAED,yCAAyC;AACzC,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,uCAAuC;AACvC,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC;AAEhD,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,+DAA+D;IAC/D,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,6DAA6D;IAC7D,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,6DAA6D;AAC7D,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAE3E,sEAAsE;AACtE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,WAAW,CAAC;IAClB,wEAAwE;IACxE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,oEAAoE;AACpE,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACzC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekyants/think-before",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A fast yes/no reflection CLI to surface the side-effects of a change before you make it. Think before you touch the big app.",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "A fast yes/no reflection CLI to surface the side-effects of a change before you make it. Scans your project (frontend/backend/full-stack) and asks stack-relevant questions. Think before you touch the big app.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"think-before": "dist/cli.js"
|