intent 0.7.1 → 0.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a78826427e690ed80d21f63d75c009a652d8f7e6152250a0259d21af5ec36d2
4
- data.tar.gz: 04c84e824a0787fed413ca28155143e407d322a8a5dd4dac76e0a14ee569a790
3
+ metadata.gz: eceb2c98af31fff1168ee446ea327a674c510e96d5bcfb948cae895e391a8399
4
+ data.tar.gz: a8225ec76a08ba859b7f8abff5729527e0426e51fff1757c26e00a63f5b5a9af
5
5
  SHA512:
6
- metadata.gz: 61ed11963ba4317356bdfef7d2213fe1f1b2b29153697a34c2d6bd2ce5a09a7f61c12a296c50879909f7f650b556ee7d4f0bce0ce11fc5de891c4a140264f546
7
- data.tar.gz: 79ba7a74906c8607edffeafc5d8555afe5853212d47b7253f8d2788567d13e4a843234a3d6934adfc1118315f3ac513e6567a5056aad1748497b73f74babe452
6
+ metadata.gz: 7151b6b4e09485ade42fc3dc8756aeaf933d72b96acdb5d216764866d9cf52dd04cfacb828bc4f8498e2a5d90397d7db30add5ae44f3370afb0f9c5916f24765
7
+ data.tar.gz: fb6b9209b34d67417a232b68e2a02dea9faf99e822252becc5d1b7dfc5a6fad5c8885ba4050258a587abc6e7afdc366e97afaf10be0ebbb768e45f2ba014987d
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Intent
2
2
 
3
- Automation engine with todo.txt
3
+ > **Automation engine with todo.txt**
4
4
 
5
5
  This tool is mired deep in the obscurity and pedantry of the text-based computing culture that originated in the 1970s and still continues today. You probably don’t want to use this.
6
6
 
@@ -16,6 +16,10 @@ gem install intent
16
16
  intent help
17
17
  ```
18
18
 
19
+ ## The ledger concept
20
+
21
+ Docs and an essay about managing text-based computational ledgers ‘coming soon’ (eventually).
22
+
19
23
  ## Copyright & License
20
24
 
21
25
  Copyright 2024 Mark Rickerby <https://maetl.net>.
data/bin/project ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ path = __FILE__
3
+ while File.symlink?(path)
4
+ path = File.expand_path(File.readlink(path), File.dirname(path))
5
+ end
6
+ $:.unshift(File.join(File.dirname(File.expand_path(path)), '..', 'lib'))
7
+
8
+ require 'intent'
9
+
10
+ Intent::Dispatcher.exec_command(:project, ARGV.dup)
@@ -0,0 +1,32 @@
1
+ module Intent
2
+ class Args
3
+ def initialize(input)
4
+ @arity = input.length
5
+
6
+ unless empty?
7
+ case @arity
8
+ when 1 then interpret_args_unary(input[0])
9
+ when 2 then interpret_args_binary(input[0], input[1])
10
+ when 3 then interpret_args_ternary(input[0], input[1], input[2])
11
+ end
12
+ end
13
+ end
14
+
15
+ def empty?
16
+ @arity == 0
17
+ end
18
+
19
+ private
20
+
21
+ def interpret_args_unary(arg1)
22
+
23
+ end
24
+
25
+ def interpret_args_binary(arg1, arg2)
26
+ end
27
+
28
+ def interpret_args_ternary(arg1, arg2, arg3)
29
+
30
+ end
31
+ end
32
+ end
@@ -1,8 +1,17 @@
1
1
  module Intent
2
2
  module Commands
3
- class Intent
3
+ class Intent < Base
4
4
  def run(args, output)
5
- output.puts args
5
+ if args.empty?
6
+ print_help(output)
7
+ else
8
+ case args.first.to_sym
9
+ when :help
10
+ print_help(output)
11
+ else
12
+ raise Core::Errors::COMMAND_NOT_FOUND
13
+ end
14
+ end
6
15
  end
7
16
  end
8
17
  end
@@ -1,5 +1,3 @@
1
- require 'tty-reader'
2
-
3
1
  module Intent
4
2
  module Commands
5
3
  class Inventory < Base
@@ -28,6 +26,12 @@ module Intent
28
26
  when :folder then assign_folder(args, output)
29
27
  when :box then assign_box(args, output)
30
28
  end
29
+ # CONCEPT:
30
+ # Verbs::Assign.invoke_rewrite()
31
+ # verbs.assign.invoke_rewrite(documents.inventory, noun)
32
+ when :sync then sync_inventory(args, output)
33
+ else
34
+ raise Errors:COMMAND_NOT_FOUND
31
35
  end
32
36
  end
33
37
  end
@@ -205,6 +209,11 @@ module Intent
205
209
  box.projects.concat(details[:projects])
206
210
  documents.inventory.save!
207
211
  end
212
+
213
+ def sync_inventory(args, output)
214
+ result = documents.inventory.sync!
215
+ output.puts "Sync inventory result: #{result}"
216
+ end
208
217
  end
209
218
  end
210
219
  end
@@ -0,0 +1,91 @@
1
+ module Intent
2
+ module Commands
3
+ class Project < Projects
4
+ def run(args, output)
5
+ if args.empty?
6
+ print_help(output)
7
+ else
8
+ case args.first.to_sym
9
+ when :help
10
+ print_help(output)
11
+ when :link
12
+ if args[1].nil?
13
+ # launch into projects selection?
14
+ raise "Need to link to a noun at this stage, sorry"
15
+ else
16
+ case args[1].to_sym
17
+ when :notes then link_notes(args, output)
18
+ else
19
+ raise "Noun not implemented"
20
+ end
21
+ end
22
+ else
23
+ raise Errors:COMMAND_NOT_FOUND
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def link_notes(args, output, needs_assign=false)
31
+ prompt = TTY::Prompt.new
32
+
33
+ project = if args.last.start_with?('+')
34
+ # args.last
35
+ # if documents.working_directory.is_linked?
36
+ # documents.working_directory.project
37
+ # else
38
+ # end
39
+ raise "Good idea and should work but not implemented properly, sorry"
40
+ else
41
+ # TODO: need to test if working_directory is documents_dir
42
+ #
43
+ if documents.working_directory.is_linked?
44
+ documents.working_directory.project
45
+ else
46
+ needs_assign = true
47
+ p_name = prompt.select('assign directory to project:', documents.projects.all_tokens)
48
+ p_id = prompt.ask('id for this directory:', default: generate_id)
49
+ p_name
50
+ end
51
+ end
52
+
53
+ if needs_assign
54
+ c_id = documents.inventory.local_computer_id
55
+ documents.projects.add_directory!(documents.working_directory.path, p_name, p_id, c_id)
56
+ end
57
+
58
+ project_ref = project.sub('+', '')
59
+
60
+ # Symlink done using maetl local notes convention, this could be improved
61
+ # and made more flexible. Would also be good to delegate this outside
62
+ # of the UI routine link_notes()
63
+ target_path = File.join(Env.documents_dir, project.sub('+', ''), 'notes.md')
64
+
65
+ if File.exist?(target_path)
66
+ # TODO: use directory instance given by input filtering so that
67
+ # operations can work on both working dir and a path provided in the UI
68
+ symbolic_path = File.join(documents.working_directory.path, 'NOTES.md')
69
+ File.symlink(target_path, symbolic_path)
70
+
71
+ # ignore_path = File.join(documents.working_directory.path, '.gitignore')
72
+ # if File.exist?(ignore_path)
73
+ # unless File.read(ignore_path).to_s.include?('NOTES.md')
74
+ # File.write(ignore_path, "NOTES.md\n", mode: 'a+')
75
+ # end
76
+ # end
77
+ else
78
+ output.puts "#{project} does not have notes"
79
+ end
80
+
81
+ # output.puts Dir.pwd
82
+ # output.puts ::Intent::Env.documents_dir
83
+ # output.puts ::Intent::Env.computer_serial
84
+ # Check if current working directory is a linked directory
85
+ #item = documents.projects.linked_directory(Dir.pwd)
86
+ #output.puts item
87
+ #File.symlink("DOCUMENT_DIR/project-name/notes.md", "Projects/project-name/NOTES.md")
88
+ end
89
+ end
90
+ end
91
+ end
@@ -1,5 +1,3 @@
1
- require 'readline'
2
-
3
1
  module Intent
4
2
  module Commands
5
3
  class Projects < Base
@@ -14,8 +12,10 @@ module Intent
14
12
  documents.projects.all.each do |task|
15
13
  output.puts task.highlight_as_project
16
14
  end
17
- when :add
18
- add_project(args, output)
15
+ when :add then add_project(args, output)
16
+ when :sync then sync_project(args, output)
17
+ else
18
+ raise Errors:COMMAND_NOT_FOUND
19
19
  end
20
20
  end
21
21
  end
@@ -29,6 +29,11 @@ module Intent
29
29
  name = "+#{name}" unless name.start_with?('+')
30
30
  output.puts name
31
31
  end
32
+
33
+ def sync_project(args, output)
34
+ result = documents.projects.sync!
35
+ output.puts "Sync projects result: #{result}"
36
+ end
32
37
  end
33
38
  end
34
39
  end
@@ -3,7 +3,7 @@ require 'intent/commands/errors'
3
3
  require 'intent/commands/intent'
4
4
  require 'intent/commands/todo'
5
5
  require 'intent/commands/projects'
6
- #require 'intent/commands/project'
6
+ require 'intent/commands/project'
7
7
  #require 'intent/commands/ideas'
8
8
  #require 'intent/commands/idea'
9
9
  require 'intent/commands/inventory'
@@ -0,0 +1,37 @@
1
+ module Intent
2
+ module Core
3
+ class Directory
4
+ attr_reader :path
5
+
6
+ def initialize(path, projects)
7
+ @path = path
8
+ @ledger = projects
9
+ @record = projects.all.find { |d| d.tags[:is] == 'directory' && d.text == @path }
10
+ end
11
+
12
+ def project
13
+ record.projects.first
14
+ end
15
+
16
+ def is_linked?
17
+ !record.nil? && record.projects.any?
18
+ end
19
+
20
+ def assign!(project)
21
+ if record.nil?
22
+ @record = Record.new("#{Date.today} #{@path} is:directory type:#{type} sku:#{sku}")
23
+ ledger.append(record)
24
+ else
25
+ record.projects << project
26
+ end
27
+
28
+ ledger.save!
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :ledger
34
+ attr_reader :record
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,17 @@
1
+ module Intent
2
+ module Core
3
+ class Documents
4
+ attr_reader :projects
5
+ attr_reader :inventory
6
+ attr_reader :inbox
7
+ attr_reader :working_directory
8
+
9
+ def initialize
10
+ @projects = Projects.new("#{Intent::Env.documents_dir}/projects.txt")
11
+ @inventory = Inventory.new("#{Intent::Env.documents_dir}/inventory.txt")
12
+ @inbox = Inbox.new("#{Intent::Env.documents_dir}/todo.txt")
13
+ @working_directory = Directory.new(Dir.pwd, @projects)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,29 @@
1
+ module Intent
2
+ module Core
3
+ class Inbox
4
+ attr_reader :list
5
+
6
+ def initialize(db_path)
7
+ @list = List.new(db_path)
8
+ end
9
+
10
+ def all
11
+ @list.by_not_done
12
+ end
13
+
14
+ def focused
15
+ @list.by_context('@focus').by_not_done
16
+ end
17
+
18
+ def focused_projects
19
+ focused.map { |t| t.projects }.flatten.uniq
20
+ end
21
+
22
+ def add_line!(line)
23
+ record = Record.new("#{Date.today} #{line}")
24
+ @list.prepend(record)
25
+ @list.save!
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,101 @@
1
+ module Intent
2
+ module Core
3
+ class Inventory
4
+ attr_reader :list
5
+ attr_reader :ledger_path
6
+
7
+ def initialize(db_path)
8
+ @ledger_path = db_path
9
+ @list = List.new(db_path)
10
+ end
11
+
12
+ def all
13
+ list.by_not_done
14
+ end
15
+
16
+ def folder_by_id(id)
17
+ all.find { |i| i.tags[:is] == 'folder' && i.tags[:id] == id }
18
+ end
19
+
20
+ def folders
21
+ all.filter { |i| i.tags[:is] == 'folder' }
22
+ end
23
+
24
+ def items_in(id)
25
+ all.filter { |i| i.tags[:in] == id }
26
+ end
27
+
28
+ def unassigned_folders
29
+ all.filter { |i| i.tags[:is] == 'folder' && i.projects.empty? }
30
+ end
31
+
32
+ def assigned_folders
33
+ all.filter { |i| i.tags[:is] == 'folder' && i.projects.any? }
34
+ end
35
+
36
+ def boxes
37
+ all.filter { |i| i.tags[:is] == 'box' }
38
+ end
39
+
40
+ def unassigned_boxes
41
+ all.filter { |i| i.tags[:is] == 'box' && i.projects.empty? }
42
+ end
43
+
44
+ def assigned_boxes
45
+ all.filter { |i| i.tags[:is] == 'box' && i.projects.any? }
46
+ end
47
+
48
+ def units_of(noun)
49
+ all.filter { |i| i.tags[:is] == 'unit' && i.tags[:type] == noun.to_s }
50
+ end
51
+
52
+ def local_computer_id
53
+ all.find { |i| i.tags[:is] == 'computer' && i.tags[:serial] == Env.computer_serial }.tags[:id]
54
+ end
55
+
56
+ def add_unit!(description, type, sku)
57
+ record = Record.new("#{Date.today} #{description} is:unit type:#{type} sku:#{sku}")
58
+ @list.append(record)
59
+ @list.save!
60
+ end
61
+
62
+ def add_item!(description, id, type, sku, box=nil)
63
+ description << " in:#{box}" unless box.nil?
64
+ record = Record.new("#{Date.today} #{description} id:#{id} is:#{type} sku:#{sku}")
65
+ @list.append(record)
66
+ @list.save!
67
+ end
68
+
69
+ def add_folder!(description, id, sku, box=nil)
70
+ add_item!(description, id, :folder, sku, box)
71
+ end
72
+
73
+ def add_box!(description, id, sku)
74
+ add_item!(description, id, :box, sku)
75
+ end
76
+
77
+ def save!
78
+ @list.save!
79
+ end
80
+
81
+ def sync!
82
+ ledger_file = File.basename(ledger_path)
83
+
84
+ if repo.status.changed?(ledger_file)
85
+ repo.add(ledger_file)
86
+ repo.commit("Synchronizing inventory [#{Time.new}]")
87
+ repo.push
88
+ true # Result:OK
89
+ else
90
+ false # Result::NO_CHANGES
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def repo
97
+ @repo ||= Git.open(Env.documents_dir, :log => Logger.new(STDERR, level: Logger::INFO))
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,58 @@
1
+ module Intent
2
+ module Core
3
+ class Projects
4
+ attr_reader :list
5
+ attr_reader :ledger_path
6
+
7
+ def initialize(db_path)
8
+ @ledger_path = db_path
9
+ @list = List.new(db_path)
10
+ end
11
+
12
+ def all
13
+ list.by_not_done
14
+ end
15
+
16
+ def all_tokens
17
+ all.map { |item| item.projects.first }.uniq
18
+ end
19
+
20
+ def linked_directory(path)
21
+ all.find { |item| item.text == path && ['repository', 'directory'].include?(item.tags[:is]) }
22
+ end
23
+
24
+ def sync!
25
+ ledger_file = File.basename(ledger_path)
26
+
27
+ if repo.status.changed?(ledger_file)
28
+ repo.add(ledger_file)
29
+ repo.commit("Synchronizing projects [#{Time.new}]")
30
+ repo.push
31
+ true # Result:OK
32
+ else
33
+ false # Result::NO_CHANGES
34
+ end
35
+ end
36
+
37
+ def add_directory!(path, project, id, computer)
38
+ record = Record.new([
39
+ Date.today,
40
+ path,
41
+ project,
42
+ "is:directory",
43
+ "id:#{id}",
44
+ "computer:#{computer}"
45
+ ].join(' '))
46
+
47
+ @list.append(record)
48
+ @list.save!
49
+ end
50
+
51
+ private
52
+
53
+ def repo
54
+ @repo ||= Git.open(Env.documents_dir, :log => Logger.new(STDERR, level: Logger::INFO))
55
+ end
56
+ end
57
+ end
58
+ end
data/lib/intent/core.rb CHANGED
@@ -1,25 +1,25 @@
1
1
  module Intent
2
- module Env
3
- def self.documents_dir
4
- File.expand_path(ENV['INTENT_DOCUMENTS_DIR'] || "").to_s
5
- end
2
+ module Core
3
+ List = ::Todo::List
4
+ Record = ::Todo::Task
6
5
 
7
- def self.inbox_dir
8
- ENV['INTENT_INBOX_DIR']
9
- end
6
+ VERBS = [:add, :assign, :list, :link, :sync]
10
7
 
11
- def self.assets_dir
12
- ENV['INTENT_ARCHIVE_DIR']
13
- end
8
+ NOUNS = {
9
+ inventory: [:unit, :box, :folder, :computer],
10
+ projects: [:project, :directory, :repository],
11
+ todo: [:task]
12
+ }
13
+
14
+ class Action
15
+ attr_reader :verb
16
+ attr_reader :noun
14
17
 
15
- def self.projects_dir
16
- ENV['INTENT_PROJECTS_DIR']
18
+ def initialize(verb_sym, noun_r)
19
+ @verb = Verbs.instance_for(verb_sym)
20
+ @noun = Noun.new(noun_r.type, noun_r.label, noun_r.tags)
21
+ end
17
22
  end
18
- end
19
-
20
- module Core
21
- List = ::Todo::List
22
- Record = ::Todo::Task
23
23
 
24
24
  class Noun
25
25
  def initialize(type, label, tags)
@@ -35,151 +35,11 @@ module Intent
35
35
  p tags
36
36
  end
37
37
  end
38
-
39
- class Projects
40
- attr_reader :list
41
-
42
- def initialize(db_path)
43
- @list = List.new(db_path)
44
- end
45
-
46
- def all
47
- list.by_not_done
48
- end
49
-
50
- def all_tokens
51
- all.map { |project| project.projects.first }
52
- end
53
- end
54
-
55
- class Inventory
56
- attr_reader :list
57
-
58
- def initialize(db_path)
59
- @list = List.new(db_path)
60
- end
61
-
62
- def all
63
- list.by_not_done
64
- end
65
-
66
- def folder_by_id(id)
67
- all.find { |i| i.tags[:is] == 'folder' && i.tags[:id] == id }
68
- end
69
-
70
- def folders
71
- all.filter { |i| i.tags[:is] == 'folder' }
72
- end
73
-
74
- def items_in(id)
75
- all.filter { |i| i.tags[:in] == id }
76
- end
77
-
78
- def unassigned_folders
79
- all.filter { |i| i.tags[:is] == 'folder' && i.projects.empty? }
80
- end
81
-
82
- def assigned_folders
83
- all.filter { |i| i.tags[:is] == 'folder' && i.projects.any? }
84
- end
85
-
86
- def boxes
87
- all.filter { |i| i.tags[:is] == 'box' }
88
- end
89
-
90
- def unassigned_boxes
91
- all.filter { |i| i.tags[:is] == 'box' && i.projects.empty? }
92
- end
93
-
94
- def assigned_boxes
95
- all.filter { |i| i.tags[:is] == 'box' && i.projects.any? }
96
- end
97
-
98
- def units_of(noun)
99
- all.filter { |i| i.tags[:is] == 'unit' && i.tags[:type] == noun.to_s }
100
- end
101
-
102
- def add_unit!(description, type, sku)
103
- record = Record.new("#{Date.today} #{description} is:unit type:#{type} sku:#{sku}")
104
- @list.append(record)
105
- @list.save!
106
- end
107
-
108
- def add_item!(description, id, type, sku, box=nil)
109
- description << " in:#{box}" unless box.nil?
110
- record = Record.new("#{Date.today} #{description} id:#{id} is:#{type} sku:#{sku}")
111
- @list.append(record)
112
- @list.save!
113
- end
114
-
115
- def add_folder!(description, id, sku, box=nil)
116
- add_item!(description, id, :folder, sku, box)
117
- end
118
-
119
- def add_box!(description, id, sku)
120
- add_item!(description, id, :box, sku)
121
- end
122
-
123
- def save!
124
- @list.save!
125
- end
126
- end
127
-
128
- class Inbox
129
- attr_reader :list
130
-
131
- def initialize(db_path)
132
- @list = List.new(db_path)
133
- end
134
-
135
- def all
136
- @list.by_not_done
137
- end
138
-
139
- def focused
140
- @list.by_context('@focus').by_not_done
141
- end
142
-
143
- def focused_projects
144
- focused.map { |t| t.projects }.flatten.uniq
145
- end
146
-
147
- def add_line!(line)
148
- record = Record.new("#{Date.today} #{line}")
149
- @list.prepend(record)
150
- @list.save!
151
- end
152
- end
153
-
154
- class Documents
155
- attr_reader :projects
156
- attr_reader :inventory
157
- attr_reader :inbox
158
-
159
- def initialize
160
- @projects = Projects.new("#{Intent::Env.documents_dir}/projects.txt")
161
- @inventory = Inventory.new("#{Intent::Env.documents_dir}/inventory.txt")
162
- @inbox = Inbox.new("#{Intent::Env.documents_dir}/todo.txt")
163
- end
164
- end
165
- end
166
-
167
- class Dispatcher
168
- def self.exec_command(command, args, output=STDOUT)
169
- command = init_command(command).new
170
- command.run(args, output)
171
- end
172
-
173
- def self.init_command(command)
174
- case command
175
- when :intent then return Commands::Intent
176
- when :inventory then return Commands::Inventory
177
- when :projects then return Commands::Projects
178
- when :project then return Commands::Project
179
- when :todo then return Commands::Todo
180
- else
181
- raise Commands::Errors::COMMAND_NOT_FOUND
182
- end
183
- end
184
38
  end
185
39
  end
40
+
41
+ require 'intent/core/projects'
42
+ require 'intent/core/inventory'
43
+ require 'intent/core/inbox'
44
+ require 'intent/core/directory'
45
+ require 'intent/core/documents'
@@ -1,3 +1,5 @@
1
- require 'pathname'
2
-
3
- require 'intent/desktop/commands'
1
+ require 'intent/verbs/add'
2
+ require 'intent/verbs/assign'
3
+ require 'intent/verbs/link'
4
+ require 'intent/verbs/list'
5
+ require 'intent/verbs/sync'
@@ -0,0 +1,20 @@
1
+ module Intent
2
+ class Dispatcher
3
+ def self.exec_command(command, args, output=STDOUT)
4
+ command = init_command(command).new
5
+ command.run(args, output)
6
+ end
7
+
8
+ def self.init_command(command)
9
+ case command
10
+ when :intent then return Commands::Intent
11
+ when :inventory then return Commands::Inventory
12
+ when :projects then return Commands::Projects
13
+ when :project then return Commands::Project
14
+ when :todo then return Commands::Todo
15
+ else
16
+ raise Commands::Errors::COMMAND_NOT_FOUND
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/intent/env.rb ADDED
@@ -0,0 +1,26 @@
1
+ module Intent
2
+ module Env
3
+ def self.documents_dir
4
+ File.expand_path(ENV['INTENT_DOCUMENTS_DIR'] || "").to_s
5
+ end
6
+
7
+ def self.inbox_dir
8
+ ENV['INTENT_INBOX_DIR']
9
+ end
10
+
11
+ def self.assets_dir
12
+ ENV['INTENT_ARCHIVE_DIR']
13
+ end
14
+
15
+ def self.projects_dir
16
+ ENV['INTENT_PROJECTS_DIR']
17
+ end
18
+
19
+ def self.computer_serial
20
+ # macOS: `system_profiler SPHardwareDataType`
21
+ # Win: `wmic bios get serialnumber`
22
+ # Linux: `ls /sys/devices/virtual/dmi/id`
23
+ ENV['INTENT_COMPUTER_SERIAL']
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,82 @@
1
+ ====================================================================
2
+ Intent . Havin a blast on the command line
3
+ ====================================================================
4
+
5
+ Welcome to the only task manager you will (n)ever need.
6
+
7
+ These docs are not written for a wide audience, but here’s the
8
+ essentials:
9
+
10
+ Verbs
11
+ -----
12
+
13
+ ### `add [noun]`
14
+
15
+ Adds [noun] to the ledger denoted by the given command.
16
+
17
+ ```
18
+ projects add
19
+ projects add project
20
+ projects add directory
21
+ projects add repository
22
+
23
+ project add
24
+
25
+ inventory add
26
+ inventory add folder
27
+ inventory add box
28
+ inventory add unit
29
+ inventory add computer
30
+
31
+ todo add
32
+
33
+ inbox add
34
+ ```
35
+
36
+ ### `assign [noun]`
37
+
38
+ Assigns projects, contexts, tags and associations to ap.
39
+
40
+ ```
41
+ projects assign
42
+
43
+ project assign
44
+
45
+ inventory assign
46
+ ```
47
+
48
+ ### `list [noun]`
49
+
50
+ Lists elements in the ledger.
51
+
52
+ ```
53
+ projects list
54
+
55
+ project list
56
+
57
+ inventory list
58
+
59
+ todo list
60
+
61
+ inbox list
62
+ ```
63
+
64
+ ### `link [noun]`
65
+
66
+ Links elements from a local directory to an assigned project.
67
+
68
+ ```
69
+ project link
70
+ ```
71
+
72
+ ### `sync [noun]`
73
+
74
+ Synchronises changes to the Git origin.
75
+
76
+ ```
77
+ projects sync
78
+
79
+ inventory sync
80
+ ```
81
+
82
+ Documentation is patchy and not always up to date.
@@ -1,3 +1,3 @@
1
1
  module Intent
2
- VERSION = '0.7.1'
2
+ VERSION = '0.8.0'
3
3
  end
data/lib/intent.rb CHANGED
@@ -1,23 +1,37 @@
1
1
  #require 'random'
2
- require 'todo-txt'
2
+ #require 'pathname'
3
+
4
+ # Pastel still required but deprecated
3
5
  require 'pastel'
4
6
  require 'paint'
7
+
8
+ # CLI UI tools
5
9
  require 'tty-prompt'
6
10
  require 'tty-table'
7
11
  require 'tty-tree'
12
+
13
+ # Identifiers
8
14
  require 'nanoid'
15
+ #require 'calyx'
16
+
17
+ # Interact with git repos
18
+ require 'logger'
19
+ require 'git'
20
+
21
+ # todo.txt data structure support
22
+ require 'todo-txt'
9
23
  require 'gem_ext/todo-txt'
10
24
 
11
25
  Todo.customize do |options|
12
26
  options.require_completed_on = false
13
27
  end
14
28
 
29
+ # Intent library
15
30
  require 'intent/version'
31
+ require 'intent/env'
32
+ require 'intent/args'
16
33
  require 'intent/core'
34
+ #require 'intent/verbs'
17
35
  require 'intent/commands'
18
36
  require 'intent/ui/term_color'
19
- # require 'intent/todo'
20
- # require 'intent/review'
21
- # require 'intent/projects'
22
- # require 'intent/desktop'
23
-
37
+ require 'intent/dispatcher'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: intent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Rickerby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-16 00:00:00.000000000 Z
11
+ date: 2024-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: todo-txt
@@ -268,9 +268,9 @@ email:
268
268
  executables:
269
269
  - intent
270
270
  - inventory
271
+ - project
271
272
  - project_doc
272
273
  - projects
273
- - projects_active
274
274
  - todo
275
275
  - todo_review
276
276
  extensions: []
@@ -283,30 +283,41 @@ files:
283
283
  - Rakefile
284
284
  - bin/intent
285
285
  - bin/inventory
286
+ - bin/project
286
287
  - bin/project_doc
287
288
  - bin/projects
288
- - bin/projects_active
289
289
  - bin/todo
290
290
  - bin/todo_review
291
291
  - intent.gemspec
292
292
  - lib/gem_ext/todo-txt.rb
293
293
  - lib/intent.rb
294
+ - lib/intent/args.rb
294
295
  - lib/intent/commands.rb
295
296
  - lib/intent/commands/base.rb
296
297
  - lib/intent/commands/errors.rb
297
298
  - lib/intent/commands/intent.rb
298
299
  - lib/intent/commands/inventory.rb
300
+ - lib/intent/commands/project.rb
299
301
  - lib/intent/commands/projects.rb
300
302
  - lib/intent/commands/todo.rb
301
303
  - lib/intent/core.rb
304
+ - lib/intent/core/directory.rb
305
+ - lib/intent/core/documents.rb
306
+ - lib/intent/core/inbox.rb
307
+ - lib/intent/core/inventory.rb
308
+ - lib/intent/core/projects.rb
302
309
  - lib/intent/desktop.rb
310
+ - lib/intent/dispatcher.rb
311
+ - lib/intent/env.rb
303
312
  - lib/intent/projects.rb
304
313
  - lib/intent/review.rb
314
+ - lib/intent/text/intent.help.txt
305
315
  - lib/intent/text/inventory.help.txt
306
316
  - lib/intent/text/project.help.txt
307
317
  - lib/intent/text/projects.help.txt
308
318
  - lib/intent/text/todo.help.txt
309
319
  - lib/intent/todo.rb
320
+ - lib/intent/ui/projects_active.rb
310
321
  - lib/intent/ui/term_color.rb
311
322
  - lib/intent/ui/ttyui.rb
312
323
  - lib/intent/verbs/add.rb