imdone-core 1.50.4 → 1.52.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.
@@ -14,8 +14,11 @@ docker run \
14
14
 
15
15
  docker exec git-remote mkdir /home/git/authorized_keys
16
16
 
17
- # TODO: Generate a key in the container and use that instead of copying the key from the host
17
+ # TODO Generate a key in the container and use that instead of copying the key from the host
18
18
  # Update to use `GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example" git clone example`
19
+ # <!--
20
+ # order:0
21
+ # -->
19
22
 
20
23
 
21
24
  docker cp ~/.ssh/id_rsa.pub git-remote:/home/git/authorized_keys
@@ -9,6 +9,19 @@ const path = require('path');
9
9
  const MarkdownIt = require('markdown-it')
10
10
  let _platform = process.platform
11
11
 
12
+ function extractWikilinkTopics(markdown) {
13
+ const wikilinkRegex = /\[\[([\w\s/]+)(\|([\w\s/]+))?\]\]/g; // Match [[Topic]] or [[Topic|Display Text]]
14
+ const topics = [];
15
+ let match;
16
+
17
+ // Use RegExp.exec to iterate through all matches
18
+ while ((match = wikilinkRegex.exec(markdown)) !== null) {
19
+ topics.push(match[1].trim()); // Extract the topic (first capture group) and trim whitespace
20
+ }
21
+
22
+ return topics;
23
+ }
24
+
12
25
  function getRenderer(projectPath) {
13
26
  const md = new MarkdownIt({html: true, breaks: true})
14
27
 
@@ -72,9 +85,9 @@ module.exports = {
72
85
  _platform = platform
73
86
  },
74
87
  renderMarkdown (markdown, projectPath) {
75
- const md = getRenderer()
76
88
  markdown = renderCancelledTasks(markdown)
77
89
  return getRenderer(projectPath).render(markdown)
78
90
  },
91
+ extractWikilinkTopics,
79
92
  removeMD
80
93
  }
@@ -18,6 +18,9 @@ module.exports = class ReadStreamCodeParser extends ReadStreamTaskParser {
18
18
  async init() {
19
19
  const code = await streamToString(this.readStream)
20
20
  // TODO Getting tokens from lists should be done higher up in the controller
21
+ // <!--
22
+ // order:-10
23
+ // -->
21
24
  const tokens = this.lists.filter(list => !list.filter).map(list => list.name)
22
25
  this.cards = this.parseCards(code, tokens)
23
26
  }
@@ -33,7 +36,10 @@ module.exports = class ReadStreamCodeParser extends ReadStreamTaskParser {
33
36
  Object.keys(comments).forEach((comment) => {
34
37
  const { begin, end, content } = comments[comment];
35
38
  const line = begin;
36
- const lastLine = end; // DOING: lastLine should not be - 1
39
+ const lastLine = end; // DOING lastLine should not be - 1
40
+ // <!--
41
+ // order:0
42
+ // -->
37
43
  const lines = content.split('\n');
38
44
 
39
45
  // Check if the comment contains "TODO"
@@ -7,7 +7,9 @@ module.exports = class FileSystemProjectReader {
7
7
  // BACKLOG ## Load the config file
8
8
  // #adapter
9
9
  // [lib/adapters/readers/FileSystemProjectReader.js](lib/adapters/readers/FileSystemProjectReader.js)
10
- // <!-- epic:"Release 2.0" -->
10
+ // <!-- epic:"Release 2.0"
11
+ // order:-590
12
+ // -->
11
13
  const files = await this.getFilesFromDirectory(projectPath)
12
14
 
13
15
  // BACKLOG ## Parse project files
@@ -18,7 +20,9 @@ module.exports = class FileSystemProjectReader {
18
20
  // - After tasks are parsed trim the description appropriately and look for Check style tasks in what's left of the description
19
21
  // #adapter
20
22
  // [lib/adapters/readers/FileSystemProjectReader.js](lib/adapters/readers/FileSystemProjectReader.js)
21
- // <!-- epic:"Release 2.0" -->
23
+ // <!-- epic:"Release 2.0"
24
+ // order:-600
25
+ // -->
22
26
 
23
27
  }
24
28
 
package/lib/card.js CHANGED
@@ -44,6 +44,10 @@ module.exports = function newCard(task, _project, dontParse) {
44
44
  this.innerInterpretedContent = value
45
45
  }
46
46
 
47
+ // TODO This should take an object of project level data and make it available to the card
48
+ // <!--
49
+ // order:-120
50
+ // -->
47
51
  init(totals = project.totals) {
48
52
  this.updateLastLine()
49
53
  this.totals = totals
@@ -58,6 +62,9 @@ module.exports = function newCard(task, _project, dontParse) {
58
62
  onTaskUpdate() {
59
63
  // TODO We should be mapping to the imdone-api task
60
64
  // #imdone-1.45.0
65
+ // <!--
66
+ // order:-20
67
+ // -->
61
68
  const interpretedContent = pluginManager.onTaskUpdate(this)
62
69
  if (interpretedContent && interpretedContent.length > 0) {
63
70
  this.interpretedContent = interpretedContent
@@ -126,11 +133,16 @@ module.exports = function newCard(task, _project, dontParse) {
126
133
  'projectPath',
127
134
  'relPath',
128
135
  'fullPath',
129
- 'totals'].sort()
136
+ 'totals',
137
+ 'topics'].sort()
130
138
  ),
131
139
  }
132
140
  }
133
141
 
142
+ // TODO Add isInCodeFile property to card
143
+ // <!--
144
+ // order:-115
145
+ // -->
134
146
  initData() {
135
147
  const props = { ...this.props, content: CONTENT_TOKEN }
136
148
  const computed = { ...this.computed }
package/lib/config.js CHANGED
@@ -176,7 +176,7 @@ class Config {
176
176
  }
177
177
 
178
178
  get archiveCompleted() {
179
- return _get(this, 'settings.cards.archiveCompleted', false)
179
+ return _get(this, 'settings.cards.archiveCompleted')
180
180
  }
181
181
 
182
182
  get tokenPrefix() {
package/lib/file.js CHANGED
@@ -830,7 +830,10 @@ File.prototype.modifyDescription = function (task, config) {
830
830
  let description = task.description.map(
831
831
  (desc) => `${spaces}${descriptionStartsWith}${desc}`
832
832
  )
833
- // BACKLOG:-30 Allow this to pad for code files as well
833
+ // BACKLOG Allow this to pad for code files as well
834
+ // <!--
835
+ // order:-620
836
+ // -->
834
837
  description = File.padDescription(description, task.beforeText).join(lineEnd)
835
838
  if (taskContentLines.length === 0 && description.length > 0) {
836
839
  beforeDescContent += description + lineEnd
@@ -885,7 +888,10 @@ File.prototype.extractTaskWithDescription = function ({
885
888
  var self = this
886
889
  const lang = this.getLang()
887
890
  let description = []
888
- // BACKLOG:-230 ## add beforeText for code files
891
+ // BACKLOG ## add beforeText for code files
892
+ // <!--
893
+ // order:-630
894
+ // -->
889
895
  const beforeText = this.getBeforeText(line, pos)
890
896
  let { rawTaskContentLines, taskContentLines, isWrappedWithCardTag } = this.getTaskContent({
891
897
  config,
@@ -1100,7 +1106,7 @@ File.prototype.removeTask = function (task) {
1100
1106
  }
1101
1107
 
1102
1108
  File.prototype.ignoreCodeBlocks = function () {
1103
- // BACKLOG:-100 This is not used, but we need a way to ignore tasks in code blocks. Maybe save position ranges
1109
+ // BACKLOG This is not used, but we need a way to ignore tasks in code blocks. Maybe save position ranges
1104
1110
  // ```javascript
1105
1111
  // var cleanContent = this.content
1106
1112
  // var replacer = function (block) {
@@ -1115,6 +1121,9 @@ File.prototype.ignoreCodeBlocks = function () {
1115
1121
  // }
1116
1122
  // return cleanContent
1117
1123
  // ```
1124
+ // <!--
1125
+ // order:-640
1126
+ // -->
1118
1127
  }
1119
1128
 
1120
1129
  File.prototype.isMarkDownFile = function () {
package/lib/list.js CHANGED
@@ -1,7 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  const uniqid = require('uniqid')
4
- // BACKLOG:10 Create list groups to show and hide for projects/repos. gh:96 id:11
4
+ // BACKLOG Create list groups to show and hide for projects/repos. gh:96 id:11
5
+ // <!--
6
+ // order:-610
7
+ // -->
5
8
 
6
9
  /**
7
10
  * Description
@@ -50,17 +50,17 @@ module.exports = function (repo, defaultSettings = defaultSettingsObject) {
50
50
  delete config.settings.defaultList
51
51
  }
52
52
 
53
- if (!config.settings.cards.defaultList) {
53
+ if (config.settings.cards.defaultList === undefined) {
54
54
  config.settings.cards.defaultList = lists ? lists[0] : ''
55
55
  }
56
56
 
57
57
  // archiveCompleted
58
58
  if (config.settings.cards.archiveCompleted === undefined) {
59
- config.settings.cards.archiveCompleted = false
59
+ config.settings.cards.archiveCompleted = true
60
60
  }
61
61
 
62
62
  // archiveFolder
63
- if (!config.settings.cards.archiveFolder) {
63
+ if (config.settings.cards.archiveFolder === undefined) {
64
64
  config.settings.cards.archiveFolder = config.settings.journalPath ? _path.join(config.settings.journalPath, 'archive') : 'archive'
65
65
  }
66
66
 
@@ -106,11 +106,11 @@ module.exports = function (repo, defaultSettings = defaultSettingsObject) {
106
106
  delete config.settings.doneList
107
107
  }
108
108
  // Set up default doneList
109
- if (!config.settings.cards.doneList) {
109
+ if (config.settings.cards.doneList === undefined) {
110
110
  config.settings.cards.doneList = lists ? lists[lists.length - 1] : ''
111
111
  }
112
112
  // Add name
113
- if (!config.settings.name) {
113
+ if (config.settings.name === undefined) {
114
114
  config.settings.name = _path.basename(path)
115
115
  }
116
116
 
@@ -138,7 +138,7 @@ module.exports = function (repo, defaultSettings = defaultSettingsObject) {
138
138
  })
139
139
 
140
140
  // Make sure kudosProbability is set
141
- if (!config.settings.kudosProbability && config.settings.kudosProbability !== 0) {
141
+ if (config.settings.kudosProbability === undefined) {
142
142
  config.settings.kudosProbability = 0.33
143
143
  }
144
144
 
@@ -251,7 +251,10 @@ function mixin(repo, fs = require('fs')) {
251
251
  }
252
252
 
253
253
  repo.loadConfig = function (cb) {
254
- // BACKLOG:-650 If a config is bad move it to config.json.bak and save a new one with defaults gh:2 id:9 +enhancement +standup +chore
254
+ // BACKLOG If a config is bad move it to config.json.bak and save a new one with defaults gh:2 id:9 +enhancement +standup +chore
255
+ // <!--
256
+ // order:-670
257
+ // -->
255
258
  cb = tools.cb(cb)
256
259
  repo.loadIgnore()
257
260
  // new
@@ -8,7 +8,10 @@ var fsStore = require('./repo-fs-store'),
8
8
 
9
9
  module.exports = mixin
10
10
 
11
- // BACKLOG:-280 Only emit file.update if the file checksum has changed
11
+ // BACKLOG Only emit file.update if the file checksum has changed
12
+ // <!--
13
+ // order:-650
14
+ // -->
12
15
  function mixin(repo, fs = require('fs')) {
13
16
  repo = fsStore(repo, fs)
14
17
  var _refresh = repo.refresh
@@ -150,6 +153,9 @@ function mixin(repo, fs = require('fs')) {
150
153
  const isFile = File.isFile(file)
151
154
  // BACKLOG ## Handle the case where the file is not in the repo
152
155
  // #urgent #1.12.0
156
+ // <!--
157
+ // order:-660
158
+ // -->
153
159
  if (isFile && stat.mtime <= file.getModifiedTime()) {
154
160
  // console.log("File update already applied. Change ignored.")
155
161
  return
@@ -28,7 +28,7 @@ module.exports = class ExtensionPlugin extends Plugin {
28
28
  }
29
29
 
30
30
  getCardProperties(task) {
31
- return this.cardPropertiesFunction(task)
31
+ return this.cardPropertiesFunction(task, this.project)
32
32
  }
33
33
 
34
34
  getCardActions(task) {
package/lib/project.js CHANGED
@@ -15,7 +15,7 @@ const exec = require('child_process').exec
15
15
  const fastSort = require('fast-sort/dist/sort.js')
16
16
  const Task = require('./task')
17
17
  const eol = require('eol')
18
- const { renderMarkdown } = require('./adapters/markdown')
18
+ const { renderMarkdown, extractWikilinkTopics } = require('./adapters/markdown')
19
19
 
20
20
  function calculateTotals(lists) {
21
21
  const totals = {}
@@ -48,6 +48,7 @@ module.exports = class WorkerProject extends Project {
48
48
  this.repo = repo
49
49
  this.innerFilter = ''
50
50
  this.fileGateway = fileGateway
51
+ this._updatedAt = undefined
51
52
  }
52
53
 
53
54
  init(cb) {
@@ -88,7 +89,10 @@ module.exports = class WorkerProject extends Project {
88
89
  if (!cb) return promise
89
90
  }
90
91
 
91
- // HACK:-50 To handle circular dependency issue with file
92
+ // HACK To handle circular dependency issue with file
93
+ // <!--
94
+ // order:0
95
+ // -->
92
96
  toJSON() {
93
97
  return { path: this.path }
94
98
  }
@@ -96,6 +100,7 @@ module.exports = class WorkerProject extends Project {
96
100
  async toImdoneJSON() {
97
101
  this.pluginManager.initDevMode()
98
102
  console.time('toJSON time')
103
+ this._updatedAt = new Date()
99
104
  const totals = calculateTotals(
100
105
  this.getLists({
101
106
  populateFiltered: true,
@@ -165,6 +170,10 @@ module.exports = class WorkerProject extends Project {
165
170
  if (this.pluginManager) this.pluginManager.destroyPlugins()
166
171
  }
167
172
 
173
+ get allTopics() {
174
+ return [...this.repo.allTopics]
175
+ }
176
+
168
177
  get allTags() {
169
178
  return [...this.repo.allTags]
170
179
  }
@@ -195,6 +204,10 @@ module.exports = class WorkerProject extends Project {
195
204
  return getIsoDateWithOffset()
196
205
  }
197
206
 
207
+ get updatedAt() {
208
+ return this._updatedAt
209
+ }
210
+
198
211
  removeList(list) {
199
212
  this.repo.removeList(list)
200
213
  }
@@ -232,6 +245,7 @@ module.exports = class WorkerProject extends Project {
232
245
  ...new Set(queryProps),
233
246
  ...[...this.repo.metaKeys].map(key => `allMeta.${key}`),
234
247
  ...[...this.repo.metaKeys].map(key => `meta.${key}`),
248
+ ...this.allTopics,
235
249
  ...this.allTags,
236
250
  ...this.allContexts,
237
251
  ]
@@ -789,4 +803,8 @@ module.exports = class WorkerProject extends Project {
789
803
  renderMarkdown(content) {
790
804
  return renderMarkdown(content, this.path)
791
805
  }
806
+
807
+ extractWikilinkTopics(markdown) {
808
+ return extractWikilinkTopics(markdown)
809
+ }
792
810
  }
package/lib/repository.js CHANGED
@@ -68,6 +68,7 @@ function Repository(_path, config) {
68
68
  this.allMeta = {}
69
69
  this.metaKeys = new Set()
70
70
  this.allTags = new Set()
71
+ this.allTopics = new Set()
71
72
  this.allContexts = new Set()
72
73
  }
73
74
 
@@ -85,6 +86,11 @@ Repository.prototype.refresh = function (cb) {
85
86
  }
86
87
  this.config = config
87
88
  this.files = []
89
+ this.allMeta = {}
90
+ this.metaKeys = new Set()
91
+ this.allTags = new Set()
92
+ this.allTopics = new Set()
93
+ this.allContexts = new Set()
88
94
  this.readFiles((err, files) => {
89
95
  if (err) {
90
96
  this.emit('initialized', { ok: false })
@@ -170,6 +176,7 @@ Repository.prototype.createListeners = function () {
170
176
  self.saveConfig()
171
177
  }
172
178
  Object.keys(task.allMeta).forEach(key => self.metaKeys.add(key))
179
+ task.topics.forEach(topic => self.allTopics.add(topic))
173
180
  task.allTags.forEach(tag => self.allTags.add(tag))
174
181
  task.allContext.forEach(context => self.allContexts.add(context))
175
182
  self.allMeta = self.addAllMeta(task.allMeta)
@@ -629,7 +636,10 @@ Repository.prototype.readFile = function (file, cb) {
629
636
  if (!/\.\.(\/|\\)/.test(filePath)) {
630
637
  this.readFileContent(file, (err, file) => {
631
638
  if (err) return cb(new Error('Unable to read file:' + filePath))
632
- // BACKLOG:-40 Allow user to assign a module for content transformation
639
+ // BACKLOG Allow user to assign a module for content transformation
640
+ // <!--
641
+ // order:-800
642
+ // -->
633
643
  file.checksum = checksum(file.getContent())
634
644
  file.updated = currentChecksum !== file.checksum
635
645
  if (file.updated)
@@ -914,7 +924,10 @@ Repository.prototype.moveTasksBetweenLists = function(oldName, newName, cb) {
914
924
  }
915
925
  })
916
926
 
917
- // BACKLOG:-730 Let's use saveModifiedFiles here id:15 gh:100 +fix
927
+ // BACKLOG Let's use saveModifiedFiles here id:15 gh:100 +fix
928
+ // <!--
929
+ // order:-810
930
+ // -->
918
931
 
919
932
  this.moving = true
920
933
  if (modifyTasks.length > 0) {
package/lib/task.js CHANGED
@@ -12,7 +12,8 @@ var _clone = require('lodash.clone'),
12
12
  lineEnd = String(eol.auto),
13
13
  fastSort = require('fast-sort/dist/sort.js'),
14
14
  { escapeRegExp } = require('./tools'),
15
- cheerio = require('cheerio');
15
+ cheerio = require('cheerio'),
16
+ { extractWikilinkTopics } = require('./adapters/markdown');
16
17
 
17
18
  const {
18
19
  CHECK_REGEX,
@@ -104,6 +105,7 @@ class Task {
104
105
  this.metaKeys = Object.keys(this.allMeta)
105
106
  this.progress = this.getProgress()
106
107
  this.content = this.getContent()
108
+ this.topics = extractWikilinkTopics(this.content)
107
109
  }
108
110
 
109
111
  issueNumberRegExp() {
@@ -386,7 +388,10 @@ Task.prototype.getTagPrefix = function () {
386
388
  }
387
389
 
388
390
  Task.prototype.addToLastCommentInContent = Task.addToLastCommentInContent = function (content, toAdd, newLine) {
389
- // BACKLOG:-220 respect padding of task prefix for list items
391
+ // BACKLOG respect padding of task prefix for list items
392
+ // <!--
393
+ // order:-680
394
+ // -->
390
395
  let prefix = newLine ? lineEnd : ' '
391
396
  const commentRegex = /<!--([\s\S]*?)-->/gm
392
397
  let result, lastIndex, index
@@ -523,7 +528,10 @@ Task.removeContext = function (text) {
523
528
  }
524
529
 
525
530
  Task.prototype.updateContext = function () {
526
- // BACKLOG:-900 implement updateContext id:1 gh:124
531
+ // BACKLOG implement updateContext id:1 gh:124
532
+ // <!--
533
+ // order:-690
534
+ // -->
527
535
  var self = this
528
536
  if (this.context) {
529
537
  let text = Task.removeContext(this.text)
@@ -700,7 +708,10 @@ Task.prototype.getList = function () {
700
708
  * @method getText
701
709
  * @return text
702
710
  */
703
- // BACKLOG:-160 make this use config.getMetaSep
711
+ // BACKLOG make this use config.getMetaSep
712
+ // <!--
713
+ // order:-700
714
+ // -->
704
715
  Task.prototype.getText = function (opts, text) {
705
716
  if (text === undefined) text = this.text
706
717
  if (opts) {
package/lib/tools.js CHANGED
@@ -4,7 +4,6 @@ var _isFunction = require('lodash.isfunction'),
4
4
  _noop = require('lodash.noop'),
5
5
  crypto = require('crypto'),
6
6
  _path = require('path'),
7
- markdown = require('markdown-it')().use(require('markdown-it-checkbox')),
8
7
  fastSort = require('fast-sort/dist/sort.js'),
9
8
  eol = require('eol'),
10
9
  max_bytes = 512
@@ -89,18 +88,6 @@ function isBinaryCheck(bytes, size) {
89
88
 
90
89
  module.exports = {
91
90
  escapeRegExp: require('escape-string-regexp'),
92
- marked: function (content) {
93
- return markdown.render(content)
94
- },
95
- parseMD: function (content) {
96
- return markdown.parse(content, {})
97
- },
98
-
99
- /**
100
- * Description
101
- * @method userHome
102
- * @return LogicalExpression
103
- */
104
91
  userHome: function () {
105
92
  return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE
106
93
  },
@@ -0,0 +1,6 @@
1
+ // TODO Add a function that returns the imdone url for vscode and obsidian plugins
2
+ // <!--
3
+ // created:2025-01-11T20:20:08.348Z
4
+ // sid:wmr_a0ikOY39kInkmudPa
5
+ // order:-110
6
+ // -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imdone-core",
3
- "version": "1.50.4",
3
+ "version": "1.52.0",
4
4
  "description": "imdone-core",
5
5
  "main": "index.js",
6
6
  "scripts": {