jekyll-ai-visible-content 0.4.6 → 0.4.8

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: 14de8a61e197c79ff7d477a1cb8a53f7586af31310b44efb84349317d3ada22a
4
- data.tar.gz: '0843a3e8a6135bebfae5bd1ce16f51eee09cf99960712f5e5757b252829c612e'
3
+ metadata.gz: 9afcf72aab91e0280ce7b14771e3b7ddd940e00093bec970feb0a5d4e0242e4d
4
+ data.tar.gz: 1b5229d2111d8e4b70518ea864863e79e7274c1c31d93f3e0658352ff7f78683
5
5
  SHA512:
6
- metadata.gz: 951b6f49beca5b9158eb0a8113a804f0f54778ae2f672b2cc6749071953104cfffb9e4439b14c0084529595b4ce460fbc7e6f948bf160e8b4ea7204726422b48
7
- data.tar.gz: 0cbd80303d37081931949e2bf3e7b1f4a95e2b9cfb8da719c84e7314e637ac6768174a0c4d2e185632a28243c68ba8f1a3ad518875bf8c35bcf6aa6862b1f568
6
+ metadata.gz: 0ccc34ccf335efbbd8b9e7151ab3d116ef2163bb02897f267b884aaa69b2a04ebf09ea7ec1d099b18904bd0a379de93a5de616b58b268c58446bf7b73d4b516a
7
+ data.tar.gz: 286af1a67ed7b1e39be4a8abe206f2bad467ef241ac1bc7a0f794578772337741d560c51172efd370f86e78fc31e7dc836e9a519813b7d27fbfc8d8a7832a277
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  .cursor
2
- *.gem
2
+ *.gem
3
+ .playwright-mcp/
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jekyll-ai-visible-content (0.4.6)
4
+ jekyll-ai-visible-content (0.4.8)
5
5
  jekyll (>= 4.0, < 5.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -132,6 +132,7 @@ ai_visible_content:
132
132
  # --- Internal Linking ---
133
133
  linking:
134
134
  enable_entity_links: true # Auto-link known entities in post body
135
+ apply_to_metadata: false # Safe default: never inject <a> into head/SEO/JSON-LD/feed fields
135
136
  entity_definitions: {} # Custom: slug -> {name, url, description}
136
137
  max_links_per_entity_per_post: 1
137
138
  enable_related_posts: true
@@ -151,6 +152,12 @@ ai_visible_content:
151
152
  max_examples: 3 # Max examples per warning group in summary mode
152
153
  ```
153
154
 
155
+ ### Entity Linking Safety
156
+
157
+ `linking.apply_to_metadata` defaults to `false` to keep metadata as plain text. With this default, entity auto-linking is applied to article body content only and is not applied to `<head>` meta tags, JSON-LD descriptions, or feed summaries.
158
+
159
+ Set `linking.apply_to_metadata: true` only if you explicitly want legacy full-document linking behavior.
160
+
154
161
  ## Layout Integration
155
162
 
156
163
  ### Automatic Mode (Recommended)
@@ -50,6 +50,7 @@ module JekyllAiVisibleContent
50
50
  },
51
51
  'linking' => {
52
52
  'enable_entity_links' => true,
53
+ 'apply_to_metadata' => false,
53
54
  'entity_definitions' => {},
54
55
  'max_links_per_entity_per_post' => 1,
55
56
  'enable_related_posts' => true,
@@ -75,6 +75,48 @@ module JekyllAiVisibleContent
75
75
  registry = Entity::Registry.new(config)
76
76
  definitions = registry.entity_definitions
77
77
  max_per = config.linking['max_links_per_entity_per_post'] || 1
78
+ apply_to_metadata = config.linking['apply_to_metadata'] == true
79
+
80
+ if apply_to_metadata
81
+ Jekyll.logger.warn(
82
+ 'ai_visible_content',
83
+ 'linking.apply_to_metadata=true may inject HTML into metadata fields'
84
+ )
85
+ end
86
+
87
+ doc.output = link_entities(
88
+ doc.output,
89
+ definitions: definitions,
90
+ max_per: max_per,
91
+ context: (apply_to_metadata ? :legacy_full_document : :body)
92
+ )
93
+ end
94
+
95
+ def link_entities(text, definitions:, max_per:, context:)
96
+ return text unless text
97
+
98
+ case context
99
+ when :body
100
+ link_entities_in_body(text, definitions, max_per)
101
+ when :metadata
102
+ sanitize_metadata_text(text)
103
+ when :legacy_full_document
104
+ replace_entities_in_fragment(text, definitions, max_per)
105
+ else
106
+ text
107
+ end
108
+ end
109
+
110
+ def link_entities_in_body(html, definitions, max_per)
111
+ return html unless html.include?('<body')
112
+
113
+ html.sub(%r{<body\b[^>]*>.*</body>}im) do |body_fragment|
114
+ replace_entities_in_fragment(body_fragment, definitions, max_per)
115
+ end
116
+ end
117
+
118
+ def replace_entities_in_fragment(fragment, definitions, max_per)
119
+ result = fragment.dup
78
120
 
79
121
  definitions.each_value do |defn|
80
122
  name = defn['name']
@@ -83,25 +125,42 @@ module JekyllAiVisibleContent
83
125
 
84
126
  link_html = %(<a href="#{url}" itemprop="about" itemscope ) +
85
127
  %(itemtype="https://schema.org/Thing"><span itemprop="name">#{name}</span></a>)
86
-
87
- doc.output = replace_entity_outside_anchor(doc.output, name, max_per, link_html)
128
+ result = replace_entity_outside_anchor(result, name, max_per, link_html)
88
129
  end
130
+
131
+ result
89
132
  end
90
133
 
91
134
  def replace_entity_outside_anchor(html, name, max_per, link_html)
92
- pattern = /(?<=\s|>)#{Regexp.escape(name)}(?=[\s,.<])/i
93
- chunks = html.split(%r{(<a\b[^>]*>.*?</a>)}im)
135
+ pattern = /(^|[\s>])(#{Regexp.escape(name)})(?=[\s,.<])/i
136
+ chunks = html.split(/(<[^>]+>)/m)
94
137
  replaced = 0
138
+ skip_text_replacement = false
139
+
140
+ chunks.map! do |chunk|
141
+ if chunk.start_with?('<')
142
+ opening_name = chunk[/\A<\s*([a-z0-9:-]+)/i, 1]&.downcase
143
+ closing_name = chunk[%r{\A<\s*/\s*([a-z0-9:-]+)}i, 1]&.downcase
144
+
145
+ if %w[a script style template].include?(opening_name) && chunk !~ %r{/\s*>\z}
146
+ skip_text_replacement = true
147
+ elsif %w[a script style template].include?(closing_name)
148
+ skip_text_replacement = false
149
+ end
150
+
151
+ next chunk
152
+ end
95
153
 
96
- chunks.map!.with_index do |chunk, idx|
97
- next chunk if idx.odd?
154
+ next chunk if skip_text_replacement
98
155
 
99
- chunk.gsub(pattern) do |match|
156
+ chunk.gsub(pattern) do
157
+ prefix = ::Regexp.last_match(1)
158
+ match = ::Regexp.last_match(2)
100
159
  if replaced < max_per
101
160
  replaced += 1
102
- link_html
161
+ "#{prefix}#{link_html}"
103
162
  else
104
- match
163
+ "#{prefix}#{match}"
105
164
  end
106
165
  end
107
166
  end
@@ -109,6 +168,10 @@ module JekyllAiVisibleContent
109
168
  chunks.join
110
169
  end
111
170
 
171
+ def sanitize_metadata_text(text)
172
+ text.to_s.gsub(/<[^>]*>/, ' ').gsub(/\s+/, ' ').strip
173
+ end
174
+
112
175
  def inject_ai_resource_links(doc, config)
113
176
  resources = doc.site.data['ai_page_resources']
114
177
  return unless resources
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JekyllAiVisibleContent
4
- VERSION = '0.4.6'
4
+ VERSION = '0.4.8'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-ai-visible-content
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.4.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - madmatvey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-07 00:00:00.000000000 Z
11
+ date: 2026-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -39,21 +39,6 @@ extensions: []
39
39
  extra_rdoc_files: []
40
40
  files:
41
41
  - ".gitignore"
42
- - ".playwright-mcp/console-2026-04-07T14-47-00-050Z.log"
43
- - ".playwright-mcp/console-2026-04-07T14-47-21-660Z.log"
44
- - ".playwright-mcp/console-2026-04-07T14-50-13-784Z.log"
45
- - ".playwright-mcp/console-2026-04-07T14-50-27-912Z.log"
46
- - ".playwright-mcp/console-2026-04-07T15-07-51-108Z.log"
47
- - ".playwright-mcp/console-2026-04-07T15-07-59-236Z.log"
48
- - ".playwright-mcp/console-2026-04-07T15-08-12-452Z.log"
49
- - ".playwright-mcp/page-2026-04-07T14-47-02-356Z.yml"
50
- - ".playwright-mcp/page-2026-04-07T14-47-22-295Z.yml"
51
- - ".playwright-mcp/page-2026-04-07T14-50-14-081Z.yml"
52
- - ".playwright-mcp/page-2026-04-07T14-50-28-154Z.yml"
53
- - ".playwright-mcp/page-2026-04-07T15-07-52-686Z.yml"
54
- - ".playwright-mcp/page-2026-04-07T15-07-59-677Z.yml"
55
- - ".playwright-mcp/page-2026-04-07T15-08-06-166Z.yml"
56
- - ".playwright-mcp/page-2026-04-07T15-08-12-836Z.yml"
57
42
  - ".rubocop.yml"
58
43
  - CHANGELOG.md
59
44
  - Gemfile
@@ -1,2 +0,0 @@
1
- [ 2214ms] [WARNING] For security reasons, Hotjar only works over HTTPS. Learn more: https://help.hotjar.com/hc/en-us/articles/115011624047 @ https://static.hotjar.com/c/hotjar-5066415.js?sv=7:2
2
- [ 2225ms] [WARNING] <meta name="apple-mobile-web-app-capable" content="yes"> is deprecated. Please include <meta name="mobile-web-app-capable" content="yes"> @ http://127.0.0.1:4000/:0
@@ -1,2 +0,0 @@
1
- [ 144ms] [WARNING] For security reasons, Hotjar only works over HTTPS. Learn more: https://help.hotjar.com/hc/en-us/articles/115011624047 @ https://static.hotjar.com/c/hotjar-5066415.js?sv=7:2
2
- [ 594ms] [WARNING] <meta name="apple-mobile-web-app-capable" content="yes"> is deprecated. Please include <meta name="mobile-web-app-capable" content="yes"> @ http://127.0.0.1:4000/posts/redis-is-single-threaded/:0
@@ -1,2 +0,0 @@
1
- [ 241ms] [WARNING] For security reasons, Hotjar only works over HTTPS. Learn more: https://help.hotjar.com/hc/en-us/articles/115011624047 @ https://static.hotjar.com/c/hotjar-5066415.js?sv=7:2
2
- [ 242ms] [WARNING] <meta name="apple-mobile-web-app-capable" content="yes"> is deprecated. Please include <meta name="mobile-web-app-capable" content="yes"> @ http://127.0.0.1:4000/posts/redis-is-single-threaded/:0
@@ -1,3 +0,0 @@
1
- [ 93ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://127.0.0.1:4000/ai/topic/redis-is-single-threaded.json:0
2
- [ 149ms] [WARNING] For security reasons, Hotjar only works over HTTPS. Learn more: https://help.hotjar.com/hc/en-us/articles/115011624047 @ https://static.hotjar.com/c/hotjar-5066415.js?sv=7:2
3
- [ 223ms] [WARNING] <meta name="apple-mobile-web-app-capable" content="yes"> is deprecated. Please include <meta name="mobile-web-app-capable" content="yes"> @ http://127.0.0.1:4000/ai/topic/redis-is-single-threaded.json:0
@@ -1,2 +0,0 @@
1
- [ 1428ms] [WARNING] For security reasons, Hotjar only works over HTTPS. Learn more: https://help.hotjar.com/hc/en-us/articles/115011624047 @ https://static.hotjar.com/c/hotjar-5066415.js?sv=7:2
2
- [ 1557ms] [WARNING] <meta name="apple-mobile-web-app-capable" content="yes"> is deprecated. Please include <meta name="mobile-web-app-capable" content="yes"> @ http://127.0.0.1:4000/:0
@@ -1,2 +0,0 @@
1
- [ 106ms] [WARNING] For security reasons, Hotjar only works over HTTPS. Learn more: https://help.hotjar.com/hc/en-us/articles/115011624047 @ https://static.hotjar.com/c/hotjar-5066415.js?sv=7:2
2
- [ 422ms] [WARNING] <meta name="apple-mobile-web-app-capable" content="yes"> is deprecated. Please include <meta name="mobile-web-app-capable" content="yes"> @ http://127.0.0.1:4000/about/:0
@@ -1,2 +0,0 @@
1
- [ 96ms] [WARNING] For security reasons, Hotjar only works over HTTPS. Learn more: https://help.hotjar.com/hc/en-us/articles/115011624047 @ https://static.hotjar.com/c/hotjar-5066415.js?sv=7:2
2
- [ 359ms] [WARNING] <meta name="apple-mobile-web-app-capable" content="yes"> is deprecated. Please include <meta name="mobile-web-app-capable" content="yes"> @ http://127.0.0.1:4000/posts/ai-junior/:0
@@ -1,297 +0,0 @@
1
- - generic [active] [ref=e1]:
2
- - complementary "Sidebar" [ref=e2]:
3
- - generic [ref=e3]:
4
- - link "Go to homepage" [ref=e4] [cursor=pointer]:
5
- - /url: /
6
- - generic [ref=e5]: Go to homepage
7
- - generic [ref=e6]: Go to homepage
8
- - img [ref=e7]
9
- - heading "Go to homepage" [level=1] [ref=e8]:
10
- - link "Go to homepage" [ref=e9] [cursor=pointer]:
11
- - /url: /
12
- - text: Eugene Leontev The Engineer
13
- - paragraph [ref=e10]: Innovate. Code. Inspire. Since 1984.
14
- - navigation [ref=e11]:
15
- - list [ref=e12]:
16
- - listitem [ref=e13]:
17
- - link "Go to homepage" [ref=e14] [cursor=pointer]:
18
- - /url: /
19
- - generic [ref=e15]: 
20
- - generic [ref=e16]: HOME
21
- - listitem [ref=e17]:
22
- - link "Go to CATEGORIES" [ref=e18] [cursor=pointer]:
23
- - /url: /categories/
24
- - generic [ref=e19]: 
25
- - generic [ref=e20]: CATEGORIES
26
- - listitem [ref=e21]:
27
- - link "Go to TAGS" [ref=e22] [cursor=pointer]:
28
- - /url: /tags/
29
- - generic [ref=e23]: 
30
- - generic [ref=e24]: TAGS
31
- - listitem [ref=e25]:
32
- - link "Go to ARCHIVES" [ref=e26] [cursor=pointer]:
33
- - /url: /archives/
34
- - generic [ref=e27]: 
35
- - generic [ref=e28]: ARCHIVES
36
- - listitem [ref=e29]:
37
- - link "Go to ABOUT" [ref=e30] [cursor=pointer]:
38
- - /url: /about/
39
- - generic [ref=e31]: 
40
- - generic [ref=e32]: ABOUT
41
- - listitem [ref=e33]:
42
- - link "Go to MOTIVATION TEST" [ref=e34] [cursor=pointer]:
43
- - /url: /motivation-test/
44
- - generic [ref=e35]: 
45
- - generic [ref=e36]: MOTIVATION TEST
46
- - listitem [ref=e37]:
47
- - link "Go to TERMS PRIVACY POLICY" [ref=e38] [cursor=pointer]:
48
- - /url: /terms-privacy-policy/
49
- - generic [ref=e39]: 
50
- - generic [ref=e40]: TERMS PRIVACY POLICY
51
- - generic [ref=e41]:
52
- - link "Visit GitHub profile" [ref=e42] [cursor=pointer]:
53
- - /url: https://github.com/madmatvey
54
- - generic [ref=e43]: Visit GitHub profile
55
- - generic [ref=e44]: Visit GitHub profile
56
- - generic [ref=e45]: 
57
- - link "Visit X (Twitter) profile" [ref=e46] [cursor=pointer]:
58
- - /url: https://x.com/EugeneLeontev
59
- - generic [ref=e47]: Visit X (Twitter) profile
60
- - generic [ref=e48]: Visit X (Twitter) profile
61
- - generic [ref=e49]: 
62
- - link "Send email" [ref=e50] [cursor=pointer]:
63
- - /url: javascript:location.href = 'mailto:' + ['potehin','gmail.com'].join('@')
64
- - generic [ref=e51]: Send email
65
- - generic [ref=e52]: Send email
66
- - generic [ref=e53]: 
67
- - link "RSS feed" [ref=e54] [cursor=pointer]:
68
- - /url: /feed.xml
69
- - generic [ref=e55]: RSS feed
70
- - generic [ref=e56]: RSS feed
71
- - generic [ref=e57]: 
72
- - link "Visit LinkedIn profile" [ref=e58] [cursor=pointer]:
73
- - /url: https://www.linkedin.com/in/eugeneleontev/
74
- - generic [ref=e59]: Visit LinkedIn profile
75
- - generic [ref=e60]: Visit LinkedIn profile
76
- - generic [ref=e61]: 
77
- - generic [ref=e62]:
78
- - generic [ref=e63]:
79
- - banner "Top Bar" [ref=e64]:
80
- - generic [ref=e65]:
81
- - navigation "Breadcrumb" [ref=e66]: Home
82
- - text:  
83
- - search [ref=e67]:
84
- - generic [ref=e68]: 
85
- - searchbox "search" [ref=e69]
86
- - generic [ref=e70]:
87
- - main "Main Content" [ref=e71]:
88
- - generic [ref=e72]:
89
- - article [ref=e73]:
90
- - link "Diagram showing Redis is single-threaded on the outside, but multithreaded on the inside Single-Threaded on the Outside, Multithreaded on the Inside Learn how Redis is single-threaded on the outside, but multithreaded on the inside. Read the full case study!  Mar 4, 2026  Tutorial, Coding" [ref=e74] [cursor=pointer]:
91
- - /url: /posts/redis-is-single-threaded/
92
- - img "Diagram showing Redis is single-threaded on the outside, but multithreaded on the inside" [ref=e77]
93
- - generic [ref=e79]:
94
- - heading "Single-Threaded on the Outside, Multithreaded on the Inside" [level=2] [ref=e80]
95
- - paragraph [ref=e82]: Learn how Redis is single-threaded on the outside, but multithreaded on the inside. Read the full case study!
96
- - generic [ref=e84]:
97
- - generic [ref=e85]: 
98
- - time [ref=e86]: Mar 4, 2026
99
- - generic [ref=e87]: 
100
- - text: Tutorial, Coding
101
- - article [ref=e88]:
102
- - 'link "Diagram showing data loading optimization in Telegram Mini App When Loading Data Isn''t Simple: Decisions Under Uncertainty Learn how we eliminated UI flicker and reduced load time in a Telegram Mini App by loading all user data in a single PostgreSQL query. Read the full case study!  Feb 4, 2026  Product, UX" [ref=e89] [cursor=pointer]':
103
- - /url: /posts/ux-when-initial-app-loading/
104
- - img "Diagram showing data loading optimization in Telegram Mini App" [ref=e92]
105
- - generic [ref=e94]:
106
- - 'heading "When Loading Data Isn''t Simple: Decisions Under Uncertainty" [level=2] [ref=e95]'
107
- - paragraph [ref=e97]: Learn how we eliminated UI flicker and reduced load time in a Telegram Mini App by loading all user data in a single PostgreSQL query. Read the full case study!
108
- - generic [ref=e99]:
109
- - generic [ref=e100]: 
110
- - time [ref=e101]: Feb 4, 2026
111
- - generic [ref=e102]: 
112
- - text: Product, UX
113
- - article [ref=e103]:
114
- - link "AI assistant coding illustration showing architectural thinking importance Why an AI Assistant Won’t Replace Your Architectural Thinking Learn why effective AI-powered development starts with your own architectural thinking and task decomposition — not just prompts. Discover how to think architecturally!  Nov 3, 2025  AI, Problem Solving" [ref=e104] [cursor=pointer]:
115
- - /url: /posts/ai-assited-coding-statement/
116
- - img "AI assistant coding illustration showing architectural thinking importance" [ref=e107]
117
- - generic [ref=e109]:
118
- - heading "Why an AI Assistant Won’t Replace Your Architectural Thinking" [level=2] [ref=e110]
119
- - paragraph [ref=e112]: Learn why effective AI-powered development starts with your own architectural thinking and task decomposition — not just prompts. Discover how to think architecturally!
120
- - generic [ref=e114]:
121
- - generic [ref=e115]: 
122
- - time [ref=e116]: Nov 3, 2025
123
- - generic [ref=e117]: 
124
- - text: AI, Problem Solving
125
- - article [ref=e118]:
126
- - link "Illustration showing startup failure statistics and customer pain validation 90% of Startups Die Because the Customer Doesn’t Feel Pain 90% of startups fail because customers don’t feel real pain. Learn how to validate ideas, avoid AI chaos, and turn vision into a working product.  Oct 13, 2025  Read this, Problem Solving" [ref=e119] [cursor=pointer]:
127
- - /url: /posts/startups-will-die/
128
- - img "Illustration showing startup failure statistics and customer pain validation" [ref=e122]
129
- - generic [ref=e124]:
130
- - heading "90% of Startups Die Because the Customer Doesn’t Feel Pain" [level=2] [ref=e125]
131
- - paragraph [ref=e127]: 90% of startups fail because customers don’t feel real pain. Learn how to validate ideas, avoid AI chaos, and turn vision into a working product.
132
- - generic [ref=e129]:
133
- - generic [ref=e130]: 
134
- - time [ref=e131]: Oct 13, 2025
135
- - generic [ref=e132]: 
136
- - text: Read this, Problem Solving
137
- - article [ref=e133]:
138
- - link "Cybersecurity warning about fake recruiters and LinkedIn phishing attacks When a Job Interview Turned Into a Cybersecurity Investigation Beware fake recruiters on LinkedIn. A real case of malware disguised as a job test, targeting crypto wallets and system data. Learn how to protect yourself.  Aug 18, 2025  Cybersecurity, Crypto" [ref=e134] [cursor=pointer]:
139
- - /url: /posts/recruiter-hacker/
140
- - img "Cybersecurity warning about fake recruiters and LinkedIn phishing attacks" [ref=e137]
141
- - generic [ref=e139]:
142
- - heading "When a Job Interview Turned Into a Cybersecurity Investigation" [level=2] [ref=e140]
143
- - paragraph [ref=e142]: Beware fake recruiters on LinkedIn. A real case of malware disguised as a job test, targeting crypto wallets and system data. Learn how to protect yourself.
144
- - generic [ref=e144]:
145
- - generic [ref=e145]: 
146
- - time [ref=e146]: Aug 18, 2025
147
- - generic [ref=e147]: 
148
- - text: Cybersecurity, Crypto
149
- - article [ref=e148]:
150
- - 'link "TARS technique diagram for formulating AI prompts in Cursor How to Formulate Prompts in Cursor: The TARS Technique Learn how to formulate prompts in Cursor using the TARS technique (Task, Assumptions, Requirements, Specification) to get more accurate and helpful results.  Jul 9, 2025  Tutorial, AI" [ref=e149] [cursor=pointer]':
151
- - /url: /posts/tars-prompting/
152
- - img "TARS technique diagram for formulating AI prompts in Cursor" [ref=e152]
153
- - generic [ref=e154]:
154
- - 'heading "How to Formulate Prompts in Cursor: The TARS Technique" [level=2] [ref=e155]'
155
- - paragraph [ref=e157]: Learn how to formulate prompts in Cursor using the TARS technique (Task, Assumptions, Requirements, Specification) to get more accurate and helpful results.
156
- - generic [ref=e159]:
157
- - generic [ref=e160]: 
158
- - time [ref=e161]: Jul 9, 2025
159
- - generic [ref=e162]: 
160
- - text: Tutorial, AI
161
- - article [ref=e163]:
162
- - 'link "Gasless USDT transactions on TRON blockchain using Ruby SDK Ruby gem ''gasfree_sdk'': Send USDT Without TRX on TRON Learn how to send USDT TRC-20 on TRON without needing TRX or energy using Ruby gem gasfree_sdk. Build gasless transactions and simplify Web3 UX.  Jun 8, 2025  Tutorial, Crypto" [ref=e164] [cursor=pointer]':
163
- - /url: /posts/introducing-ruby-gasless-sdk/
164
- - img "Gasless USDT transactions on TRON blockchain using Ruby SDK" [ref=e167]
165
- - generic [ref=e169]:
166
- - 'heading "Ruby gem ''gasfree_sdk'': Send USDT Without TRX on TRON" [level=2] [ref=e170]'
167
- - paragraph [ref=e172]: Learn how to send USDT TRC-20 on TRON without needing TRX or energy using Ruby gem gasfree_sdk. Build gasless transactions and simplify Web3 UX.
168
- - generic [ref=e174]:
169
- - generic [ref=e175]: 
170
- - time [ref=e176]: Jun 8, 2025
171
- - generic [ref=e177]: 
172
- - text: Tutorial, Crypto
173
- - article [ref=e178]:
174
- - link "AI junior developer illustration showing Cursor.ai productivity boost How I Hired a Fast AI Junior Developer for $192 a Year How I use Cursor.ai as a fast AI junior developer for $192/year to speed up coding, automate tasks, and boost productivity by 2-3x. Learn more!  Feb 3, 2025  Personal, Blog" [ref=e179] [cursor=pointer]:
175
- - /url: /posts/ai-junior/
176
- - img "AI junior developer illustration showing Cursor.ai productivity boost" [ref=e182]
177
- - generic [ref=e184]:
178
- - heading "How I Hired a Fast AI Junior Developer for $192 a Year" [level=2] [ref=e185]
179
- - paragraph [ref=e187]: How I use Cursor.ai as a fast AI junior developer for $192/year to speed up coding, automate tasks, and boost productivity by 2-3x. Learn more!
180
- - generic [ref=e189]:
181
- - generic [ref=e190]: 
182
- - time [ref=e191]: Feb 3, 2025
183
- - generic [ref=e192]: 
184
- - text: Personal, Blog
185
- - article [ref=e193]:
186
- - link "Top 5 must-read books for engineering leaders Top 5 Must-Read Books for Engineering Leaders Top 5 must-read books for engineering leaders to boost team dynamics, drive innovation, and master flexible leadership. Read more!  Sep 26, 2024  Read this, Leadership" [ref=e194] [cursor=pointer]:
187
- - /url: /posts/top-five-books-for-engineering-leaders/
188
- - img "Top 5 must-read books for engineering leaders" [ref=e197]
189
- - generic [ref=e199]:
190
- - heading "Top 5 Must-Read Books for Engineering Leaders" [level=2] [ref=e200]
191
- - paragraph [ref=e202]: Top 5 must-read books for engineering leaders to boost team dynamics, drive innovation, and master flexible leadership. Read more!
192
- - generic [ref=e204]:
193
- - generic [ref=e205]: 
194
- - time [ref=e206]: Sep 26, 2024
195
- - generic [ref=e207]: 
196
- - text: Read this, Leadership
197
- - article [ref=e208]:
198
- - 'link "Product-minded software engineer illustration showing product-focused development approach Product-Minded Software Engineer: Key Asset for Teams In today''s tech industry, successful engineers are product-minded, deeply involved in product decisions, user behavior, and business success.  Aug 30, 2024  Leadership, Product Development" [ref=e209] [cursor=pointer]':
199
- - /url: /posts/product-minded-engineer/
200
- - img "Product-minded software engineer illustration showing product-focused development approach" [ref=e212]
201
- - generic [ref=e214]:
202
- - 'heading "Product-Minded Software Engineer: Key Asset for Teams" [level=2] [ref=e215]'
203
- - paragraph [ref=e217]: In today's tech industry, successful engineers are product-minded, deeply involved in product decisions, user behavior, and business success.
204
- - generic [ref=e219]:
205
- - generic [ref=e220]: 
206
- - time [ref=e221]: Aug 30, 2024
207
- - generic [ref=e222]: 
208
- - text: Leadership, Product Development
209
- - navigation "Page Navigation" [ref=e223]:
210
- - list [ref=e224]:
211
- - listitem [ref=e225]:
212
- - link "Go to previous page":
213
- - /url: "#"
214
- - generic: Go to previous page
215
- - generic: Go to previous page
216
- - generic: 
217
- - listitem [ref=e226]:
218
- - link "Go to page 1" [ref=e227] [cursor=pointer]:
219
- - /url: /
220
- - text: "1"
221
- - listitem [ref=e228]:
222
- - link "Go to page 2" [ref=e229] [cursor=pointer]:
223
- - /url: /page2
224
- - text: "2"
225
- - listitem [ref=e230]:
226
- - link "Go to page 3" [ref=e231] [cursor=pointer]:
227
- - /url: /page3
228
- - text: "3"
229
- - listitem [ref=e232]:
230
- - link "Go to next page" [ref=e233] [cursor=pointer]:
231
- - /url: /page2
232
- - generic [ref=e234]: Go to next page
233
- - generic [ref=e235]: Go to next page
234
- - generic [ref=e236]: 
235
- - complementary "Panel" [ref=e237]:
236
- - generic [ref=e238]:
237
- - generic [ref=e239]:
238
- - heading "Recently Updated" [level=2] [ref=e240]
239
- - list [ref=e241]:
240
- - listitem [ref=e242]:
241
- - link "Single-Threaded on the Outside, Multithreaded on the Inside" [ref=e243] [cursor=pointer]:
242
- - /url: /posts/redis-is-single-threaded/
243
- - listitem [ref=e244]:
244
- - 'link "How to Formulate Prompts in Cursor: The TARS Technique" [ref=e245] [cursor=pointer]':
245
- - /url: /posts/tars-prompting/
246
- - listitem [ref=e246]:
247
- - 'link "Product-Minded Software Engineer: Key Asset for Teams" [ref=e247] [cursor=pointer]':
248
- - /url: /posts/product-minded-engineer/
249
- - listitem [ref=e248]:
250
- - 'link "Ruby gem ''gasfree_sdk'': Send USDT Without TRX on TRON" [ref=e249] [cursor=pointer]':
251
- - /url: /posts/introducing-ruby-gasless-sdk/
252
- - listitem [ref=e250]:
253
- - 'link "Discovering Your IKIGAI: Foundation of Strategic Job Search" [ref=e251] [cursor=pointer]':
254
- - /url: /posts/ikigai/
255
- - generic [ref=e252]:
256
- - heading "Trending Tags" [level=2] [ref=e253]
257
- - generic [ref=e254]:
258
- - link "software development" [ref=e255] [cursor=pointer]:
259
- - /url: /tags/software-development/
260
- - link "innovation" [ref=e256] [cursor=pointer]:
261
- - /url: /tags/innovation/
262
- - link "programming" [ref=e257] [cursor=pointer]:
263
- - /url: /tags/programming/
264
- - link "tech blog" [ref=e258] [cursor=pointer]:
265
- - /url: /tags/tech-blog/
266
- - link "problem-solving" [ref=e259] [cursor=pointer]:
267
- - /url: /tags/problem-solving/
268
- - link "engineering leadership" [ref=e260] [cursor=pointer]:
269
- - /url: /tags/engineering-leadership/
270
- - link "personal development" [ref=e261] [cursor=pointer]:
271
- - /url: /tags/personal-development/
272
- - link "tech" [ref=e262] [cursor=pointer]:
273
- - /url: /tags/tech/
274
- - link "leadership" [ref=e263] [cursor=pointer]:
275
- - /url: /tags/leadership/
276
- - link "career development" [ref=e264] [cursor=pointer]:
277
- - /url: /tags/career-development/
278
- - contentinfo "Site Info" [ref=e267]:
279
- - paragraph [ref=e268]:
280
- - text: ©
281
- - time [ref=e269]: "2026"
282
- - link "Visit Eugene Leontev's profile" [ref=e270] [cursor=pointer]:
283
- - /url: https://x.com/EugeneLeontev
284
- - text: Eugene Leontev
285
- - text: . Some rights reserved.
286
- - paragraph [ref=e271]:
287
- - text: Using the
288
- - link "Visit Chirpy theme on GitHub" [ref=e272] [cursor=pointer]:
289
- - /url: https://github.com/cotes2020/jekyll-theme-chirpy
290
- - text: Chirpy
291
- - text: theme for
292
- - link "Visit Jekyll website" [ref=e273] [cursor=pointer]:
293
- - /url: https://jekyllrb.com
294
- - text: Jekyll
295
- - text: .
296
- - text: "# # # # # # # # # #"
297
- - complementary "Scroll to Top"