issy 0.1.5 → 0.1.6
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/bin/issy +47 -3
- package/dist/cli.js +40 -9
- package/package.json +3 -3
package/bin/issy
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { dirname } from "node:path";
|
|
2
3
|
import { existsSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";
|
|
3
4
|
import { join, resolve } from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -15,10 +16,53 @@ const cliCommands = new Set([
|
|
|
15
16
|
"--help",
|
|
16
17
|
"-h",
|
|
17
18
|
]);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Find .issues directory by walking up from the given path.
|
|
22
|
+
* Returns the path if found, or null if not found.
|
|
23
|
+
*/
|
|
24
|
+
function findIssuesDirUpward(fromPath) {
|
|
25
|
+
let current = resolve(fromPath);
|
|
26
|
+
for (let i = 0; i < 20; i++) {
|
|
27
|
+
const candidate = join(current, ".issues");
|
|
28
|
+
if (existsSync(candidate)) {
|
|
29
|
+
return candidate;
|
|
30
|
+
}
|
|
31
|
+
const parent = dirname(current);
|
|
32
|
+
if (parent === current) break;
|
|
33
|
+
current = parent;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Resolve the issues directory using priority:
|
|
40
|
+
* 1. ISSUES_DIR env var (explicit override)
|
|
41
|
+
* 2. Walk up from ISSUES_ROOT or cwd to find existing .issues
|
|
42
|
+
* 3. Fall back to creating .issues in ISSUES_ROOT or cwd
|
|
43
|
+
*/
|
|
44
|
+
function resolveIssuesDir() {
|
|
45
|
+
// 1. Explicit override
|
|
46
|
+
if (process.env.ISSUES_DIR) {
|
|
47
|
+
return resolve(process.env.ISSUES_DIR);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 2. Try to find existing .issues by walking up
|
|
51
|
+
const startDir = process.env.ISSUES_ROOT || process.cwd();
|
|
52
|
+
const found = findIssuesDirUpward(startDir);
|
|
53
|
+
if (found) {
|
|
54
|
+
return found;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 3. Fall back to creating in start directory
|
|
58
|
+
return join(resolve(startDir), ".issues");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const issuesDir = resolveIssuesDir();
|
|
62
|
+
// Set env vars for downstream consumers
|
|
21
63
|
process.env.ISSUES_DIR = issuesDir;
|
|
64
|
+
// Set ISSUES_ROOT to the parent of .issues for consistency
|
|
65
|
+
process.env.ISSUES_ROOT = dirname(issuesDir);
|
|
22
66
|
|
|
23
67
|
if (cliCommands.has(args[0] || "")) {
|
|
24
68
|
const here = resolve(fileURLToPath(import.meta.url), "..");
|
package/dist/cli.js
CHANGED
|
@@ -2,24 +2,54 @@
|
|
|
2
2
|
// @bun
|
|
3
3
|
|
|
4
4
|
// src/cli.ts
|
|
5
|
-
import { join as join2 } from "path";
|
|
6
5
|
import { parseArgs } from "util";
|
|
7
6
|
// ../core/src/lib/issues.ts
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
8
|
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
9
|
-
import { join } from "node:path";
|
|
9
|
+
import { dirname, join, resolve } from "node:path";
|
|
10
10
|
var issuesDir = null;
|
|
11
11
|
function setIssuesDir(dir) {
|
|
12
12
|
issuesDir = dir;
|
|
13
13
|
}
|
|
14
14
|
function getIssuesDir() {
|
|
15
15
|
if (!issuesDir) {
|
|
16
|
-
throw new Error("Issues directory not initialized. Call setIssuesDir() first.");
|
|
16
|
+
throw new Error("Issues directory not initialized. Call setIssuesDir() or resolveIssuesDir() first.");
|
|
17
17
|
}
|
|
18
18
|
return issuesDir;
|
|
19
19
|
}
|
|
20
20
|
async function ensureIssuesDir() {
|
|
21
21
|
await mkdir(getIssuesDir(), { recursive: true });
|
|
22
22
|
}
|
|
23
|
+
function findIssuesDirUpward(fromPath) {
|
|
24
|
+
let current = resolve(fromPath);
|
|
25
|
+
for (let i = 0;i < 20; i++) {
|
|
26
|
+
const candidate = join(current, ".issues");
|
|
27
|
+
if (existsSync(candidate)) {
|
|
28
|
+
return candidate;
|
|
29
|
+
}
|
|
30
|
+
const parent = dirname(current);
|
|
31
|
+
if (parent === current)
|
|
32
|
+
break;
|
|
33
|
+
current = parent;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
function resolveIssuesDir() {
|
|
38
|
+
if (process.env.ISSUES_DIR) {
|
|
39
|
+
const dir = resolve(process.env.ISSUES_DIR);
|
|
40
|
+
setIssuesDir(dir);
|
|
41
|
+
return dir;
|
|
42
|
+
}
|
|
43
|
+
const startDir = process.env.ISSUES_ROOT || process.cwd();
|
|
44
|
+
const found = findIssuesDirUpward(startDir);
|
|
45
|
+
if (found) {
|
|
46
|
+
setIssuesDir(found);
|
|
47
|
+
return found;
|
|
48
|
+
}
|
|
49
|
+
const fallback = join(resolve(startDir), ".issues");
|
|
50
|
+
setIssuesDir(fallback);
|
|
51
|
+
return fallback;
|
|
52
|
+
}
|
|
23
53
|
function parseFrontmatter(content) {
|
|
24
54
|
const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
25
55
|
if (!match) {
|
|
@@ -1558,9 +1588,7 @@ function filterAndSearchIssues(issues, filters) {
|
|
|
1558
1588
|
return result;
|
|
1559
1589
|
}
|
|
1560
1590
|
// src/cli.ts
|
|
1561
|
-
|
|
1562
|
-
var ISSUES_DIR = process.env.ISSUES_DIR || join2(DEFAULT_ROOT, ".issues");
|
|
1563
|
-
setIssuesDir(ISSUES_DIR);
|
|
1591
|
+
resolveIssuesDir();
|
|
1564
1592
|
function prioritySymbol(priority) {
|
|
1565
1593
|
switch (priority) {
|
|
1566
1594
|
case "high":
|
|
@@ -1654,14 +1682,14 @@ Create New Issue`);
|
|
|
1654
1682
|
console.log("-".repeat(40));
|
|
1655
1683
|
const prompt = (question) => {
|
|
1656
1684
|
process.stdout.write(question);
|
|
1657
|
-
return new Promise((
|
|
1685
|
+
return new Promise((resolve2) => {
|
|
1658
1686
|
let input = "";
|
|
1659
1687
|
process.stdin.setRawMode?.(false);
|
|
1660
1688
|
process.stdin.resume();
|
|
1661
1689
|
process.stdin.setEncoding("utf8");
|
|
1662
1690
|
process.stdin.once("data", (data) => {
|
|
1663
1691
|
input = data.toString().trim();
|
|
1664
|
-
|
|
1692
|
+
resolve2(input);
|
|
1665
1693
|
});
|
|
1666
1694
|
});
|
|
1667
1695
|
};
|
|
@@ -1862,7 +1890,10 @@ Examples:
|
|
|
1862
1890
|
process.exit(1);
|
|
1863
1891
|
}
|
|
1864
1892
|
}
|
|
1865
|
-
main().catch((err) => {
|
|
1893
|
+
var ready = main().catch((err) => {
|
|
1866
1894
|
console.error(err);
|
|
1867
1895
|
process.exit(1);
|
|
1868
1896
|
});
|
|
1897
|
+
export {
|
|
1898
|
+
ready
|
|
1899
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "issy",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "AI-native issue tracking. Markdown files in .issues/, managed by your coding assistant.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"lint": "biome check src bin"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@miketromba/issy-app": "^0.1.
|
|
38
|
-
"@miketromba/issy-core": "^0.1.
|
|
37
|
+
"@miketromba/issy-app": "^0.1.6",
|
|
38
|
+
"@miketromba/issy-core": "^0.1.6"
|
|
39
39
|
}
|
|
40
40
|
}
|