atris 3.12.1 → 3.14.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 +39 -14
- package/bin/atris.js +39 -15
- package/commands/business.js +514 -24
- package/commands/computer.js +326 -9
- package/commands/errors.js +155 -0
- package/commands/proof.js +115 -0
- package/commands/pull.js +12 -6
- package/commands/push.js +8 -2
- package/commands/task.js +217 -0
- package/commands/visualize.js +324 -8
- package/lib/task-db.js +288 -0
- package/lib/todo-fallback.js +142 -0
- package/lib/todo.js +99 -184
- package/package.json +2 -2
- package/cli/__pycache__/atris_code.cpython-314.pyc +0 -0
- package/cli/__pycache__/runtime_guard.cpython-312.pyc +0 -0
- package/cli/__pycache__/runtime_guard.cpython-314.pyc +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Pure TODO.md markdown parser. The original lib/todo.js logic, extracted so
|
|
2
|
+
// the shim in lib/todo.js can fall back to it when the SQLite store is empty
|
|
3
|
+
// (or when ATRIS_TASK_DB is not enabled).
|
|
4
|
+
//
|
|
5
|
+
// Do not add new callers. Use lib/todo.js (the shim) — it merges DB + markdown.
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
function parseTodoFile(todoPath) {
|
|
13
|
+
if (!fs.existsSync(todoPath)) return { backlog: [], inProgress: [], completed: [] };
|
|
14
|
+
const content = fs.readFileSync(todoPath, 'utf8');
|
|
15
|
+
return {
|
|
16
|
+
backlog: parseSection(content, 'Backlog'),
|
|
17
|
+
inProgress: parseSection(content, 'In Progress'),
|
|
18
|
+
completed: parseSection(content, 'Completed'),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function parseSection(content, sectionName) {
|
|
23
|
+
const escaped = sectionName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
24
|
+
const match = content.match(new RegExp(`##\\s+${escaped}\\n([\\s\\S]*?)(?=\\n##|$)`, 'i'));
|
|
25
|
+
if (!match) return [];
|
|
26
|
+
|
|
27
|
+
const body = (match[1] || '').trim();
|
|
28
|
+
if (!body || /^\(clean\)/i.test(body) || /^\(empty/i.test(body) || /^\(see /i.test(body)) return [];
|
|
29
|
+
|
|
30
|
+
const tasks = [];
|
|
31
|
+
const lines = body.split('\n');
|
|
32
|
+
let current = null;
|
|
33
|
+
|
|
34
|
+
for (const rawLine of lines) {
|
|
35
|
+
const line = rawLine.trimEnd();
|
|
36
|
+
|
|
37
|
+
const taskMatch = line.match(/^- \*\*([A-Za-z][A-Za-z0-9#]*\d[a-z]?):\*\*\s*(.+)$/);
|
|
38
|
+
if (taskMatch) {
|
|
39
|
+
if (current) tasks.push(current);
|
|
40
|
+
const allTags = [...taskMatch[2].matchAll(/\[(\w+)\]/g)].map(m => m[1]);
|
|
41
|
+
const tag = allTags.includes('endgame') ? 'endgame' : (allTags[0] || null);
|
|
42
|
+
current = {
|
|
43
|
+
id: taskMatch[1],
|
|
44
|
+
title: taskMatch[2].replace(/\s*\[\w+\]/g, '').trim(),
|
|
45
|
+
tag,
|
|
46
|
+
tags: allTags,
|
|
47
|
+
claimed: null,
|
|
48
|
+
stage: null,
|
|
49
|
+
verify: null,
|
|
50
|
+
};
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const checkMatch = line.match(/^- \[[ x]\]\s+(.+)$/);
|
|
55
|
+
if (checkMatch && !current) {
|
|
56
|
+
tasks.push({ id: null, title: checkMatch[1].trim(), tag: null, claimed: null, stage: null, verify: null });
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const plainMatch = line.match(/^- (.+)$/);
|
|
61
|
+
if (plainMatch && !current && !plainMatch[1].startsWith('**')) {
|
|
62
|
+
tasks.push({ id: null, title: plainMatch[1].trim(), tag: null, claimed: null, stage: null, verify: null });
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!current) continue;
|
|
67
|
+
|
|
68
|
+
const claimMatch = line.match(/\*\*Claimed by:\*\*\s*(.+)$/) || line.match(/Claimed by:\s*(.+)$/);
|
|
69
|
+
if (claimMatch) { current.claimed = claimMatch[1].trim(); continue; }
|
|
70
|
+
|
|
71
|
+
const stageMatch = line.match(/\*\*Stage:\*\*\s*(.+)$/) || line.match(/Stage:\s*(.+)$/);
|
|
72
|
+
if (stageMatch) { current.stage = stageMatch[1].trim(); continue; }
|
|
73
|
+
|
|
74
|
+
const verifyMatch = line.match(/\*\*Verify:\*\*\s*(.+)$/) || line.match(/Verify:\s*(.+)$/);
|
|
75
|
+
if (verifyMatch) { current.verify = verifyMatch[1].trim(); continue; }
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (current) tasks.push(current);
|
|
79
|
+
return tasks;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function getTeamMemberJournal(atrisDir, memberName) {
|
|
83
|
+
const journalDir = path.join(atrisDir, 'team', memberName, 'journal');
|
|
84
|
+
if (!fs.existsSync(journalDir)) return null;
|
|
85
|
+
|
|
86
|
+
let files;
|
|
87
|
+
try {
|
|
88
|
+
files = fs.readdirSync(journalDir).filter(f => f.endsWith('.md')).sort().reverse();
|
|
89
|
+
} catch { return null; }
|
|
90
|
+
|
|
91
|
+
if (files.length === 0) return null;
|
|
92
|
+
|
|
93
|
+
const latestFile = files[0];
|
|
94
|
+
let content;
|
|
95
|
+
try { content = fs.readFileSync(path.join(journalDir, latestFile), 'utf8'); }
|
|
96
|
+
catch { return null; }
|
|
97
|
+
|
|
98
|
+
const date = latestFile.replace('.md', '');
|
|
99
|
+
const taskMatch = content.match(/\*\*Task:\*\*\s*(.+)/);
|
|
100
|
+
const deliveredMatch = content.match(/\*\*Delivered:\*\*\s*(.+)/);
|
|
101
|
+
const patternMatch = content.match(/\*\*Pattern:\*\*\s*(.+)/);
|
|
102
|
+
const learnedMatch = content.match(/\*\*Learned:\*\*\s*(.+)/);
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
date,
|
|
106
|
+
file: path.join(journalDir, latestFile),
|
|
107
|
+
task: taskMatch ? taskMatch[1].trim() : null,
|
|
108
|
+
delivered: deliveredMatch ? deliveredMatch[1].trim() : null,
|
|
109
|
+
pattern: patternMatch ? patternMatch[1].trim() : null,
|
|
110
|
+
learned: learnedMatch ? learnedMatch[1].trim() : null,
|
|
111
|
+
raw: content,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function listTeamMembers(atrisDir) {
|
|
116
|
+
const teamDir = path.join(atrisDir, 'team');
|
|
117
|
+
if (!fs.existsSync(teamDir)) return [];
|
|
118
|
+
return fs.readdirSync(teamDir).filter(name => {
|
|
119
|
+
if (name.startsWith('_') || name.startsWith('.')) return false;
|
|
120
|
+
const full = path.join(teamDir, name);
|
|
121
|
+
try { return fs.statSync(full).isDirectory(); } catch { return false; }
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function getTeamActivity(atrisDir) {
|
|
126
|
+
const members = listTeamMembers(atrisDir);
|
|
127
|
+
const activity = [];
|
|
128
|
+
for (const member of members) {
|
|
129
|
+
const journal = getTeamMemberJournal(atrisDir, member);
|
|
130
|
+
if (journal) activity.push({ member, ...journal });
|
|
131
|
+
}
|
|
132
|
+
activity.sort((a, b) => b.date.localeCompare(a.date));
|
|
133
|
+
return activity;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
module.exports = {
|
|
137
|
+
parseTodoFile,
|
|
138
|
+
parseSection,
|
|
139
|
+
getTeamMemberJournal,
|
|
140
|
+
listTeamMembers,
|
|
141
|
+
getTeamActivity,
|
|
142
|
+
};
|
package/lib/todo.js
CHANGED
|
@@ -1,204 +1,119 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
// SHIM. Same export surface as the legacy markdown parser, but reads from the
|
|
2
|
+
// SQLite task store first when ATRIS_TASK_DB=1 is set, falling back to the
|
|
3
|
+
// pure markdown parser at lib/todo-fallback.js.
|
|
4
|
+
//
|
|
5
|
+
// All 3 callers (commands/autopilot.js, commands/status.js, commands/run.js)
|
|
6
|
+
// inherit the strangler without changing their import path.
|
|
7
|
+
//
|
|
8
|
+
// When ATRIS_TASK_DB=1:
|
|
9
|
+
// parseTodo({path}) returns DB-derived tasks first; markdown rows whose
|
|
10
|
+
// title doesn't already exist in DB are appended (so import is gradual).
|
|
11
|
+
// Otherwise: behaves exactly like the old parser.
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const fallback = require('./todo-fallback');
|
|
16
|
+
|
|
17
|
+
const TASK_DB_ENABLED = process.env.ATRIS_TASK_DB === '1';
|
|
18
|
+
|
|
19
|
+
function dbToShimRow(row) {
|
|
20
|
+
const metadata = row.metadata && typeof row.metadata === 'object' ? row.metadata : {};
|
|
21
|
+
const verify = typeof metadata.verify === 'string' && metadata.verify.trim()
|
|
22
|
+
? metadata.verify.trim()
|
|
23
|
+
: null;
|
|
24
|
+
const claimed = row.claimed_by || metadata.claimed || null;
|
|
25
|
+
// Map DB row → the shape the existing consumers expect from parseTodo().
|
|
13
26
|
return {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
27
|
+
id: row.id,
|
|
28
|
+
title: row.title,
|
|
29
|
+
tag: row.tag || null,
|
|
30
|
+
tags: row.tag ? [row.tag] : [],
|
|
31
|
+
claimed,
|
|
32
|
+
stage: row.status === 'claimed' ? 'in_progress' : (metadata.stage || null),
|
|
33
|
+
verify,
|
|
34
|
+
_source: 'db',
|
|
17
35
|
};
|
|
18
36
|
}
|
|
19
37
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// New task line: - **T1:** Description or - **T1a:** Description [tag] [tag]
|
|
42
|
-
// Accepts task IDs like T1, W3b, M12c, R1, T#1 — letter(s), optional symbols, digits, optional trailing letter.
|
|
43
|
-
const taskMatch = line.match(/^- \*\*([A-Za-z][A-Za-z0-9#]*\d[a-z]?):\*\*\s*(.+)$/);
|
|
44
|
-
if (taskMatch) {
|
|
45
|
-
if (current) tasks.push(current);
|
|
46
|
-
// Capture ALL bracketed tags in the line, not just the last one. Endgame is priority.
|
|
47
|
-
const allTags = [...taskMatch[2].matchAll(/\[(\w+)\]/g)].map(m => m[1]);
|
|
48
|
-
const tag = allTags.includes('endgame') ? 'endgame' : (allTags[0] || null);
|
|
49
|
-
current = {
|
|
50
|
-
id: taskMatch[1],
|
|
51
|
-
title: taskMatch[2].replace(/\s*\[\w+\]/g, '').trim(),
|
|
52
|
-
tag,
|
|
53
|
-
tags: allTags,
|
|
54
|
-
claimed: null,
|
|
55
|
-
stage: null,
|
|
56
|
-
verify: null,
|
|
57
|
-
};
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Also support checkbox format: - [x] Description
|
|
62
|
-
const checkMatch = line.match(/^- \[[ x]\]\s+(.+)$/);
|
|
63
|
-
if (checkMatch && !current) {
|
|
64
|
-
tasks.push({
|
|
65
|
-
id: null,
|
|
66
|
-
title: checkMatch[1].trim(),
|
|
67
|
-
tag: null,
|
|
68
|
-
claimed: null,
|
|
69
|
-
stage: null,
|
|
70
|
-
verify: null,
|
|
71
|
-
});
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Plain bullet without ID: - Description
|
|
76
|
-
const plainMatch = line.match(/^- (.+)$/);
|
|
77
|
-
if (plainMatch && !current && !plainMatch[1].startsWith('**')) {
|
|
78
|
-
tasks.push({
|
|
79
|
-
id: null,
|
|
80
|
-
title: plainMatch[1].trim(),
|
|
81
|
-
tag: null,
|
|
82
|
-
claimed: null,
|
|
83
|
-
stage: null,
|
|
84
|
-
verify: null,
|
|
85
|
-
});
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (!current) continue;
|
|
90
|
-
|
|
91
|
-
// Claimed by line
|
|
92
|
-
const claimMatch = line.match(/\*\*Claimed by:\*\*\s*(.+)$/) || line.match(/Claimed by:\s*(.+)$/);
|
|
93
|
-
if (claimMatch) {
|
|
94
|
-
current.claimed = claimMatch[1].trim();
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Stage line
|
|
99
|
-
const stageMatch = line.match(/\*\*Stage:\*\*\s*(.+)$/) || line.match(/Stage:\s*(.+)$/);
|
|
100
|
-
if (stageMatch) {
|
|
101
|
-
current.stage = stageMatch[1].trim();
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
38
|
+
function dbBuckets(workspaceRoot) {
|
|
39
|
+
const taskDb = require('./task-db');
|
|
40
|
+
const db = taskDb.open();
|
|
41
|
+
const rows = taskDb.listTasks(db, { workspaceRoot, limit: 500 });
|
|
42
|
+
// Need raw source_key for merge dedup, plus the shim shape for callers.
|
|
43
|
+
const backlog = [];
|
|
44
|
+
const inProgress = [];
|
|
45
|
+
const completed = [];
|
|
46
|
+
const sourceKeys = new Set();
|
|
47
|
+
// Query directly so the shim can dedup against markdown by the strong key
|
|
48
|
+
// even if future list filters hide rows.
|
|
49
|
+
const stmt = db.prepare('SELECT id, source_key FROM tasks WHERE workspace_root = ? AND source_key IS NOT NULL');
|
|
50
|
+
for (const r of stmt.all(workspaceRoot)) sourceKeys.add(r.source_key);
|
|
51
|
+
for (const r of rows) {
|
|
52
|
+
const shaped = dbToShimRow(r);
|
|
53
|
+
if (r.status === 'open') backlog.push(shaped);
|
|
54
|
+
else if (r.status === 'claimed') inProgress.push(shaped);
|
|
55
|
+
else if (r.status === 'done' || r.status === 'failed') completed.push(shaped);
|
|
56
|
+
}
|
|
57
|
+
return { backlog, inProgress, completed, sourceKeys };
|
|
58
|
+
}
|
|
104
59
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
60
|
+
function mergeBuckets(dbBuck, mdBuck, todoPath) {
|
|
61
|
+
// Append markdown rows that aren't already in the DB. Dedup by source_key
|
|
62
|
+
// (strong: same source_file + normalized_title hash) first, and by
|
|
63
|
+
// normalized_title as a compatibility fallback for legacy markdown rows
|
|
64
|
+
// that pre-date the import path.
|
|
65
|
+
const taskDb = require('./task-db');
|
|
66
|
+
const norm = (t) => String(t || '').toLowerCase().trim().replace(/\s+/g, ' ');
|
|
67
|
+
const seenTitles = new Set();
|
|
68
|
+
const out = { backlog: [], inProgress: [], completed: [] };
|
|
69
|
+
for (const k of ['backlog', 'inProgress', 'completed']) {
|
|
70
|
+
for (const r of dbBuck[k]) { out[k].push(r); seenTitles.add(norm(r.title)); }
|
|
71
|
+
for (const r of mdBuck[k]) {
|
|
72
|
+
const sk = todoPath ? taskDb.sourceKey(todoPath, r.title) : null;
|
|
73
|
+
if (sk && dbBuck.sourceKeys && dbBuck.sourceKeys.has(sk)) continue;
|
|
74
|
+
if (seenTitles.has(norm(r.title))) continue;
|
|
75
|
+
out[k].push({ ...r, _source: 'md' });
|
|
110
76
|
}
|
|
111
77
|
}
|
|
112
|
-
|
|
113
|
-
if (current) tasks.push(current);
|
|
114
|
-
return tasks;
|
|
78
|
+
return out;
|
|
115
79
|
}
|
|
116
80
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
let
|
|
81
|
+
function parseTodo(todoPath) {
|
|
82
|
+
// Legacy pure-markdown path.
|
|
83
|
+
if (!TASK_DB_ENABLED) return fallback.parseTodoFile(todoPath);
|
|
84
|
+
|
|
85
|
+
// DB-first merged view. Workspace scope = directory containing todoPath
|
|
86
|
+
// (or its parent), so the DB stays per-repo.
|
|
87
|
+
const path = require('path');
|
|
88
|
+
const fs = require('fs');
|
|
89
|
+
const taskDb = require('./task-db');
|
|
90
|
+
let workspaceRoot;
|
|
127
91
|
try {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
92
|
+
const todoAbs = path.resolve(todoPath);
|
|
93
|
+
// typical layout: <repo>/atris/TODO.md → workspace = <repo>
|
|
94
|
+
const guess = path.dirname(path.dirname(todoAbs));
|
|
95
|
+
// Normalize via taskDb so it matches what `task add` writes.
|
|
96
|
+
workspaceRoot = fs.existsSync(guess) ? taskDb.workspaceRoot(guess) : taskDb.workspaceRoot();
|
|
132
97
|
} catch {
|
|
133
|
-
|
|
98
|
+
workspaceRoot = taskDb.workspaceRoot();
|
|
134
99
|
}
|
|
135
100
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const latestFile = files[0];
|
|
139
|
-
let content;
|
|
101
|
+
let dbBuck;
|
|
140
102
|
try {
|
|
141
|
-
|
|
142
|
-
} catch {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
// Extract key fields from journal entry
|
|
148
|
-
const taskMatch = content.match(/\*\*Task:\*\*\s*(.+)/);
|
|
149
|
-
const deliveredMatch = content.match(/\*\*Delivered:\*\*\s*(.+)/);
|
|
150
|
-
const patternMatch = content.match(/\*\*Pattern:\*\*\s*(.+)/);
|
|
151
|
-
const learnedMatch = content.match(/\*\*Learned:\*\*\s*(.+)/);
|
|
152
|
-
|
|
153
|
-
return {
|
|
154
|
-
date,
|
|
155
|
-
file: path.join(journalDir, latestFile),
|
|
156
|
-
task: taskMatch ? taskMatch[1].trim() : null,
|
|
157
|
-
delivered: deliveredMatch ? deliveredMatch[1].trim() : null,
|
|
158
|
-
pattern: patternMatch ? patternMatch[1].trim() : null,
|
|
159
|
-
learned: learnedMatch ? learnedMatch[1].trim() : null,
|
|
160
|
-
raw: content,
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Get all team members that have directories in atris/team/
|
|
166
|
-
*/
|
|
167
|
-
function listTeamMembers(atrisDir) {
|
|
168
|
-
const teamDir = path.join(atrisDir, 'team');
|
|
169
|
-
if (!fs.existsSync(teamDir)) return [];
|
|
170
|
-
|
|
171
|
-
return fs.readdirSync(teamDir)
|
|
172
|
-
.filter(name => {
|
|
173
|
-
if (name.startsWith('_') || name.startsWith('.')) return false;
|
|
174
|
-
const full = path.join(teamDir, name);
|
|
175
|
-
try { return fs.statSync(full).isDirectory(); } catch { return false; }
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Get team activity: latest journal entry per member
|
|
181
|
-
*/
|
|
182
|
-
function getTeamActivity(atrisDir) {
|
|
183
|
-
const members = listTeamMembers(atrisDir);
|
|
184
|
-
const activity = [];
|
|
185
|
-
|
|
186
|
-
for (const member of members) {
|
|
187
|
-
const journal = getTeamMemberJournal(atrisDir, member);
|
|
188
|
-
if (journal) {
|
|
189
|
-
activity.push({ member, ...journal });
|
|
190
|
-
}
|
|
103
|
+
dbBuck = dbBuckets(workspaceRoot);
|
|
104
|
+
} catch (e) {
|
|
105
|
+
// If sqlite blew up (missing in node, perms), don't break the legacy path.
|
|
106
|
+
if (process.env.ATRIS_DEBUG) console.error('[todo shim] db read failed:', e.message);
|
|
107
|
+
return fallback.parseTodoFile(todoPath);
|
|
191
108
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
activity.sort((a, b) => b.date.localeCompare(a.date));
|
|
195
|
-
return activity;
|
|
109
|
+
const mdBuck = fallback.parseTodoFile(todoPath);
|
|
110
|
+
return mergeBuckets(dbBuck, mdBuck, todoPath);
|
|
196
111
|
}
|
|
197
112
|
|
|
198
113
|
module.exports = {
|
|
199
114
|
parseTodo,
|
|
200
|
-
parseSection,
|
|
201
|
-
getTeamMemberJournal,
|
|
202
|
-
listTeamMembers,
|
|
203
|
-
getTeamActivity,
|
|
115
|
+
parseSection: fallback.parseSection,
|
|
116
|
+
getTeamMemberJournal: fallback.getTeamMemberJournal,
|
|
117
|
+
listTeamMembers: fallback.listTeamMembers,
|
|
118
|
+
getTeamActivity: fallback.getTeamActivity,
|
|
204
119
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atris",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.14.0",
|
|
4
4
|
"description": "Atris — an operating system for intelligence. Integrates with any agent.",
|
|
5
5
|
"main": "bin/atris.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin/",
|
|
11
|
-
"cli
|
|
11
|
+
"cli/*.py",
|
|
12
12
|
"commands/",
|
|
13
13
|
"utils/",
|
|
14
14
|
"lib/",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|