sequant 1.0.0 → 1.1.1

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 (77) hide show
  1. package/README.md +12 -8
  2. package/dist/bin/cli.js +12 -0
  3. package/dist/bin/cli.js.map +1 -1
  4. package/dist/src/commands/doctor.d.ts.map +1 -1
  5. package/dist/src/commands/doctor.js +46 -0
  6. package/dist/src/commands/doctor.js.map +1 -1
  7. package/dist/src/commands/doctor.test.d.ts +2 -0
  8. package/dist/src/commands/doctor.test.d.ts.map +1 -0
  9. package/dist/src/commands/doctor.test.js +140 -0
  10. package/dist/src/commands/doctor.test.js.map +1 -0
  11. package/dist/src/commands/init.d.ts.map +1 -1
  12. package/dist/src/commands/init.js +45 -2
  13. package/dist/src/commands/init.js.map +1 -1
  14. package/dist/src/commands/init.test.d.ts +2 -0
  15. package/dist/src/commands/init.test.d.ts.map +1 -0
  16. package/dist/src/commands/init.test.js +152 -0
  17. package/dist/src/commands/init.test.js.map +1 -0
  18. package/dist/src/commands/logs.d.ts +18 -0
  19. package/dist/src/commands/logs.d.ts.map +1 -0
  20. package/dist/src/commands/logs.js +188 -0
  21. package/dist/src/commands/logs.js.map +1 -0
  22. package/dist/src/commands/run.d.ts +2 -0
  23. package/dist/src/commands/run.d.ts.map +1 -1
  24. package/dist/src/commands/run.js +114 -29
  25. package/dist/src/commands/run.js.map +1 -1
  26. package/dist/src/lib/stacks.d.ts.map +1 -1
  27. package/dist/src/lib/stacks.js +39 -0
  28. package/dist/src/lib/stacks.js.map +1 -1
  29. package/dist/src/lib/stacks.test.d.ts +2 -0
  30. package/dist/src/lib/stacks.test.d.ts.map +1 -0
  31. package/dist/src/lib/stacks.test.js +145 -0
  32. package/dist/src/lib/stacks.test.js.map +1 -0
  33. package/dist/src/lib/system.d.ts +16 -0
  34. package/dist/src/lib/system.d.ts.map +1 -0
  35. package/dist/src/lib/system.js +52 -0
  36. package/dist/src/lib/system.js.map +1 -0
  37. package/dist/src/lib/system.test.d.ts +2 -0
  38. package/dist/src/lib/system.test.d.ts.map +1 -0
  39. package/dist/src/lib/system.test.js +80 -0
  40. package/dist/src/lib/system.test.js.map +1 -0
  41. package/dist/src/lib/workflow/log-writer.d.ts +83 -0
  42. package/dist/src/lib/workflow/log-writer.d.ts.map +1 -0
  43. package/dist/src/lib/workflow/log-writer.js +193 -0
  44. package/dist/src/lib/workflow/log-writer.js.map +1 -0
  45. package/dist/src/lib/workflow/run-log-schema.d.ts +261 -0
  46. package/dist/src/lib/workflow/run-log-schema.d.ts.map +1 -0
  47. package/dist/src/lib/workflow/run-log-schema.js +234 -0
  48. package/dist/src/lib/workflow/run-log-schema.js.map +1 -0
  49. package/package.json +6 -4
  50. package/stacks/astro.yaml +35 -0
  51. package/templates/hooks/post-tool.sh +0 -11
  52. package/templates/hooks/pre-tool.sh +2 -2
  53. package/templates/memory/constitution.md +8 -0
  54. package/templates/scripts/cleanup-worktree.sh +1 -1
  55. package/templates/scripts/new-feature.sh +7 -5
  56. package/templates/skills/assess/SKILL.md +31 -16
  57. package/templates/skills/clean/SKILL.md +17 -2
  58. package/templates/skills/docs/SKILL.md +48 -34
  59. package/templates/skills/exec/SKILL.md +31 -25
  60. package/templates/skills/fullsolve/SKILL.md +34 -16
  61. package/templates/skills/loop/SKILL.md +22 -5
  62. package/templates/skills/qa/SKILL.md +89 -4
  63. package/templates/skills/qa/references/code-quality-exemplars.md +23 -28
  64. package/templates/skills/qa/references/code-review-checklist.md +6 -17
  65. package/templates/skills/qa/scripts/quality-checks.sh +4 -17
  66. package/templates/skills/reflect/SKILL.md +18 -2
  67. package/templates/skills/reflect/references/documentation-tiers.md +3 -3
  68. package/templates/skills/security-review/SKILL.md +15 -0
  69. package/templates/skills/security-review/references/security-checklists.md +10 -8
  70. package/templates/skills/solve/SKILL.md +147 -149
  71. package/templates/skills/spec/SKILL.md +61 -3
  72. package/templates/skills/spec/references/parallel-groups.md +1 -1
  73. package/templates/skills/spec/references/verification-criteria.md +1 -1
  74. package/templates/skills/test/SKILL.md +20 -5
  75. package/templates/skills/testgen/SKILL.md +15 -1
  76. package/templates/skills/verify/SKILL.md +20 -5
  77. package/templates/skills/reflect/scripts/workflow-queries.ts +0 -165
@@ -0,0 +1,145 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { detectStack, getStackConfig, STACKS } from "./stacks.js";
3
+ // Mock the fs module
4
+ vi.mock("./fs.js", () => ({
5
+ fileExists: vi.fn(),
6
+ readFile: vi.fn(),
7
+ }));
8
+ import { fileExists, readFile } from "./fs.js";
9
+ const mockFileExists = vi.mocked(fileExists);
10
+ const mockReadFile = vi.mocked(readFile);
11
+ describe("STACKS", () => {
12
+ describe("astro config", () => {
13
+ it("has correct detection files", () => {
14
+ expect(STACKS.astro.detection.files).toEqual([
15
+ "astro.config.mjs",
16
+ "astro.config.js",
17
+ "astro.config.ts",
18
+ ]);
19
+ });
20
+ it("has astro in packageDeps", () => {
21
+ expect(STACKS.astro.detection.packageDeps).toContain("astro");
22
+ });
23
+ it("has correct commands", () => {
24
+ expect(STACKS.astro.commands.build).toBe("npm run build");
25
+ expect(STACKS.astro.commands.dev).toBe("npm run dev");
26
+ expect(STACKS.astro.commands.test).toBe("npm test");
27
+ expect(STACKS.astro.commands.lint).toBe("npm run lint");
28
+ });
29
+ });
30
+ });
31
+ describe("detectStack", () => {
32
+ beforeEach(() => {
33
+ vi.resetAllMocks();
34
+ mockFileExists.mockResolvedValue(false);
35
+ mockReadFile.mockResolvedValue("{}");
36
+ });
37
+ describe("Astro detection", () => {
38
+ it("detects astro.config.mjs", async () => {
39
+ mockFileExists.mockImplementation(async (path) => {
40
+ return path === "astro.config.mjs";
41
+ });
42
+ const result = await detectStack();
43
+ expect(result).toBe("astro");
44
+ });
45
+ it("detects astro.config.js", async () => {
46
+ mockFileExists.mockImplementation(async (path) => {
47
+ return path === "astro.config.js";
48
+ });
49
+ const result = await detectStack();
50
+ expect(result).toBe("astro");
51
+ });
52
+ it("detects astro.config.ts", async () => {
53
+ mockFileExists.mockImplementation(async (path) => {
54
+ return path === "astro.config.ts";
55
+ });
56
+ const result = await detectStack();
57
+ expect(result).toBe("astro");
58
+ });
59
+ it("detects astro in dependencies via package.json", async () => {
60
+ mockFileExists.mockImplementation(async (path) => {
61
+ return path === "package.json";
62
+ });
63
+ mockReadFile.mockResolvedValue(JSON.stringify({
64
+ dependencies: { astro: "^4.0.0" },
65
+ }));
66
+ const result = await detectStack();
67
+ expect(result).toBe("astro");
68
+ });
69
+ it("detects astro in devDependencies via package.json", async () => {
70
+ mockFileExists.mockImplementation(async (path) => {
71
+ return path === "package.json";
72
+ });
73
+ mockReadFile.mockResolvedValue(JSON.stringify({
74
+ devDependencies: { astro: "^4.0.0" },
75
+ }));
76
+ const result = await detectStack();
77
+ expect(result).toBe("astro");
78
+ });
79
+ });
80
+ describe("priority", () => {
81
+ it("Next.js takes priority over Astro when both present", async () => {
82
+ mockFileExists.mockImplementation(async (path) => {
83
+ return path === "next.config.js" || path === "astro.config.mjs";
84
+ });
85
+ const result = await detectStack();
86
+ expect(result).toBe("nextjs");
87
+ });
88
+ it("Next.js dep takes priority over Astro dep", async () => {
89
+ mockFileExists.mockImplementation(async (path) => {
90
+ return path === "package.json";
91
+ });
92
+ mockReadFile.mockResolvedValue(JSON.stringify({
93
+ dependencies: { next: "^14.0.0", astro: "^4.0.0" },
94
+ }));
95
+ const result = await detectStack();
96
+ expect(result).toBe("nextjs");
97
+ });
98
+ it("Astro config file takes priority over Rust", async () => {
99
+ mockFileExists.mockImplementation(async (path) => {
100
+ return path === "astro.config.mjs" || path === "Cargo.toml";
101
+ });
102
+ const result = await detectStack();
103
+ expect(result).toBe("astro");
104
+ });
105
+ });
106
+ describe("edge cases", () => {
107
+ it("returns null when no stack detected", async () => {
108
+ mockFileExists.mockResolvedValue(false);
109
+ const result = await detectStack();
110
+ expect(result).toBeNull();
111
+ });
112
+ it("handles malformed package.json gracefully", async () => {
113
+ mockFileExists.mockImplementation(async (path) => {
114
+ return path === "package.json";
115
+ });
116
+ mockReadFile.mockResolvedValue("{ invalid json }");
117
+ const result = await detectStack();
118
+ expect(result).toBeNull();
119
+ });
120
+ it("handles empty package.json", async () => {
121
+ mockFileExists.mockImplementation(async (path) => {
122
+ return path === "package.json";
123
+ });
124
+ mockReadFile.mockResolvedValue("{}");
125
+ const result = await detectStack();
126
+ expect(result).toBeNull();
127
+ });
128
+ });
129
+ });
130
+ describe("getStackConfig", () => {
131
+ it("returns astro config for astro stack", () => {
132
+ const config = getStackConfig("astro");
133
+ expect(config.name).toBe("astro");
134
+ expect(config.displayName).toBe("Astro");
135
+ });
136
+ it("returns generic config for unknown stack", () => {
137
+ const config = getStackConfig("unknown-stack");
138
+ expect(config.name).toBe("generic");
139
+ });
140
+ it("returns generic config for empty string", () => {
141
+ const config = getStackConfig("");
142
+ expect(config.name).toBe("generic");
143
+ });
144
+ });
145
+ //# sourceMappingURL=stacks.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stacks.test.js","sourceRoot":"","sources":["../../../src/lib/stacks.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * System utility functions for checking prerequisites
3
+ */
4
+ /**
5
+ * Check if a command exists on the system
6
+ */
7
+ export declare function commandExists(cmd: string): boolean;
8
+ /**
9
+ * Check if gh CLI is authenticated
10
+ */
11
+ export declare function isGhAuthenticated(): boolean;
12
+ /**
13
+ * Get platform-specific install hint for a package
14
+ */
15
+ export declare function getInstallHint(pkg: string): string;
16
+ //# sourceMappingURL=system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../src/lib/system.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOlD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAsBlD"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * System utility functions for checking prerequisites
3
+ */
4
+ import { execSync } from "child_process";
5
+ /**
6
+ * Check if a command exists on the system
7
+ */
8
+ export function commandExists(cmd) {
9
+ try {
10
+ execSync(`command -v ${cmd}`, { stdio: "ignore" });
11
+ return true;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ /**
18
+ * Check if gh CLI is authenticated
19
+ */
20
+ export function isGhAuthenticated() {
21
+ try {
22
+ execSync("gh auth status", { stdio: "ignore" });
23
+ return true;
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ /**
30
+ * Get platform-specific install hint for a package
31
+ */
32
+ export function getInstallHint(pkg) {
33
+ const platform = process.platform;
34
+ const hints = {
35
+ jq: {
36
+ darwin: "brew install jq",
37
+ linux: "apt install jq # or: yum install jq",
38
+ win32: "choco install jq # or: scoop install jq",
39
+ },
40
+ gh: {
41
+ darwin: "brew install gh",
42
+ linux: "apt install gh # see: https://cli.github.com",
43
+ win32: "choco install gh # or: winget install GitHub.cli",
44
+ },
45
+ };
46
+ const pkgHints = hints[pkg];
47
+ if (!pkgHints) {
48
+ return `Install ${pkg}`;
49
+ }
50
+ return pkgHints[platform] || pkgHints["linux"] || `Install ${pkg}`;
51
+ }
52
+ //# sourceMappingURL=system.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../../../src/lib/system.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,QAAQ,CAAC,cAAc,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,QAAQ,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAElC,MAAM,KAAK,GAA2C;QACpD,EAAE,EAAE;YACF,MAAM,EAAE,iBAAiB;YACzB,KAAK,EAAE,sCAAsC;YAC7C,KAAK,EAAE,0CAA0C;SAClD;QACD,EAAE,EAAE;YACF,MAAM,EAAE,iBAAiB;YACzB,KAAK,EAAE,+CAA+C;YACtD,KAAK,EAAE,mDAAmD;SAC3D;KACF,CAAC;IAEF,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,WAAW,GAAG,EAAE,CAAC;IAC1B,CAAC;IAED,OAAO,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,IAAI,WAAW,GAAG,EAAE,CAAC;AACrE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=system.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.test.d.ts","sourceRoot":"","sources":["../../../src/lib/system.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,80 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { execSync } from "child_process";
3
+ // Mock child_process
4
+ vi.mock("child_process", () => ({
5
+ execSync: vi.fn(),
6
+ }));
7
+ import { commandExists, isGhAuthenticated, getInstallHint } from "./system.js";
8
+ const mockExecSync = vi.mocked(execSync);
9
+ describe("system utilities", () => {
10
+ beforeEach(() => {
11
+ vi.resetAllMocks();
12
+ });
13
+ describe("commandExists", () => {
14
+ it("returns true when command exists", () => {
15
+ mockExecSync.mockReturnValue(Buffer.from("/usr/local/bin/gh"));
16
+ expect(commandExists("gh")).toBe(true);
17
+ expect(mockExecSync).toHaveBeenCalledWith("command -v gh", {
18
+ stdio: "ignore",
19
+ });
20
+ });
21
+ it("returns false when command does not exist", () => {
22
+ mockExecSync.mockImplementation(() => {
23
+ throw new Error("command not found");
24
+ });
25
+ expect(commandExists("nonexistent")).toBe(false);
26
+ });
27
+ it("checks different commands correctly", () => {
28
+ mockExecSync.mockReturnValue(Buffer.from("/usr/local/bin/jq"));
29
+ expect(commandExists("jq")).toBe(true);
30
+ expect(mockExecSync).toHaveBeenCalledWith("command -v jq", {
31
+ stdio: "ignore",
32
+ });
33
+ });
34
+ });
35
+ describe("isGhAuthenticated", () => {
36
+ it("returns true when gh is authenticated", () => {
37
+ mockExecSync.mockReturnValue(Buffer.from(""));
38
+ expect(isGhAuthenticated()).toBe(true);
39
+ expect(mockExecSync).toHaveBeenCalledWith("gh auth status", {
40
+ stdio: "ignore",
41
+ });
42
+ });
43
+ it("returns false when gh is not authenticated", () => {
44
+ mockExecSync.mockImplementation(() => {
45
+ throw new Error("not authenticated");
46
+ });
47
+ expect(isGhAuthenticated()).toBe(false);
48
+ });
49
+ });
50
+ describe("getInstallHint", () => {
51
+ const originalPlatform = process.platform;
52
+ beforeEach(() => {
53
+ // Reset platform after each test
54
+ Object.defineProperty(process, "platform", {
55
+ value: originalPlatform,
56
+ writable: true,
57
+ });
58
+ });
59
+ it("returns macOS hint for gh on darwin", () => {
60
+ Object.defineProperty(process, "platform", { value: "darwin" });
61
+ expect(getInstallHint("gh")).toBe("brew install gh");
62
+ });
63
+ it("returns macOS hint for jq on darwin", () => {
64
+ Object.defineProperty(process, "platform", { value: "darwin" });
65
+ expect(getInstallHint("jq")).toBe("brew install jq");
66
+ });
67
+ it("returns Linux hint for gh on linux", () => {
68
+ Object.defineProperty(process, "platform", { value: "linux" });
69
+ expect(getInstallHint("gh")).toContain("apt install gh");
70
+ });
71
+ it("returns Windows hint for gh on win32", () => {
72
+ Object.defineProperty(process, "platform", { value: "win32" });
73
+ expect(getInstallHint("gh")).toContain("choco install gh");
74
+ });
75
+ it("returns generic hint for unknown package", () => {
76
+ expect(getInstallHint("unknown-package")).toBe("Install unknown-package");
77
+ });
78
+ });
79
+ });
80
+ //# sourceMappingURL=system.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.test.js","sourceRoot":"","sources":["../../../src/lib/system.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,qBAAqB;AACrB,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9B,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;CAClB,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE/E,MAAM,YAAY,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEzC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,YAAY,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;YAE/D,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC,eAAe,EAAE;gBACzD,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,YAAY,CAAC,kBAAkB,CAAC,GAAG,EAAE;gBACnC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,YAAY,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;YAE/D,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC,eAAe,EAAE;gBACzD,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,YAAY,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAE9C,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,MAAM,CAAC,YAAY,CAAC,CAAC,oBAAoB,CAAC,gBAAgB,EAAE;gBAC1D,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,YAAY,CAAC,kBAAkB,CAAC,GAAG,EAAE;gBACnC,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,MAAM,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;QAE1C,UAAU,CAAC,GAAG,EAAE;YACd,iCAAiC;YACjC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE;gBACzC,KAAK,EAAE,gBAAgB;gBACvB,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEhE,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEhE,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAE/D,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAE/D,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Log writer for structured workflow run logs
3
+ *
4
+ * Writes JSON logs to disk for analysis and debugging.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { LogWriter } from './log-writer';
9
+ *
10
+ * const writer = new LogWriter({ projectPath: '.sequant/logs' });
11
+ * await writer.initialize(config);
12
+ * await writer.logPhase(phaseLog);
13
+ * await writer.finalize();
14
+ * ```
15
+ */
16
+ import { type RunLog, type RunConfig, type PhaseLog, type Phase } from "./run-log-schema.js";
17
+ export interface LogWriterOptions {
18
+ /** Path to log directory (default: .sequant/logs in current directory) */
19
+ logPath?: string;
20
+ /** Whether to also write to user-level logs */
21
+ writeToUserLogs?: boolean;
22
+ /** Enable verbose logging */
23
+ verbose?: boolean;
24
+ }
25
+ /**
26
+ * Manages writing structured run logs to disk
27
+ */
28
+ export declare class LogWriter {
29
+ private runLog;
30
+ private currentIssue;
31
+ private logPath;
32
+ private writeToUserLogs;
33
+ private verbose;
34
+ constructor(options?: LogWriterOptions);
35
+ /**
36
+ * Initialize a new run log
37
+ *
38
+ * @param config - Run configuration
39
+ */
40
+ initialize(config: RunConfig): Promise<void>;
41
+ /**
42
+ * Start logging a new issue
43
+ *
44
+ * @param issueNumber - GitHub issue number
45
+ * @param title - Issue title
46
+ * @param labels - Issue labels
47
+ */
48
+ startIssue(issueNumber: number, title: string, labels: string[]): void;
49
+ /**
50
+ * Log a completed phase
51
+ *
52
+ * @param phaseLog - Complete phase log entry
53
+ */
54
+ logPhase(phaseLog: PhaseLog): void;
55
+ /**
56
+ * Complete the current issue and add it to the run log
57
+ */
58
+ completeIssue(): void;
59
+ /**
60
+ * Finalize the run log and write to disk
61
+ *
62
+ * @returns Path to the written log file
63
+ */
64
+ finalize(): Promise<string>;
65
+ /**
66
+ * Get the current run log (for inspection)
67
+ */
68
+ getRunLog(): Omit<RunLog, "endTime"> | null;
69
+ /**
70
+ * Get the run ID
71
+ */
72
+ getRunId(): string | null;
73
+ private resolvePath;
74
+ private ensureLogDirectory;
75
+ private writeLogFile;
76
+ }
77
+ /**
78
+ * Create a simple phase log from timing data
79
+ *
80
+ * Utility function for creating phase logs when you have start/end times.
81
+ */
82
+ export declare function createPhaseLogFromTiming(phase: Phase, issueNumber: number, startTime: Date, endTime: Date, status: PhaseLog["status"], options?: Partial<Pick<PhaseLog, "error" | "iterations" | "filesModified" | "testsRun" | "testsPassed">>): PhaseLog;
83
+ //# sourceMappingURL=log-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-writer.d.ts","sourceRoot":"","sources":["../../../../src/lib/workflow/log-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EACL,KAAK,MAAM,EACX,KAAK,SAAS,EAEd,KAAK,QAAQ,EACb,KAAK,KAAK,EAMX,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,gBAAgB;IAC/B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAwC;IACtD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,OAAO,CAAU;gBAEb,OAAO,GAAE,gBAAqB;IAM1C;;;;OAIG;IACG,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBlD;;;;;;OAMG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAmBtE;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAwBlC;;OAEG;IACH,aAAa,IAAI,IAAI;IA+BrB;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAiCjC;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAI;IAI3C;;OAEG;IACH,QAAQ,IAAI,MAAM,GAAG,IAAI;IAIzB,OAAO,CAAC,WAAW;YAIL,kBAAkB;YAOlB,YAAY;CAO3B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,EACb,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC1B,OAAO,CAAC,EAAE,OAAO,CACf,IAAI,CACF,QAAQ,EACR,OAAO,GAAG,YAAY,GAAG,eAAe,GAAG,UAAU,GAAG,aAAa,CACtE,CACF,GACA,QAAQ,CAYV"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Log writer for structured workflow run logs
3
+ *
4
+ * Writes JSON logs to disk for analysis and debugging.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { LogWriter } from './log-writer';
9
+ *
10
+ * const writer = new LogWriter({ projectPath: '.sequant/logs' });
11
+ * await writer.initialize(config);
12
+ * await writer.logPhase(phaseLog);
13
+ * await writer.finalize();
14
+ * ```
15
+ */
16
+ import * as fs from "fs";
17
+ import * as path from "path";
18
+ import * as os from "os";
19
+ import { createEmptyRunLog, finalizeRunLog, generateLogFilename, LOG_PATHS, } from "./run-log-schema.js";
20
+ /**
21
+ * Manages writing structured run logs to disk
22
+ */
23
+ export class LogWriter {
24
+ runLog = null;
25
+ currentIssue = null;
26
+ logPath;
27
+ writeToUserLogs;
28
+ verbose;
29
+ constructor(options = {}) {
30
+ this.logPath = options.logPath ?? LOG_PATHS.project;
31
+ this.writeToUserLogs = options.writeToUserLogs ?? false;
32
+ this.verbose = options.verbose ?? false;
33
+ }
34
+ /**
35
+ * Initialize a new run log
36
+ *
37
+ * @param config - Run configuration
38
+ */
39
+ async initialize(config) {
40
+ this.runLog = createEmptyRunLog(config);
41
+ // Ensure log directory exists
42
+ await this.ensureLogDirectory(this.logPath);
43
+ if (this.writeToUserLogs) {
44
+ const userPath = LOG_PATHS.user.replace("~", os.homedir());
45
+ await this.ensureLogDirectory(userPath);
46
+ }
47
+ if (this.verbose && this.runLog) {
48
+ console.log(`📝 Log initialized: ${this.runLog.runId}`);
49
+ }
50
+ }
51
+ /**
52
+ * Start logging a new issue
53
+ *
54
+ * @param issueNumber - GitHub issue number
55
+ * @param title - Issue title
56
+ * @param labels - Issue labels
57
+ */
58
+ startIssue(issueNumber, title, labels) {
59
+ if (!this.runLog) {
60
+ throw new Error("LogWriter not initialized. Call initialize() first.");
61
+ }
62
+ this.currentIssue = {
63
+ issueNumber,
64
+ title,
65
+ labels,
66
+ phases: [],
67
+ status: "success",
68
+ totalDurationSeconds: 0,
69
+ };
70
+ if (this.verbose) {
71
+ console.log(`📝 Started logging issue #${issueNumber}`);
72
+ }
73
+ }
74
+ /**
75
+ * Log a completed phase
76
+ *
77
+ * @param phaseLog - Complete phase log entry
78
+ */
79
+ logPhase(phaseLog) {
80
+ if (!this.currentIssue) {
81
+ throw new Error("No current issue. Call startIssue() first.");
82
+ }
83
+ this.currentIssue.phases = [...(this.currentIssue.phases ?? []), phaseLog];
84
+ // Update issue status based on phase result
85
+ if (phaseLog.status === "failure") {
86
+ this.currentIssue.status = "failure";
87
+ }
88
+ else if (phaseLog.status === "timeout" &&
89
+ this.currentIssue.status !== "failure") {
90
+ this.currentIssue.status = "partial";
91
+ }
92
+ if (this.verbose) {
93
+ console.log(`📝 Logged phase: ${phaseLog.phase} (${phaseLog.status}) - ${phaseLog.durationSeconds.toFixed(1)}s`);
94
+ }
95
+ }
96
+ /**
97
+ * Complete the current issue and add it to the run log
98
+ */
99
+ completeIssue() {
100
+ if (!this.runLog || !this.currentIssue) {
101
+ throw new Error("No current issue to complete.");
102
+ }
103
+ // Calculate total duration from phases
104
+ const totalDurationSeconds = this.currentIssue.phases?.reduce((sum, p) => sum + p.durationSeconds, 0) ?? 0;
105
+ const issueLog = {
106
+ issueNumber: this.currentIssue.issueNumber,
107
+ title: this.currentIssue.title,
108
+ labels: this.currentIssue.labels,
109
+ status: this.currentIssue.status,
110
+ phases: this.currentIssue.phases,
111
+ totalDurationSeconds,
112
+ };
113
+ this.runLog.issues.push(issueLog);
114
+ this.currentIssue = null;
115
+ if (this.verbose) {
116
+ console.log(`📝 Completed issue #${issueLog.issueNumber} (${issueLog.status})`);
117
+ }
118
+ }
119
+ /**
120
+ * Finalize the run log and write to disk
121
+ *
122
+ * @returns Path to the written log file
123
+ */
124
+ async finalize() {
125
+ if (!this.runLog) {
126
+ throw new Error("LogWriter not initialized.");
127
+ }
128
+ // Complete any pending issue
129
+ if (this.currentIssue) {
130
+ this.completeIssue();
131
+ }
132
+ const finalLog = finalizeRunLog(this.runLog);
133
+ const filename = generateLogFilename(finalLog.runId, new Date(finalLog.startTime));
134
+ // Write to project logs
135
+ const projectPath = path.join(this.resolvePath(this.logPath), filename);
136
+ await this.writeLogFile(projectPath, finalLog);
137
+ // Optionally write to user logs
138
+ if (this.writeToUserLogs) {
139
+ const userPath = path.join(this.resolvePath(LOG_PATHS.user), filename);
140
+ await this.writeLogFile(userPath, finalLog);
141
+ }
142
+ if (this.verbose) {
143
+ console.log(`📝 Log written: ${projectPath}`);
144
+ }
145
+ return projectPath;
146
+ }
147
+ /**
148
+ * Get the current run log (for inspection)
149
+ */
150
+ getRunLog() {
151
+ return this.runLog;
152
+ }
153
+ /**
154
+ * Get the run ID
155
+ */
156
+ getRunId() {
157
+ return this.runLog?.runId ?? null;
158
+ }
159
+ resolvePath(logPath) {
160
+ return logPath.replace("~", os.homedir());
161
+ }
162
+ async ensureLogDirectory(logPath) {
163
+ const resolved = this.resolvePath(logPath);
164
+ if (!fs.existsSync(resolved)) {
165
+ fs.mkdirSync(resolved, { recursive: true });
166
+ }
167
+ }
168
+ async writeLogFile(filePath, log) {
169
+ const dir = path.dirname(filePath);
170
+ if (!fs.existsSync(dir)) {
171
+ fs.mkdirSync(dir, { recursive: true });
172
+ }
173
+ fs.writeFileSync(filePath, JSON.stringify(log, null, 2));
174
+ }
175
+ }
176
+ /**
177
+ * Create a simple phase log from timing data
178
+ *
179
+ * Utility function for creating phase logs when you have start/end times.
180
+ */
181
+ export function createPhaseLogFromTiming(phase, issueNumber, startTime, endTime, status, options) {
182
+ const durationSeconds = (endTime.getTime() - startTime.getTime()) / 1000;
183
+ return {
184
+ phase,
185
+ issueNumber,
186
+ startTime: startTime.toISOString(),
187
+ endTime: endTime.toISOString(),
188
+ durationSeconds,
189
+ status,
190
+ ...options,
191
+ };
192
+ }
193
+ //# sourceMappingURL=log-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-writer.js","sourceRoot":"","sources":["../../../../src/lib/workflow/log-writer.ts"],"names":[],"mappings":"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"}