forge-cc 0.1.40 → 1.0.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.
Files changed (72) hide show
  1. package/README.md +454 -338
  2. package/dist/cli.js +194 -906
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config/loader.d.ts +1 -1
  5. package/dist/config/loader.js +49 -56
  6. package/dist/config/loader.js.map +1 -1
  7. package/dist/config/schema.d.ts +37 -125
  8. package/dist/config/schema.js +13 -28
  9. package/dist/config/schema.js.map +1 -1
  10. package/dist/doctor.d.ts +10 -0
  11. package/dist/doctor.js +148 -0
  12. package/dist/doctor.js.map +1 -0
  13. package/dist/gates/index.d.ts +14 -12
  14. package/dist/gates/index.js +53 -105
  15. package/dist/gates/index.js.map +1 -1
  16. package/dist/gates/lint-gate.d.ts +2 -2
  17. package/dist/gates/lint-gate.js +60 -66
  18. package/dist/gates/lint-gate.js.map +1 -1
  19. package/dist/gates/tests-gate.d.ts +2 -4
  20. package/dist/gates/tests-gate.js +75 -203
  21. package/dist/gates/tests-gate.js.map +1 -1
  22. package/dist/gates/types-gate.d.ts +2 -2
  23. package/dist/gates/types-gate.js +53 -59
  24. package/dist/gates/types-gate.js.map +1 -1
  25. package/dist/go/linear-sync-cli.js +13 -4
  26. package/dist/go/linear-sync-cli.js.map +1 -1
  27. package/dist/go/linear-sync.d.ts +1 -0
  28. package/dist/go/linear-sync.js +67 -4
  29. package/dist/go/linear-sync.js.map +1 -1
  30. package/dist/linear/client.d.ts +34 -105
  31. package/dist/linear/client.js +85 -365
  32. package/dist/linear/client.js.map +1 -1
  33. package/dist/linear/issues.d.ts +3 -1
  34. package/dist/linear/issues.js +14 -2
  35. package/dist/linear/issues.js.map +1 -1
  36. package/dist/linear/projects.js +3 -2
  37. package/dist/linear/projects.js.map +1 -1
  38. package/dist/linear/sync.d.ts +15 -0
  39. package/dist/linear/sync.js +102 -0
  40. package/dist/linear/sync.js.map +1 -0
  41. package/dist/runner/loop.d.ts +4 -0
  42. package/dist/runner/loop.js +168 -0
  43. package/dist/runner/loop.js.map +1 -0
  44. package/dist/runner/prompt.d.ts +14 -0
  45. package/dist/runner/prompt.js +59 -0
  46. package/dist/runner/prompt.js.map +1 -0
  47. package/dist/runner/update.d.ts +1 -0
  48. package/dist/runner/update.js +72 -0
  49. package/dist/runner/update.js.map +1 -0
  50. package/dist/server.d.ts +6 -2
  51. package/dist/server.js +43 -101
  52. package/dist/server.js.map +1 -1
  53. package/dist/setup.d.ts +5 -0
  54. package/dist/setup.js +208 -0
  55. package/dist/setup.js.map +1 -0
  56. package/dist/state/cache.d.ts +3 -0
  57. package/dist/state/cache.js +23 -0
  58. package/dist/state/cache.js.map +1 -0
  59. package/dist/state/status.d.ts +66 -0
  60. package/dist/state/status.js +96 -0
  61. package/dist/state/status.js.map +1 -0
  62. package/dist/types.d.ts +46 -114
  63. package/dist/worktree/manager.d.ts +6 -103
  64. package/dist/worktree/manager.js +25 -296
  65. package/dist/worktree/manager.js.map +1 -1
  66. package/hooks/pre-commit-verify.js +109 -109
  67. package/package.json +3 -2
  68. package/skills/forge-go.md +583 -575
  69. package/skills/forge-setup.md +149 -388
  70. package/skills/forge-spec.md +367 -342
  71. package/skills/forge-triage.md +179 -133
  72. package/skills/forge-update.md +87 -93
@@ -1,219 +1,91 @@
1
- import { execSync } from "node:child_process";
2
- import { buildTestRemediation, buildTestCoverageRemediation } from "./remediation.js";
3
- import { analyzeTestCoverage } from "./test-analysis.js";
4
- import { loadConfig } from "../config/loader.js";
5
- /**
6
- * Common test failure patterns with file/line info:
7
- * FAIL src/foo.test.ts > suite > test name
8
- * at src/foo.test.ts:42:10
9
- */
10
- const TEST_FILE_RE = /^FAIL\s+(.+?)(?:\s+>|$)/;
11
- const STACKTRACE_RE = /at\s+.*?([^\s(]+):(\d+):\d+/;
12
- export async function verifyTests(projectDir, options) {
13
- const start = Date.now();
14
- const errors = [];
15
- const warnings = [];
16
- // Load config and run test analysis
17
- const config = loadConfig(options?.configRoot ?? projectDir);
18
- const testingConfig = config.testing;
19
- const analysis = await analyzeTestCoverage(projectDir);
20
- // Detect whether a test script exists in package.json
21
- let hasTestScript = false;
1
+ import { spawn } from "node:child_process";
2
+ import { readFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ /** Detect test runner from package.json dependencies. */
5
+ async function detectRunner(projectDir) {
22
6
  try {
23
- const pkgRaw = execSync("node -e \"process.stdout.write(JSON.stringify(require('./package.json')))\"", {
24
- cwd: projectDir,
25
- stdio: "pipe",
26
- timeout: 10_000,
27
- });
28
- const pkg = JSON.parse(String(pkgRaw));
29
- hasTestScript = !!pkg.scripts?.test;
7
+ const content = await readFile(join(projectDir, "package.json"), "utf-8");
8
+ const pkg = JSON.parse(content);
9
+ const deps = {
10
+ ...pkg.dependencies,
11
+ ...pkg.devDependencies,
12
+ };
13
+ if ("vitest" in deps)
14
+ return "vitest";
15
+ if ("jest" in deps)
16
+ return "jest";
30
17
  }
31
18
  catch {
32
- // No package.json or invalid hasTestScript stays false
33
- }
34
- // -----------------------------------------------------------------------
35
- // Baseline check: If zero test files AND no test script, FAIL immediately
36
- // -----------------------------------------------------------------------
37
- if (analysis.coverage.testFiles === 0 && !hasTestScript) {
38
- const categoryNames = analysis.categories.map(c => c.name).join(", ");
39
- const msg = `No tests found. ${analysis.coverage.sourceFiles} source file${analysis.coverage.sourceFiles === 1 ? "" : "s"} across ${analysis.categories.length} categor${analysis.categories.length === 1 ? "y" : "ies"} (${categoryNames || "none"}) have no test coverage. Run \`/forge:setup\` to scaffold tests.`;
40
- const error = { message: msg };
41
- error.remediation = buildTestCoverageRemediation(error);
42
- errors.push(error);
43
- return {
44
- gate: "tests",
45
- passed: false,
46
- errors,
47
- warnings,
48
- duration_ms: Date.now() - start,
49
- };
19
+ // No package.json — fall through
50
20
  }
51
- // Also baseline-fail if test files exist but no test script to run them
52
- if (analysis.coverage.testFiles === 0 && hasTestScript) {
53
- // Test script exists but no test files found — still baseline fail
54
- const msg = `No test files found. A test script exists in package.json but no test files were detected. Run \`/forge:setup\` to scaffold tests.`;
55
- const error = { message: msg };
56
- error.remediation = buildTestCoverageRemediation(error);
57
- errors.push(error);
21
+ return "unknown";
22
+ }
23
+ async function runTestRunner(projectDir) {
24
+ const start = Date.now();
25
+ const runner = await detectRunner(projectDir);
26
+ if (runner === "unknown") {
58
27
  return {
59
28
  gate: "tests",
60
29
  passed: false,
61
- errors,
62
- warnings,
63
- duration_ms: Date.now() - start,
30
+ errors: [{ file: "", line: 0, message: "No test runner detected (install vitest or jest)" }],
31
+ durationMs: Date.now() - start,
64
32
  };
65
33
  }
66
- // -----------------------------------------------------------------------
67
- // Run tests (if a test script exists)
68
- // -----------------------------------------------------------------------
69
- let testsRanSuccessfully = true;
70
- if (hasTestScript) {
71
- try {
72
- const result = execSync("npm run test -- --run", {
73
- cwd: projectDir,
74
- stdio: "pipe",
75
- timeout: 300_000,
76
- });
77
- const output = String(result);
78
- // Parse test summary from Vitest output
79
- const summaryMatch = output.match(/Tests\s+(\d+)\s+passed(?:\s*\|\s*(\d+)\s+failed)?/);
80
- if (summaryMatch) {
81
- const passed = summaryMatch[1];
82
- const failed = summaryMatch[2] ?? "0";
83
- warnings.push(`${passed} passed, ${failed} failed`);
84
- }
85
- }
86
- catch (err) {
87
- testsRanSuccessfully = false;
88
- const stdout = err instanceof Error && "stdout" in err
89
- ? String(err.stdout)
90
- : "";
91
- const stderr = err instanceof Error && "stderr" in err
92
- ? String(err.stderr)
93
- : "";
94
- const output = `${stdout}\n${stderr}`;
95
- let lastFailFile;
96
- for (const line of output.split("\n")) {
97
- const trimmed = line.trim();
98
- if (!trimmed)
99
- continue;
100
- // Track which test file we're in
101
- const failMatch = TEST_FILE_RE.exec(trimmed);
102
- if (failMatch) {
103
- lastFailFile = failMatch[1];
104
- }
105
- // Try to extract stack trace location
106
- const stackMatch = STACKTRACE_RE.exec(trimmed);
107
- if (stackMatch) {
108
- lastFailFile = stackMatch[1];
109
- }
110
- if (trimmed.includes("FAIL") ||
111
- trimmed.includes("AssertionError") ||
112
- trimmed.includes("AssertionError") ||
113
- trimmed.includes("Expected") ||
114
- trimmed.includes("Received")) {
34
+ const cmd = runner === "vitest" ? ["vitest", "run"] : ["jest", "--ci"];
35
+ return new Promise((resolve) => {
36
+ const child = spawn("npx", cmd, {
37
+ cwd: projectDir,
38
+ shell: true,
39
+ stdio: ["ignore", "pipe", "pipe"],
40
+ });
41
+ let stdout = "";
42
+ let stderr = "";
43
+ child.stdout.on("data", (data) => {
44
+ stdout += data.toString();
45
+ });
46
+ child.stderr.on("data", (data) => {
47
+ stderr += data.toString();
48
+ });
49
+ child.on("close", (code) => {
50
+ const errors = [];
51
+ if (code !== 0) {
52
+ const output = stdout + stderr;
53
+ const failRegex = /FAIL\s+(.+)/g;
54
+ let match;
55
+ while ((match = failRegex.exec(output)) !== null) {
115
56
  errors.push({
116
- file: lastFailFile,
117
- line: stackMatch ? Number.parseInt(stackMatch[2], 10) : undefined,
118
- message: trimmed,
57
+ file: match[1].trim(),
58
+ line: 0,
59
+ message: `Test suite failed: ${match[1].trim()}`,
119
60
  });
120
61
  }
121
- }
122
- // Also try to extract the summary even on failure
123
- const summaryMatch = output.match(/Tests\s+(?:(\d+)\s+passed\s*\|\s*)?(\d+)\s+failed/);
124
- if (summaryMatch) {
125
- const passed = summaryMatch[1] ?? "0";
126
- const failed = summaryMatch[2];
127
- warnings.push(`${passed} passed, ${failed} failed`);
128
- }
129
- if (errors.length === 0) {
130
- errors.push({ message: "Test runner exited with non-zero status" });
131
- }
132
- // Enrich errors with remediation hints
133
- for (const error of errors) {
134
- error.remediation = buildTestRemediation(error);
135
- }
136
- }
137
- }
138
- // -----------------------------------------------------------------------
139
- // Enforcement check: Verify changed files have corresponding tests
140
- // -----------------------------------------------------------------------
141
- if (testingConfig?.enforce) {
142
- const changedSourceFiles = getChangedSourceFiles(projectDir);
143
- if (changedSourceFiles.length > 0) {
144
- const untestedSet = new Set(analysis.coverage.untestedFiles);
145
- for (const file of changedSourceFiles) {
146
- const normalized = file.replace(/\\/g, "/");
147
- if (untestedSet.has(normalized)) {
148
- const error = {
149
- file: normalized,
150
- message: `Missing test file for changed source: ${normalized}`,
151
- };
152
- error.remediation = buildTestCoverageRemediation(error);
153
- errors.push(error);
154
- }
155
- }
156
- }
157
- }
158
- // -----------------------------------------------------------------------
159
- // Thin coverage advisory
160
- // -----------------------------------------------------------------------
161
- if (analysis.coverage.testFiles > 0 && analysis.coverage.ratio < 0.3) {
162
- warnings.push(`Thin test coverage: ratio ${analysis.coverage.ratio} (${analysis.coverage.testFiles} test file${analysis.coverage.testFiles === 1 ? "" : "s"} for ${analysis.coverage.sourceFiles} source file${analysis.coverage.sourceFiles === 1 ? "" : "s"}). Consider adding tests for untested files.`);
163
- }
164
- const passed = testsRanSuccessfully && errors.length === 0;
165
- return {
166
- gate: "tests",
167
- passed,
168
- errors,
169
- warnings,
170
- duration_ms: Date.now() - start,
171
- };
172
- }
173
- /**
174
- * Get source files changed relative to HEAD~1 or the staging area.
175
- * Returns paths relative to projectDir, normalized with forward slashes.
176
- */
177
- function getChangedSourceFiles(projectDir) {
178
- const files = [];
179
- // Try git diff against HEAD~1 first, fall back to cached diff
180
- for (const cmd of [
181
- "git diff --name-only HEAD~1",
182
- "git diff --cached --name-only",
183
- ]) {
184
- try {
185
- const output = execSync(cmd, {
186
- cwd: projectDir,
187
- stdio: "pipe",
188
- timeout: 10_000,
189
- }).toString().trim();
190
- if (output) {
191
- for (const line of output.split("\n")) {
192
- const trimmed = line.trim();
193
- if (!trimmed)
194
- continue;
195
- // Only include source files (not test files, not configs)
196
- if (isSourceFilePath(trimmed)) {
197
- files.push(trimmed.replace(/\\/g, "/"));
198
- }
62
+ if (errors.length === 0) {
63
+ errors.push({
64
+ file: "",
65
+ line: 0,
66
+ message: `Test runner exited with code ${code}`,
67
+ });
199
68
  }
200
- break; // Use the first successful command
201
69
  }
202
- }
203
- catch {
204
- // Command failed — try the next one
205
- }
206
- }
207
- return files;
208
- }
209
- /** Check if a path looks like a source file (TS/JS, not a test, not a declaration). */
210
- function isSourceFilePath(filePath) {
211
- if (!/\.(ts|tsx|js|jsx)$/.test(filePath))
212
- return false;
213
- if (/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filePath))
214
- return false;
215
- if (filePath.endsWith(".d.ts"))
216
- return false;
217
- return true;
70
+ resolve({
71
+ gate: "tests",
72
+ passed: code === 0,
73
+ errors,
74
+ durationMs: Date.now() - start,
75
+ });
76
+ });
77
+ child.on("error", (err) => {
78
+ resolve({
79
+ gate: "tests",
80
+ passed: false,
81
+ errors: [{ file: "", line: 0, message: err.message }],
82
+ durationMs: Date.now() - start,
83
+ });
84
+ });
85
+ });
218
86
  }
87
+ export const testsGate = {
88
+ name: "tests",
89
+ run: runTestRunner,
90
+ };
219
91
  //# sourceMappingURL=tests-gate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tests-gate.js","sourceRoot":"","sources":["../../src/gates/tests-gate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tests-gate.js","sourceRoot":"","sources":["../../src/gates/tests-gate.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import type { GateResult } from "../types.js";
2
- export declare function verifyTypes(projectDir: string): Promise<GateResult>;
1
+ import type { Gate } from "./index.js";
2
+ export declare const typesGate: Gate;
@@ -1,64 +1,58 @@
1
- import { execSync } from "node:child_process";
2
- import { buildTypeRemediation } from "./remediation.js";
3
- /** Regex to parse tsc error lines: src/foo.ts(10,5): error TS2322: ... */
4
- const TSC_ERROR_RE = /^(.+?)\((\d+),\d+\):\s*(.+)$/;
5
- export async function verifyTypes(projectDir) {
6
- const start = Date.now();
1
+ import { spawn } from "node:child_process";
2
+ /** Parse tsc output lines into structured errors. */
3
+ function parseTscOutput(output) {
7
4
  const errors = [];
8
- const warnings = [];
9
- try {
10
- execSync("npx tsc --noEmit", {
11
- cwd: projectDir,
12
- stdio: "pipe",
13
- timeout: 120_000,
5
+ // tsc error format: file(line,col): error TSxxxx: message
6
+ const regex = /^(.+?)\((\d+),(\d+)\):\s+error\s+TS\d+:\s+(.+)$/gm;
7
+ let match;
8
+ while ((match = regex.exec(output)) !== null) {
9
+ errors.push({
10
+ file: match[1],
11
+ line: parseInt(match[2], 10),
12
+ column: parseInt(match[3], 10),
13
+ message: match[4],
14
14
  });
15
- return {
16
- gate: "types",
17
- passed: true,
18
- errors,
19
- warnings,
20
- duration_ms: Date.now() - start,
21
- };
22
- }
23
- catch (err) {
24
- const output = err instanceof Error && "stdout" in err
25
- ? String(err.stdout)
26
- : "";
27
- for (const line of output.split("\n")) {
28
- const trimmed = line.trim();
29
- if (!trimmed)
30
- continue;
31
- if (trimmed.toLowerCase().includes("warning")) {
32
- warnings.push(trimmed);
33
- }
34
- else if (trimmed.includes("error TS")) {
35
- const match = TSC_ERROR_RE.exec(trimmed);
36
- if (match) {
37
- errors.push({
38
- file: match[1],
39
- line: Number.parseInt(match[2], 10),
40
- message: match[3],
41
- });
42
- }
43
- else {
44
- errors.push({ message: trimmed });
45
- }
46
- }
47
- }
48
- if (errors.length === 0) {
49
- errors.push({ message: "tsc exited with non-zero status but no TS errors were parsed" });
50
- }
51
- // Enrich errors with remediation hints
52
- for (const error of errors) {
53
- error.remediation = buildTypeRemediation(error);
54
- }
55
- return {
56
- gate: "types",
57
- passed: false,
58
- errors,
59
- warnings,
60
- duration_ms: Date.now() - start,
61
- };
62
15
  }
16
+ return errors;
17
+ }
18
+ function runTsc(projectDir) {
19
+ return new Promise((resolve) => {
20
+ const start = Date.now();
21
+ const child = spawn("npx", ["tsc", "--noEmit"], {
22
+ cwd: projectDir,
23
+ shell: true,
24
+ stdio: ["ignore", "pipe", "pipe"],
25
+ });
26
+ let stdout = "";
27
+ let stderr = "";
28
+ child.stdout.on("data", (data) => {
29
+ stdout += data.toString();
30
+ });
31
+ child.stderr.on("data", (data) => {
32
+ stderr += data.toString();
33
+ });
34
+ child.on("close", (code) => {
35
+ const output = stdout + stderr;
36
+ const errors = parseTscOutput(output);
37
+ resolve({
38
+ gate: "types",
39
+ passed: code === 0,
40
+ errors,
41
+ durationMs: Date.now() - start,
42
+ });
43
+ });
44
+ child.on("error", (err) => {
45
+ resolve({
46
+ gate: "types",
47
+ passed: false,
48
+ errors: [{ file: "", line: 0, message: err.message }],
49
+ durationMs: Date.now() - start,
50
+ });
51
+ });
52
+ });
63
53
  }
54
+ export const typesGate = {
55
+ name: "types",
56
+ run: runTsc,
57
+ };
64
58
  //# sourceMappingURL=types-gate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types-gate.js","sourceRoot":"","sources":["../../src/gates/types-gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,0EAA0E;AAC1E,MAAM,YAAY,GAAG,8BAA8B,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAkB;IAClD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,QAAQ,CAAC,kBAAkB,EAAE;YAC3B,GAAG,EAAE,UAAU;YACf,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,OAAO;YACL,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,IAAI;YACZ,MAAM;YACN,QAAQ;YACR,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;SAChC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,MAAM,GACV,GAAG,YAAY,KAAK,IAAI,QAAQ,IAAI,GAAG;YACrC,CAAC,CAAC,MAAM,CAAE,GAA0B,CAAC,MAAM,CAAC;YAC5C,CAAC,CAAC,EAAE,CAAC;QAET,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO;gBAAE,SAAS;YAEvB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9C,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;iBAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;gBACxC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACzC,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;wBACd,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;wBACnC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;qBAClB,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,8DAA8D,EAAE,CAAC,CAAC;QAC3F,CAAC;QAED,uCAAuC;QACvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,KAAK,CAAC,WAAW,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAClD,CAAC;QAED,OAAO;YACL,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,KAAK;YACb,MAAM;YACN,QAAQ;YACR,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;SAChC,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"types-gate.js","sourceRoot":"","sources":["../../src/gates/types-gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAI3C,qDAAqD;AACrD,SAAS,cAAc,CAAC,MAAc;IACpC,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,0DAA0D;IAC1D,MAAM,KAAK,GAAG,mDAAmD,CAAC;IAClE,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;YACd,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YAC9B,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;SAClB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,MAAM,CAAC,UAAkB;IAChC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE;YAC9C,GAAG,EAAE,UAAU;YACf,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACvC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACvC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;YAC/B,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YACtC,OAAO,CAAC;gBACN,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,IAAI,KAAK,CAAC;gBAClB,MAAM;gBACN,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;aAC/B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,OAAO,CAAC;gBACN,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;gBACrD,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;aAC/B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAS;IAC7B,IAAI,EAAE,OAAO;IACb,GAAG,EAAE,MAAM;CACZ,CAAC"}
@@ -42,6 +42,7 @@ export async function resolveLinearProjectId(projectDir, slug) {
42
42
  }
43
43
  catch (error) {
44
44
  if (error instanceof LinearClientError) {
45
+ console.warn("[linear-sync] WARN: LINEAR_API_KEY not set — skipping Linear sync");
45
46
  return null;
46
47
  }
47
48
  throw error;
@@ -92,8 +93,10 @@ export async function cliSyncStart(projectDir, slug, milestoneNumber) {
92
93
  new LinearClient();
93
94
  }
94
95
  catch (error) {
95
- if (error instanceof LinearClientError)
96
+ if (error instanceof LinearClientError) {
97
+ console.warn("[linear-sync] WARN: LINEAR_API_KEY not set — skipping Linear sync");
96
98
  return null;
99
+ }
97
100
  throw error;
98
101
  }
99
102
  const milestoneName = await resolveMilestoneName(projectDir, slug, milestoneNumber);
@@ -121,8 +124,10 @@ export async function cliSyncComplete(projectDir, slug, milestoneNumber, isLastM
121
124
  new LinearClient();
122
125
  }
123
126
  catch (error) {
124
- if (error instanceof LinearClientError)
127
+ if (error instanceof LinearClientError) {
128
+ console.warn("[linear-sync] WARN: LINEAR_API_KEY not set — skipping Linear sync");
125
129
  return null;
130
+ }
126
131
  throw error;
127
132
  }
128
133
  const milestoneName = await resolveMilestoneName(projectDir, slug, milestoneNumber);
@@ -151,8 +156,10 @@ export async function cliFetchIssueIdentifiers(projectDir, slug) {
151
156
  new LinearClient();
152
157
  }
153
158
  catch (error) {
154
- if (error instanceof LinearClientError)
159
+ if (error instanceof LinearClientError) {
160
+ console.warn("[linear-sync] WARN: LINEAR_API_KEY not set — skipping Linear sync");
155
161
  return null;
162
+ }
156
163
  throw error;
157
164
  }
158
165
  return fetchProjectIssueIdentifiers({ projectId });
@@ -174,8 +181,10 @@ export async function cliSyncDone(projectDir, slug) {
174
181
  new LinearClient();
175
182
  }
176
183
  catch (error) {
177
- if (error instanceof LinearClientError)
184
+ if (error instanceof LinearClientError) {
185
+ console.warn("[linear-sync] WARN: LINEAR_API_KEY not set — skipping Linear sync");
178
186
  return null;
187
+ }
179
188
  throw error;
180
189
  }
181
190
  return syncProjectDone({ projectId });
@@ -1 +1 @@
1
- {"version":3,"file":"linear-sync-cli.js","sourceRoot":"","sources":["../../src/go/linear-sync-cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"linear-sync-cli.js","sourceRoot":"","sources":["../../src/go/linear-sync-cli.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ export interface LinearSyncOptions {
16
16
  projectId: string;
17
17
  milestoneNumber: number;
18
18
  milestoneName: string;
19
+ teamId?: string;
19
20
  apiKey?: string;
20
21
  }
21
22
  export interface MilestoneStartSync {