@prestyj/cli 4.3.160 → 4.3.164

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.
Files changed (63) hide show
  1. package/dist/cli.d.ts +1 -1
  2. package/dist/cli.js +7 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/core/language-detector.d.ts +32 -0
  5. package/dist/core/language-detector.d.ts.map +1 -0
  6. package/dist/core/language-detector.js +191 -0
  7. package/dist/core/language-detector.js.map +1 -0
  8. package/dist/core/language-detector.test.d.ts +2 -0
  9. package/dist/core/language-detector.test.d.ts.map +1 -0
  10. package/dist/core/language-detector.test.js +109 -0
  11. package/dist/core/language-detector.test.js.map +1 -0
  12. package/dist/core/prompt-commands.d.ts.map +1 -1
  13. package/dist/core/prompt-commands.js +93 -0
  14. package/dist/core/prompt-commands.js.map +1 -1
  15. package/dist/core/setup-history.d.ts +13 -0
  16. package/dist/core/setup-history.d.ts.map +1 -0
  17. package/dist/core/setup-history.js +71 -0
  18. package/dist/core/setup-history.js.map +1 -0
  19. package/dist/core/setup-history.test.d.ts +2 -0
  20. package/dist/core/setup-history.test.d.ts.map +1 -0
  21. package/dist/core/setup-history.test.js +74 -0
  22. package/dist/core/setup-history.test.js.map +1 -0
  23. package/dist/core/style-packs/index.d.ts +19 -0
  24. package/dist/core/style-packs/index.d.ts.map +1 -0
  25. package/dist/core/style-packs/index.js +70 -0
  26. package/dist/core/style-packs/index.js.map +1 -0
  27. package/dist/core/style-packs/packs.d.ts +18 -0
  28. package/dist/core/style-packs/packs.d.ts.map +1 -0
  29. package/dist/core/style-packs/packs.js +229 -0
  30. package/dist/core/style-packs/packs.js.map +1 -0
  31. package/dist/core/verify-commands.d.ts +35 -0
  32. package/dist/core/verify-commands.d.ts.map +1 -0
  33. package/dist/core/verify-commands.js +209 -0
  34. package/dist/core/verify-commands.js.map +1 -0
  35. package/dist/core/verify-commands.test.d.ts +2 -0
  36. package/dist/core/verify-commands.test.d.ts.map +1 -0
  37. package/dist/core/verify-commands.test.js +85 -0
  38. package/dist/core/verify-commands.test.js.map +1 -0
  39. package/dist/system-prompt.d.ts +2 -1
  40. package/dist/system-prompt.d.ts.map +1 -1
  41. package/dist/system-prompt.js +32 -5
  42. package/dist/system-prompt.js.map +1 -1
  43. package/dist/tools/prompt-hints.js +1 -1
  44. package/dist/tools/prompt-hints.js.map +1 -1
  45. package/dist/ui/App.d.ts +23 -1
  46. package/dist/ui/App.d.ts.map +1 -1
  47. package/dist/ui/App.js +227 -15
  48. package/dist/ui/App.js.map +1 -1
  49. package/dist/ui/pixel.test.js +1 -1
  50. package/dist/ui/pixel.test.js.map +1 -1
  51. package/dist/ui/render.d.ts +8 -0
  52. package/dist/ui/render.d.ts.map +1 -1
  53. package/dist/ui/render.js +2 -0
  54. package/dist/ui/render.js.map +1 -1
  55. package/dist/ui/theme/dark-ansi.json +2 -1
  56. package/dist/ui/theme/dark-daltonized.json +2 -1
  57. package/dist/ui/theme/dark.json +2 -1
  58. package/dist/ui/theme/light-ansi.json +2 -1
  59. package/dist/ui/theme/light-daltonized.json +2 -1
  60. package/dist/ui/theme/light.json +2 -1
  61. package/dist/ui/theme/theme.d.ts +1 -0
  62. package/dist/ui/theme/theme.d.ts.map +1 -1
  63. package/package.json +3 -3
@@ -0,0 +1,109 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { detectLanguages, isStrictSuperset, languagesToSortedArray, } from "./language-detector.js";
6
+ let tmpDir;
7
+ beforeEach(() => {
8
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "lang-detect-"));
9
+ });
10
+ afterEach(() => {
11
+ fs.rmSync(tmpDir, { recursive: true, force: true });
12
+ });
13
+ function touch(rel) {
14
+ const full = path.join(tmpDir, rel);
15
+ fs.mkdirSync(path.dirname(full), { recursive: true });
16
+ fs.writeFileSync(full, "");
17
+ }
18
+ describe("detectLanguages", () => {
19
+ it("returns an empty set for an empty directory", () => {
20
+ expect(detectLanguages(tmpDir).size).toBe(0);
21
+ });
22
+ it("detects TypeScript via tsconfig.json", () => {
23
+ touch("tsconfig.json");
24
+ touch("package.json");
25
+ const detected = detectLanguages(tmpDir);
26
+ expect(detected.has("typescript")).toBe(true);
27
+ // JS is suppressed when TS is present
28
+ expect(detected.has("javascript")).toBe(false);
29
+ });
30
+ it("detects JavaScript only when no tsconfig", () => {
31
+ touch("package.json");
32
+ const detected = detectLanguages(tmpDir);
33
+ expect(detected.has("javascript")).toBe(true);
34
+ expect(detected.has("typescript")).toBe(false);
35
+ });
36
+ it("detects Python via pyproject.toml", () => {
37
+ touch("pyproject.toml");
38
+ expect(detectLanguages(tmpDir).has("python")).toBe(true);
39
+ });
40
+ it("detects Go via go.mod", () => {
41
+ touch("go.mod");
42
+ expect(detectLanguages(tmpDir).has("go")).toBe(true);
43
+ });
44
+ it("detects Rust via Cargo.toml", () => {
45
+ touch("Cargo.toml");
46
+ expect(detectLanguages(tmpDir).has("rust")).toBe(true);
47
+ });
48
+ it("detects multiple languages in a polyglot repo", () => {
49
+ touch("package.json");
50
+ touch("tsconfig.json");
51
+ touch("pyproject.toml");
52
+ touch("Cargo.toml");
53
+ const detected = detectLanguages(tmpDir);
54
+ expect(detected.has("typescript")).toBe(true);
55
+ expect(detected.has("python")).toBe(true);
56
+ expect(detected.has("rust")).toBe(true);
57
+ expect(detected.has("javascript")).toBe(false); // suppressed by TS
58
+ });
59
+ it("detects extension-only languages (C, SQL, Bash)", () => {
60
+ touch("script.sh");
61
+ touch("query.sql");
62
+ touch("main.c");
63
+ const detected = detectLanguages(tmpDir);
64
+ expect(detected.has("bash")).toBe(true);
65
+ expect(detected.has("sql")).toBe(true);
66
+ expect(detected.has("c")).toBe(true);
67
+ });
68
+ it("prefers C++ over C when .cpp sources exist alongside headers", () => {
69
+ touch("src/main.cpp");
70
+ touch("src/util.h");
71
+ const detected = detectLanguages(tmpDir);
72
+ expect(detected.has("cpp")).toBe(true);
73
+ expect(detected.has("c")).toBe(false);
74
+ });
75
+ it("does not crash on unreadable subdirs", () => {
76
+ touch("tsconfig.json");
77
+ // Pretend `src/` exists but is unreadable — just don't create it.
78
+ expect(() => detectLanguages(tmpDir)).not.toThrow();
79
+ });
80
+ });
81
+ describe("isStrictSuperset", () => {
82
+ it("returns true when next has all of prev plus more", () => {
83
+ const prev = new Set(["typescript"]);
84
+ const next = new Set(["typescript", "python"]);
85
+ expect(isStrictSuperset(next, prev)).toBe(true);
86
+ });
87
+ it("returns false when sets are equal", () => {
88
+ const a = new Set(["typescript", "python"]);
89
+ const b = new Set(["typescript", "python"]);
90
+ expect(isStrictSuperset(a, b)).toBe(false);
91
+ });
92
+ it("returns false when next is missing a member of prev", () => {
93
+ const prev = new Set(["typescript", "python"]);
94
+ const next = new Set(["typescript", "rust"]);
95
+ expect(isStrictSuperset(next, prev)).toBe(false);
96
+ });
97
+ it("returns false when next is smaller", () => {
98
+ const prev = new Set(["typescript", "python"]);
99
+ const next = new Set(["typescript"]);
100
+ expect(isStrictSuperset(next, prev)).toBe(false);
101
+ });
102
+ });
103
+ describe("languagesToSortedArray", () => {
104
+ it("returns a deterministic sorted order", () => {
105
+ const set = new Set(["rust", "typescript", "python"]);
106
+ expect(languagesToSortedArray(set)).toEqual(["python", "rust", "typescript"]);
107
+ });
108
+ });
109
+ //# sourceMappingURL=language-detector.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language-detector.test.js","sourceRoot":"","sources":["../../src/core/language-detector.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-commands.d.ts","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,eAAe,EAAE,aAAa,EAy0B1C,CAAC;AAEF,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAExE"}
1
+ {"version":3,"file":"prompt-commands.d.ts","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,eAAe,EAAE,aAAa,EAs6B1C,CAAC;AAEF,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAExE"}
@@ -843,6 +843,99 @@ If strong candidates had no ecosystem match, list them at the bottom:
843
843
 
844
844
  After presenting the list, ask which (if any) to install. Install nothing without explicit confirmation. Once confirmed, hand off to find-skills to perform the actual install.`,
845
845
  },
846
+ {
847
+ name: "setup",
848
+ aliases: ["setup-project"],
849
+ description: "Audit project hygiene, tooling, verify pipeline, and style-pack alignment",
850
+ prompt: `Audit this project across six categories and report gaps. **Do not fix anything yet.** Wait for me to choose what to address after the report.
851
+
852
+ Language-agnostic and project-agnostic — adapt findings to the languages and stack actually present. Ignore categories that don't apply (e.g. skip CI for a local-only scratchpad).
853
+
854
+ ## Categories
855
+
856
+ ### 1. Project hygiene
857
+
858
+ - \`.gitignore\` present and covers the active language(s)?
859
+ - \`README.md\` present with at least install + run instructions?
860
+ - License file present (if this looks like a public/shareable project)?
861
+ - \`.editorconfig\` present?
862
+ - Git initialized? (\`.git\` directory exists)
863
+
864
+ ### 2. Toolchain version pinning
865
+
866
+ - Language version pinned in a canonical file: \`.nvmrc\` / \`package.json#engines\` (Node), \`.python-version\` / \`pyproject.toml#requires-python\` (Python), \`rust-toolchain.toml\` (Rust), the \`go\` line in \`go.mod\`, \`.ruby-version\` (Ruby), etc.
867
+ - Lockfile present and committed? (\`package-lock.json\`, \`pnpm-lock.yaml\`, \`yarn.lock\`, \`bun.lockb\`, \`uv.lock\`, \`poetry.lock\`, \`Cargo.lock\`, \`go.sum\`, \`Gemfile.lock\`, \`composer.lock\`)
868
+
869
+ ### 3. Code quality tooling
870
+
871
+ For each active language, check that a formatter, linter, and (where applicable) type checker are configured:
872
+ - **Formatter**: Prettier / ruff format / gofmt (built-in) / rustfmt (built-in) / clang-format / etc.
873
+ - **Linter**: ESLint / Ruff / golangci-lint / Clippy / etc. — with a reasonable strictness preset
874
+ - **Type checker** (statically-typed langs only): tsc strict, Pyright strict, mypy strict
875
+ - **Test framework**: vitest / jest / pytest / go test / cargo test / rspec / etc.
876
+
877
+ Report which are present, missing, or configured below the pack's strictness recommendation.
878
+
879
+ ### 4. Verify pipeline
880
+
881
+ - Are \`lint\` / \`typecheck\` / \`format:check\` / \`test\` (or language-equivalent) wired as runnable commands? (scripts in \`package.json\`, \`pyproject.toml\`, a \`Makefile\`, or \`justfile\`)
882
+ - Pre-commit hook configured? (\`.husky/\`, \`pre-commit\` framework, \`lefthook\`, etc.) — nice-to-have, not required.
883
+ - CI config present? (\`.github/workflows/\`, \`.gitlab-ci.yml\`, \`.circleci/\`, etc.)
884
+
885
+ ### 5. Style pack alignment
886
+
887
+ "Active style packs" refers specifically to the per-language sub-sections inside the **Language Style Packs** section in your system prompt (e.g. \`### TypeScript\`, \`### Python\`, \`### Go\`). It does **NOT** include the cross-cutting \`### Agent-Written Code\` preamble that sits above them — those are guidelines for how code is *written*, not project-scaffolding to audit. It also does **NOT** include Skills (\`.ezcoder/skills/\`) or any other extension category. If the Language Style Packs section is absent or empty, **skip this entire section entirely** — do not substitute Skills or any other concept.
888
+
889
+ When per-language packs are present, compare the project against each pack's **Tooling** bullet and the system prompt's **Verification** commands:
890
+ - Tooling: which strict-mode flags or lint-rule presets does the pack recommend that the project is missing? (e.g. \`tsconfig\` missing \`noUncheckedIndexedAccess\`, \`pyproject\` missing \`[tool.ruff]\`, Go project missing \`golangci-lint\` config).
891
+ - Dependencies: list which pack-mentioned libs (Zod, Pydantic, thiserror, anyhow, etc.) the project uses, has an equivalent for, or lacks. **Observation only — no recommendation to install.**
892
+
893
+ ### 6. Documentation hygiene
894
+
895
+ - \`CLAUDE.md\` or \`AGENTS.md\` present?
896
+ - Public API documented? (top-level docstrings, type signatures, or README examples)
897
+ - Architecture doc for non-trivial projects? (\`ARCHITECTURE.md\`, \`docs/architecture/\`, ADRs)
898
+
899
+ ## How to investigate
900
+
901
+ - Read the project root + obvious config locations (\`./\`, \`.github/\`, \`.husky/\`, \`docs/\`).
902
+ - Don't recurse into \`node_modules\`, \`dist\`, \`build\`, \`target\`, vendored folders.
903
+ - Use \`ls\`, \`read\`, \`find\` (with name patterns) — do not \`grep\` source code for this audit; it's about scaffolding, not code review.
904
+ - Cap at ~20 file reads total. If a file is huge (e.g. \`pnpm-lock.yaml\`), don't read its body — presence is what matters.
905
+
906
+ ## Output format
907
+
908
+ A single Markdown report, organized by category. Within each category, mark each item as one of:
909
+ - \`[OK]\` — present and reasonable
910
+ - \`[GAP]\` — missing or misconfigured; safe to add/fix
911
+ - \`[INFO]\` — observation only, no action implied
912
+ - \`[N/A]\` — doesn't apply to this project (omit from output if obvious)
913
+
914
+ Keep each line to one sentence. No prose paragraphs.
915
+
916
+ At the end:
917
+
918
+ \`\`\`
919
+ ## Summary
920
+
921
+ <N> gaps in hygiene, <N> in tooling, <N> in verify pipeline, <N> in style-pack alignment.
922
+
923
+ Which (if any) would you like me to fix? Options:
924
+ - A) All [GAP] items that are safe + additive (no overwrites)
925
+ - B) Pick category: hygiene / tooling / verify / style-pack alignment
926
+ - C) Specific items — tell me which
927
+ - D) None — just the report
928
+ \`\`\`
929
+
930
+ ## Rules
931
+
932
+ - **Report only.** No edits, no installs, no commits without explicit user confirmation after the report.
933
+ - **No code refactors recommended.** This audit is about scaffolding/tooling, not code review. Use \`/scan\` or \`/verify\` for code-level findings.
934
+ - **No dependency installations in the report.** Listing them as observations is fine; recommending installation is not — that's the user's call.
935
+ - **Skip empty categories.** If a category has no findings, omit it.
936
+ - **Adapt to scale.** A 50-line script doesn't need CI, a license, or an ARCHITECTURE.md. Use judgment.
937
+ - **Brand-new empty project**: report "Empty project — nothing to audit. To bootstrap, tell me the stack you want and I'll scaffold from scratch." and stop.`,
938
+ },
846
939
  ];
847
940
  /** Look up a prompt command by name or alias */
848
941
  export function getPromptCommand(name) {
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-commands.js","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompt-commands.js","sourceRoot":"","sources":["../../src/core/prompt-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** Returns true if this cwd has never been audited by /setup before. */
2
+ export declare function isFirstTimeSetup(cwd: string): boolean;
3
+ /** Mark this cwd as audited. Called immediately after the auto-run fires
4
+ * (whether or not the agent actually completes the audit) so we never
5
+ * double-trigger across sessions. */
6
+ export declare function markSetupAudited(cwd: string): void;
7
+ /** Returns the language ids that have already been announced via the
8
+ * "STYLE PACK ACTIVE" badge for this cwd. */
9
+ export declare function getAnnouncedLanguages(cwd: string): string[];
10
+ /** Add language ids to the announced set for this cwd. No-op if the input
11
+ * is empty or adds nothing new. */
12
+ export declare function markLanguagesAnnounced(cwd: string, langs: readonly string[]): void;
13
+ //# sourceMappingURL=setup-history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-history.d.ts","sourceRoot":"","sources":["../../src/core/setup-history.ts"],"names":[],"mappings":"AAiDA,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;sCAEsC;AACtC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAKlD;AAED;8CAC8C;AAC9C,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAG3D;AAED;oCACoC;AACpC,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CASlF"}
@@ -0,0 +1,71 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ const HISTORY_PATH = path.join(os.homedir(), ".ezcoder", "setup-history.json");
5
+ /**
6
+ * Persisted record of which project directories have been auto-audited by
7
+ * `/setup`. Used to gate the first-time auto-run: we want the audit to fire
8
+ * exactly once per project, not once per session.
9
+ *
10
+ * Stored at `~/.ezcoder/setup-history.json`. Keys are absolute cwd paths. The file
11
+ * is small (one line per project the user has ever opened with ezcoder) and
12
+ * read/written on session start only \u2014 not in any hot path.
13
+ */
14
+ function readHistory() {
15
+ try {
16
+ const raw = fs.readFileSync(HISTORY_PATH, "utf-8");
17
+ const parsed = JSON.parse(raw);
18
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
19
+ return parsed;
20
+ }
21
+ }
22
+ catch {
23
+ /* missing or unparseable \u2014 treat as empty */
24
+ }
25
+ return {};
26
+ }
27
+ function writeHistory(history) {
28
+ try {
29
+ fs.mkdirSync(path.dirname(HISTORY_PATH), { recursive: true });
30
+ fs.writeFileSync(HISTORY_PATH, JSON.stringify(history, null, 2), "utf-8");
31
+ }
32
+ catch {
33
+ /* best-effort \u2014 a failed write just means the auto-run will fire again
34
+ next session, which is annoying but not broken. */
35
+ }
36
+ }
37
+ /** Returns true if this cwd has never been audited by /setup before. */
38
+ export function isFirstTimeSetup(cwd) {
39
+ const history = readHistory();
40
+ return history[cwd]?.lastAuditedAt === undefined;
41
+ }
42
+ /** Mark this cwd as audited. Called immediately after the auto-run fires
43
+ * (whether or not the agent actually completes the audit) so we never
44
+ * double-trigger across sessions. */
45
+ export function markSetupAudited(cwd) {
46
+ const history = readHistory();
47
+ const existing = history[cwd] ?? {};
48
+ history[cwd] = { ...existing, lastAuditedAt: new Date().toISOString() };
49
+ writeHistory(history);
50
+ }
51
+ /** Returns the language ids that have already been announced via the
52
+ * "STYLE PACK ACTIVE" badge for this cwd. */
53
+ export function getAnnouncedLanguages(cwd) {
54
+ const history = readHistory();
55
+ return history[cwd]?.announcedLanguages ?? [];
56
+ }
57
+ /** Add language ids to the announced set for this cwd. No-op if the input
58
+ * is empty or adds nothing new. */
59
+ export function markLanguagesAnnounced(cwd, langs) {
60
+ if (langs.length === 0)
61
+ return;
62
+ const history = readHistory();
63
+ const existing = history[cwd] ?? {};
64
+ const prev = existing.announcedLanguages ?? [];
65
+ const merged = Array.from(new Set([...prev, ...langs]));
66
+ if (merged.length === prev.length)
67
+ return;
68
+ history[cwd] = { ...existing, announcedLanguages: merged };
69
+ writeHistory(history);
70
+ }
71
+ //# sourceMappingURL=setup-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-history.js","sourceRoot":"","sources":["../../src/core/setup-history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,oBAAoB,CAAC,CAAC;AAa/E;;;;;;;;GAQG;AACH,SAAS,WAAW;IAClB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,OAAO,MAAsB,CAAC;QAChC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kDAAkD;IACpD,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,YAAY,CAAC,OAAqB;IACzC,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP;6DACqD;IACvD,CAAC;AACH,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,aAAa,KAAK,SAAS,CAAC;AACnD,CAAC;AAED;;sCAEsC;AACtC,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,aAAa,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IACxE,YAAY,CAAC,OAAO,CAAC,CAAC;AACxB,CAAC;AAED;8CAC8C;AAC9C,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,kBAAkB,IAAI,EAAE,CAAC;AAChD,CAAC;AAED;oCACoC;AACpC,MAAM,UAAU,sBAAsB,CAAC,GAAW,EAAE,KAAwB;IAC1E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC/B,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,kBAAkB,IAAI,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACxD,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO;IAC1C,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC3D,YAAY,CAAC,OAAO,CAAC,CAAC;AACxB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=setup-history.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-history.test.d.ts","sourceRoot":"","sources":["../../src/core/setup-history.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,74 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ let tmpHome;
6
+ beforeEach(() => {
7
+ tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), "setup-history-"));
8
+ // Re-point os.homedir() at our tmp dir. Done via a spy so the change is
9
+ // reverted after each test via vi.restoreAllMocks().
10
+ vi.spyOn(os, "homedir").mockReturnValue(tmpHome);
11
+ // setup-history.ts captures HISTORY_PATH at module load via os.homedir().
12
+ // We must re-import after the mock is in place to pick up the tmp path.
13
+ vi.resetModules();
14
+ });
15
+ afterEach(() => {
16
+ fs.rmSync(tmpHome, { recursive: true, force: true });
17
+ vi.restoreAllMocks();
18
+ });
19
+ async function loadModule() {
20
+ return await import("./setup-history.js");
21
+ }
22
+ describe("setup-history", () => {
23
+ it("isFirstTimeSetup returns true when history file is absent", async () => {
24
+ const { isFirstTimeSetup } = await loadModule();
25
+ expect(isFirstTimeSetup("/tmp/never-seen")).toBe(true);
26
+ });
27
+ it("markSetupAudited persists the cwd entry", async () => {
28
+ const { isFirstTimeSetup, markSetupAudited } = await loadModule();
29
+ const cwd = "/tmp/first-project";
30
+ expect(isFirstTimeSetup(cwd)).toBe(true);
31
+ markSetupAudited(cwd);
32
+ expect(isFirstTimeSetup(cwd)).toBe(false);
33
+ });
34
+ it("treats distinct cwds independently", async () => {
35
+ const { isFirstTimeSetup, markSetupAudited } = await loadModule();
36
+ markSetupAudited("/tmp/project-a");
37
+ expect(isFirstTimeSetup("/tmp/project-a")).toBe(false);
38
+ expect(isFirstTimeSetup("/tmp/project-b")).toBe(true);
39
+ });
40
+ it("tolerates corrupt history files (treats as empty)", async () => {
41
+ const ggDir = path.join(tmpHome, ".ezcoder");
42
+ fs.mkdirSync(ggDir, { recursive: true });
43
+ fs.writeFileSync(path.join(ggDir, "setup-history.json"), "{ not valid json");
44
+ const { isFirstTimeSetup } = await loadModule();
45
+ expect(isFirstTimeSetup("/tmp/anywhere")).toBe(true);
46
+ });
47
+ it("getAnnouncedLanguages returns [] when never announced", async () => {
48
+ const { getAnnouncedLanguages } = await loadModule();
49
+ expect(getAnnouncedLanguages("/tmp/fresh")).toEqual([]);
50
+ });
51
+ it("markLanguagesAnnounced persists and dedupes across calls", async () => {
52
+ const { getAnnouncedLanguages, markLanguagesAnnounced } = await loadModule();
53
+ const cwd = "/tmp/proj";
54
+ markLanguagesAnnounced(cwd, ["typescript"]);
55
+ expect(getAnnouncedLanguages(cwd)).toEqual(["typescript"]);
56
+ markLanguagesAnnounced(cwd, ["typescript", "rust"]);
57
+ expect(getAnnouncedLanguages(cwd).sort()).toEqual(["rust", "typescript"]);
58
+ });
59
+ it("markLanguagesAnnounced and markSetupAudited coexist without clobbering", async () => {
60
+ const { isFirstTimeSetup, markSetupAudited, getAnnouncedLanguages, markLanguagesAnnounced } = await loadModule();
61
+ const cwd = "/tmp/coexist";
62
+ markLanguagesAnnounced(cwd, ["python"]);
63
+ expect(isFirstTimeSetup(cwd)).toBe(true);
64
+ markSetupAudited(cwd);
65
+ expect(isFirstTimeSetup(cwd)).toBe(false);
66
+ expect(getAnnouncedLanguages(cwd)).toEqual(["python"]);
67
+ });
68
+ it("markLanguagesAnnounced is a no-op for empty input", async () => {
69
+ const { getAnnouncedLanguages, markLanguagesAnnounced } = await loadModule();
70
+ markLanguagesAnnounced("/tmp/noop", []);
71
+ expect(getAnnouncedLanguages("/tmp/noop")).toEqual([]);
72
+ });
73
+ });
74
+ //# sourceMappingURL=setup-history.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-history.test.js","sourceRoot":"","sources":["../../src/core/setup-history.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { LanguageId } from "../language-detector.js";
2
+ /**
3
+ * Load the style-pack content for a given language. Checks for a per-project
4
+ * override at `<cwd>/.ezcoder/styles/<id>.md` first, falling back to the bundled
5
+ * pack. Returns `null` if neither exists (defensive — should not happen for
6
+ * any LanguageId in PACKS).
7
+ */
8
+ export declare function loadPack(id: LanguageId, cwd: string): string | null;
9
+ /**
10
+ * Render the full "Language Style Packs" section that gets spliced into the
11
+ * system prompt. Returns an empty string when the active set is empty so the
12
+ * caller can skip the section entirely.
13
+ *
14
+ * The output is intentionally compact: a single header followed by each pack
15
+ * separated by a blank line. Packs already include their own \`### <Language>\`
16
+ * sub-headers.
17
+ */
18
+ export declare function renderStylePacksSection(active: Set<LanguageId>, cwd: string): string;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/style-packs/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAI1D;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAWnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAgBpF"}
@@ -0,0 +1,70 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { languagesToSortedArray } from "../language-detector.js";
4
+ import { PACKS } from "./packs.js";
5
+ /**
6
+ * Load the style-pack content for a given language. Checks for a per-project
7
+ * override at `<cwd>/.ezcoder/styles/<id>.md` first, falling back to the bundled
8
+ * pack. Returns `null` if neither exists (defensive — should not happen for
9
+ * any LanguageId in PACKS).
10
+ */
11
+ export function loadPack(id, cwd) {
12
+ const overridePath = path.join(cwd, ".ezcoder", "styles", `${id}.md`);
13
+ try {
14
+ const stat = fs.statSync(overridePath);
15
+ if (stat.isFile()) {
16
+ return fs.readFileSync(overridePath, "utf-8").trim();
17
+ }
18
+ }
19
+ catch {
20
+ /* no override — fall through to bundled */
21
+ }
22
+ return PACKS[id] ?? null;
23
+ }
24
+ /**
25
+ * Render the full "Language Style Packs" section that gets spliced into the
26
+ * system prompt. Returns an empty string when the active set is empty so the
27
+ * caller can skip the section entirely.
28
+ *
29
+ * The output is intentionally compact: a single header followed by each pack
30
+ * separated by a blank line. Packs already include their own \`### <Language>\`
31
+ * sub-headers.
32
+ */
33
+ export function renderStylePacksSection(active, cwd) {
34
+ if (active.size === 0)
35
+ return "";
36
+ const ids = languagesToSortedArray(active);
37
+ const parts = [];
38
+ for (const id of ids) {
39
+ const pack = loadPack(id, cwd);
40
+ if (pack)
41
+ parts.push(pack);
42
+ }
43
+ if (parts.length === 0)
44
+ return "";
45
+ return (`## Language Style Packs\n\n` +
46
+ `Conventions for new code in each active language. Library names below are ` +
47
+ `illustrative — use whatever the project already imports.\n\n` +
48
+ `${AGENT_WRITTEN_CODE_PREAMBLE}\n\n` +
49
+ parts.join("\n\n"));
50
+ }
51
+ /**
52
+ * Cross-cutting rules that apply to every language pack. These are agent-native
53
+ * concerns (determinism, observability, no hidden state, output stability) that
54
+ * matter more for code written *by* and *read by* agents than for human-only
55
+ * codebases. Kept terse — every line is a load-bearing constraint, not advice.
56
+ *
57
+ * Lives in the system prompt above the per-language packs so the model reads
58
+ * universal rules first, then specializes per language.
59
+ */
60
+ const AGENT_WRITTEN_CODE_PREAMBLE = `### Agent-Written Code (cross-cutting)
61
+
62
+ Universal rules — apply to every language below.
63
+
64
+ - **Observability at boundaries.** Structured logging (key/value pairs, not string interpolation) at every external I/O — HTTP calls, DB queries, file reads, subprocess runs. Log inputs, outcome, and elapsed time. Use the language's stdlib or canonical structured logger (\`log/slog\`, \`tracing\`, \`structlog\`, Pino, \`Microsoft.Extensions.Logging\`, etc.). Never leave \`console.log\`/\`print\`/\`fmt.Println\` debugging in committed code.
65
+ - **Determinism by default.** Sort before iterating maps/sets where output order is observable. Stable IDs (UUIDv7, ULID, or content hash) — never \`random + timestamp\`. Never read wall-clock time inside pure logic; inject a clock at the boundary. Use canonical-form serialization (sorted keys) for anything that gets compared, hashed, persisted, or diffed.
66
+ - **No hidden state.** No module-level mutables, no global singletons as the primary state container, no implicit DI through container magic. Pass dependencies explicitly through function signatures or constructors. State that escapes the signature is invisible at the call site, which means invisible to the agent reading it later.
67
+ - **Local verifiability.** A function should be small enough that its correctness is confirmable by reading it plus its direct callers — not by tracing through four layers of indirection. Prefer composing small pure functions over deep class hierarchies. The agent will re-read this code; optimize for that.
68
+ - **Tests pin behavior, not implementation.** Arrange-Act-Assert with each phase visible. No shared mutable fixtures across tests. Each test runnable independently in any order. Table-driven when there's a clear input→output mapping. A test that breaks on a refactor without a behavior change is a bad test.
69
+ - **Fail loudly at boundaries, handle locally inside.** Validate untrusted input the moment it crosses into your code (per the per-language Data rules). Once validated, interior code trusts the types. Errors as values for the local-handling half — see each pack's Errors rule.`;
70
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/style-packs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAc,EAAE,GAAW;IAClD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAClB,OAAO,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACvD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2CAA2C;IAC7C,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;AAC3B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAuB,EAAE,GAAW;IAC1E,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC/B,IAAI,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,OAAO,CACL,6BAA6B;QAC7B,4EAA4E;QAC5E,8DAA8D;QAC9D,GAAG,2BAA2B,MAAM;QACpC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CACnB,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,2BAA2B,GAAG;;;;;;;;;qRASiP,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { LanguageId } from "../language-detector.js";
2
+ /**
3
+ * Per-language style packs injected into the system prompt when the detector
4
+ * sees the language is active in the project.
5
+ *
6
+ * Design principles (apply to every pack):
7
+ * 1. Apply the strictest reasonable subset of *idiomatic* style — nothing
8
+ * exotic the model has to think about. The agent already knows these
9
+ * patterns; the pack just narrows the choice space.
10
+ * 2. Optimize for low ambiguity, not for human readability. Bullet form.
11
+ * 3. Errors as values, schema at boundaries, mechanical formatting,
12
+ * one canonical way to do common tasks.
13
+ * 4. ~30-50 lines per pack. Anything longer is bloat in the system prompt.
14
+ * 5. Avoid triple backticks (template literal conflict). Use single
15
+ * backticks for inline tokens, escape with \\\` when needed.
16
+ */
17
+ export declare const PACKS: Readonly<Record<LanguageId, string>>;
18
+ //# sourceMappingURL=packs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packs.d.ts","sourceRoot":"","sources":["../../../src/core/style-packs/packs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CA4OtD,CAAC"}