stratanodex 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +251 -0
- package/dist/api/ApiError.js +10 -0
- package/dist/api/client.js +96 -0
- package/dist/commands/add.js +45 -0
- package/dist/commands/config.js +41 -0
- package/dist/commands/done.js +39 -0
- package/dist/commands/executor.js +457 -0
- package/dist/commands/list.js +86 -0
- package/dist/commands/login.js +1 -0
- package/dist/commands/loginFlow.js +86 -0
- package/dist/commands/logout.js +11 -0
- package/dist/commands/registry.js +351 -0
- package/dist/commands/resolver.js +184 -0
- package/dist/config.js +16 -0
- package/dist/index.js +77 -0
- package/dist/tui/App.js +141 -0
- package/dist/tui/components/AutocompleteOverlay.js +22 -0
- package/dist/tui/components/BottomBar.js +8 -0
- package/dist/tui/components/Breadcrumb.js +6 -0
- package/dist/tui/components/CommandInput.js +111 -0
- package/dist/tui/components/CommandPalette.js +1 -0
- package/dist/tui/components/ErrorBoundary.js +26 -0
- package/dist/tui/components/FocusMode.js +1 -0
- package/dist/tui/components/FolderItem.js +5 -0
- package/dist/tui/components/Header.js +5 -0
- package/dist/tui/components/Keybindings.js +5 -0
- package/dist/tui/components/ListItem.js +5 -0
- package/dist/tui/components/NodeRow.js +14 -0
- package/dist/tui/components/PriorityBadge.js +9 -0
- package/dist/tui/components/SearchOverlay.js +1 -0
- package/dist/tui/components/Spinner.js +23 -0
- package/dist/tui/components/StatusBadge.js +9 -0
- package/dist/tui/components/SuggestionItem.js +8 -0
- package/dist/tui/components/TopBar.js +13 -0
- package/dist/tui/components/TreeConnector.js +17 -0
- package/dist/tui/hooks/useAuth.js +37 -0
- package/dist/tui/hooks/useCommandInput.js +35 -0
- package/dist/tui/hooks/useFolders.js +16 -0
- package/dist/tui/hooks/useKeymap.js +30 -0
- package/dist/tui/hooks/useLists.js +16 -0
- package/dist/tui/hooks/useNavigation.js +15 -0
- package/dist/tui/hooks/useTree.js +93 -0
- package/dist/tui/screens/DailyScreen.js +77 -0
- package/dist/tui/screens/DashboardScreen.js +262 -0
- package/dist/tui/screens/HomeScreen.js +75 -0
- package/dist/tui/screens/ListsScreen.js +73 -0
- package/dist/tui/screens/LoginScreen.js +115 -0
- package/dist/tui/screens/NodeScreen.js +48 -0
- package/dist/tui/screens/TreeScreen.js +182 -0
- package/dist/tui/screens/WelcomeScreen.js +83 -0
- package/dist/tui/types.js +1 -0
- package/dist/types/index.js +1 -0
- package/dist/utils/auth.js +11 -0
- package/dist/utils/logger.js +32 -0
- package/dist/utils/numbering.js +38 -0
- package/dist/utils/recents.js +24 -0
- package/dist/utils/scoring.js +29 -0
- package/dist/utils/tree.js +125 -0
- package/package.json +74 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export function flattenTree(nodes) {
|
|
2
|
+
const result = [];
|
|
3
|
+
function dfs(children) {
|
|
4
|
+
for (const node of children) {
|
|
5
|
+
result.push(node);
|
|
6
|
+
if ((node.children ?? []).length > 0)
|
|
7
|
+
dfs(node.children ?? []);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
dfs(nodes);
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
export function findNode(nodes, id) {
|
|
14
|
+
for (const node of nodes) {
|
|
15
|
+
if (node.id === id)
|
|
16
|
+
return node;
|
|
17
|
+
const found = findNode(node.children ?? [], id);
|
|
18
|
+
if (found)
|
|
19
|
+
return found;
|
|
20
|
+
}
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
function removeFromTree(nodes, id) {
|
|
24
|
+
let removed;
|
|
25
|
+
const result = nodes.reduce((acc, node) => {
|
|
26
|
+
if (node.id === id) {
|
|
27
|
+
removed = node;
|
|
28
|
+
return acc;
|
|
29
|
+
}
|
|
30
|
+
const [newChildren, removedChild] = removeFromTree(node.children ?? [], id);
|
|
31
|
+
if (removedChild)
|
|
32
|
+
removed = removedChild;
|
|
33
|
+
return [...acc, { ...node, children: newChildren }];
|
|
34
|
+
}, []);
|
|
35
|
+
return [result, removed];
|
|
36
|
+
}
|
|
37
|
+
function insertIntoTree(nodes, parentId, node) {
|
|
38
|
+
if (parentId === null) {
|
|
39
|
+
return [...nodes, { ...node, parentId: null }];
|
|
40
|
+
}
|
|
41
|
+
return nodes.map((n) => {
|
|
42
|
+
if (n.id === parentId) {
|
|
43
|
+
return { ...n, children: [...(n.children ?? []), { ...node, parentId }] };
|
|
44
|
+
}
|
|
45
|
+
return { ...n, children: insertIntoTree(n.children ?? [], parentId, node) };
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Move a node to a new parent (or to root if newParentId is null).
|
|
50
|
+
* Returns a new tree — does not mutate input.
|
|
51
|
+
* Caller must also call moveNode() API to persist.
|
|
52
|
+
*/
|
|
53
|
+
export function moveNode(nodes, nodeId, newParentId) {
|
|
54
|
+
const [treeWithout, removed] = removeFromTree(nodes, nodeId);
|
|
55
|
+
if (!removed)
|
|
56
|
+
return nodes;
|
|
57
|
+
return insertIntoTree(treeWithout, newParentId, removed);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Make a node the last child of its previous sibling.
|
|
61
|
+
* Does nothing if no previous sibling exists.
|
|
62
|
+
*/
|
|
63
|
+
export function indentNode(nodes, nodeId) {
|
|
64
|
+
const flat = flattenTree(nodes);
|
|
65
|
+
const node = flat.find((n) => n.id === nodeId);
|
|
66
|
+
if (!node)
|
|
67
|
+
return nodes;
|
|
68
|
+
const siblings = flat
|
|
69
|
+
.filter((n) => n.parentId === node.parentId)
|
|
70
|
+
.sort((a, b) => a.position - b.position);
|
|
71
|
+
const idx = siblings.findIndex((n) => n.id === nodeId);
|
|
72
|
+
if (idx <= 0)
|
|
73
|
+
return nodes;
|
|
74
|
+
return moveNode(nodes, nodeId, siblings[idx - 1].id);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Promote a node to its grandparent level (one level up).
|
|
78
|
+
* Does nothing if node is already at root.
|
|
79
|
+
*/
|
|
80
|
+
export function outdentNode(nodes, nodeId) {
|
|
81
|
+
const flat = flattenTree(nodes);
|
|
82
|
+
const node = flat.find((n) => n.id === nodeId);
|
|
83
|
+
if (!node || node.parentId === null)
|
|
84
|
+
return nodes;
|
|
85
|
+
const parent = flat.find((n) => n.id === node.parentId);
|
|
86
|
+
if (!parent)
|
|
87
|
+
return nodes;
|
|
88
|
+
return moveNode(nodes, nodeId, parent.parentId);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Swap a node with its previous or next sibling by position.
|
|
92
|
+
* Returns new tree — does not mutate input.
|
|
93
|
+
* Caller must also call moveNode() API to persist.
|
|
94
|
+
*/
|
|
95
|
+
export function reorderSiblings(nodes, nodeId, direction) {
|
|
96
|
+
const flat = flattenTree(nodes);
|
|
97
|
+
const node = flat.find((n) => n.id === nodeId);
|
|
98
|
+
if (!node)
|
|
99
|
+
return nodes;
|
|
100
|
+
const siblings = flat
|
|
101
|
+
.filter((n) => n.parentId === node.parentId)
|
|
102
|
+
.sort((a, b) => a.position - b.position);
|
|
103
|
+
const idx = siblings.findIndex((n) => n.id === nodeId);
|
|
104
|
+
if (direction === 'up' && idx <= 0)
|
|
105
|
+
return nodes;
|
|
106
|
+
if (direction === 'down' && idx >= siblings.length - 1)
|
|
107
|
+
return nodes;
|
|
108
|
+
const swapIdx = direction === 'up' ? idx - 1 : idx + 1;
|
|
109
|
+
const swap = siblings[swapIdx];
|
|
110
|
+
const nodePos = node.position;
|
|
111
|
+
const swapPos = swap.position;
|
|
112
|
+
function updatePositions(children) {
|
|
113
|
+
return children.map((n) => {
|
|
114
|
+
const updated = n.id === nodeId
|
|
115
|
+
? { ...n, position: swapPos }
|
|
116
|
+
: n.id === swap.id
|
|
117
|
+
? { ...n, position: nodePos }
|
|
118
|
+
: n;
|
|
119
|
+
return (updated.children ?? []).length > 0
|
|
120
|
+
? { ...updated, children: updatePositions(updated.children ?? []) }
|
|
121
|
+
: updated;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return updatePositions(nodes);
|
|
125
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "stratanodex",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Keyboard-driven terminal task manager — hierarchical folders, lists & nodes with a full TUI",
|
|
5
|
+
"homepage": "https://stratanodex.online",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/pranavdadhe1806/StrataNodex-CLI"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"bin": {
|
|
12
|
+
"stratanodex": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20.0.0"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "tsx src/index.ts",
|
|
19
|
+
"dev:local": "cross-env STRATANODEX_API_URL=http://localhost:3000 STRATANODEX_AUTH_URL=http://localhost:3001 tsx src/index.ts",
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"start": "node dist/index.js",
|
|
22
|
+
"test": "vitest",
|
|
23
|
+
"test:watch": "vitest --watch",
|
|
24
|
+
"lint": "eslint src/",
|
|
25
|
+
"format": "prettier --write src/",
|
|
26
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
27
|
+
"prepare": "husky install",
|
|
28
|
+
"prepublishOnly": "npm run lint && npm run test -- --run && npm run build"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"keywords": [
|
|
34
|
+
"cli",
|
|
35
|
+
"productivity",
|
|
36
|
+
"task-manager",
|
|
37
|
+
"todo",
|
|
38
|
+
"tui",
|
|
39
|
+
"terminal",
|
|
40
|
+
"stratanodex",
|
|
41
|
+
"ink"
|
|
42
|
+
],
|
|
43
|
+
"author": "Pranav Dadhe <pranavdadhe1806@gmail.com>",
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@inkjs/ui": "^2.0.0",
|
|
47
|
+
"axios": "^1.6.0",
|
|
48
|
+
"chalk": "^5.3.0",
|
|
49
|
+
"commander": "^11.0.0",
|
|
50
|
+
"conf": "^12.0.0",
|
|
51
|
+
"dotenv": "^16.3.0",
|
|
52
|
+
"ink": "^5.2.1",
|
|
53
|
+
"ink-text-input": "^6.0.0",
|
|
54
|
+
"open": "^11.0.0",
|
|
55
|
+
"pino": "^8.16.0",
|
|
56
|
+
"react": "^18.2.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/node": "^20.10.0",
|
|
60
|
+
"@types/react": "^18.2.0",
|
|
61
|
+
"@typescript-eslint/eslint-plugin": "^8.58.2",
|
|
62
|
+
"@typescript-eslint/parser": "^8.58.2",
|
|
63
|
+
"cross-env": "^10.1.0",
|
|
64
|
+
"eslint": "^8.55.0",
|
|
65
|
+
"eslint-plugin-react": "^7.37.5",
|
|
66
|
+
"husky": "^8.0.0",
|
|
67
|
+
"ink-testing-library": "^3.0.0",
|
|
68
|
+
"lint-staged": "^15.2.0",
|
|
69
|
+
"prettier": "^3.1.0",
|
|
70
|
+
"tsx": "^4.7.0",
|
|
71
|
+
"typescript": "^5.3.0",
|
|
72
|
+
"vitest": "^1.0.0"
|
|
73
|
+
}
|
|
74
|
+
}
|