pwn 0.5.782 → 0.5.783

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.
@@ -7,13 +7,113 @@ require 'fileutils'
7
7
  describe PWN::Sessions do
8
8
  include_context 'pwn tmp sandbox'
9
9
 
10
+ it 'reconciles page size, filtered inventory and physical support entries' do
11
+ allow(Dir).to receive(:home).and_return(@tmp)
12
+ 3.times { described_class.create }
13
+ File.write(File.join(described_class.sessions_dir, 'abandoned.tmp'), 'fixture')
14
+ page = described_class.catalog(limit: 1)
15
+ expect(page).to include(total: 0, physical_sessions: 3, filtered_sessions: 3, returned: 0, has_previous: false)
16
+ expect(page[:storage][:transcripts]).to eq(3)
17
+ expect(page[:storage].values.sum).to eq(Dir.children(described_class.sessions_dir).length)
18
+ end
19
+
20
+ it 'uses the compact layout while reading legacy metadata and sharing legacy lock inodes' do
21
+ allow(Dir).to receive(:home).and_return(@tmp)
22
+ sid = described_class.create[:id]
23
+ old_meta = File.join(described_class.sessions_dir, "#{sid}.meta.json")
24
+ old_lock = File.join(described_class.sessions_dir, ".#{sid}.cleanup.lock")
25
+ lease = described_class.activate(session_id: sid)
26
+ File.write(File.join(described_class.sessions_dir, '.layout-v2'), '2')
27
+ expect(described_class.metadata(session_id: sid)[:id]).to eq(sid)
28
+ expect(described_class.active?(session_id: sid)).to be(true)
29
+ expect(described_class.support_path(kind: :metadata, session_id: sid)).to eq(old_meta)
30
+ expect(described_class.support_path(kind: :lease, session_id: sid)).to eq(old_lock)
31
+ fresh = described_class.create[:id]
32
+ expect(File.file?(File.join(described_class.sessions_dir, 'support', 'metadata', "#{fresh}.meta.json"))).to be(true)
33
+ expect(described_class.dependency_index[:errors]).to be_empty
34
+ ensure
35
+ described_class.deactivate(lease: lease)
36
+ end
37
+
38
+ it 'treats complete policy trajectories as self-contained provenance but pins incomplete legacy rows' do
39
+ allow(Dir).to receive(:home).and_return(@tmp)
40
+ FileUtils.mkdir_p(File.join(@tmp, '.pwn'))
41
+ sid = described_class.create[:id]
42
+ trajectory = File.join(@tmp, '.pwn', 'policy_traj.jsonl')
43
+ row = { session_id: sid, request_family: 'ops', kind: 'task', engine: 'fixture', started_at: 'start', ended_at: 'end',
44
+ score: 1.0, verdict: 'success', return: 1.0, attribution: {}, steps: [{ state: 's', action: 'a', reward: 1.0, next_state: 's2', ok: true, duration: 0.1, terminal: true }] }
45
+ File.write(trajectory, "#{JSON.generate(row)}\n")
46
+ expect(described_class.dependency_index[:dependencies].fetch(sid, [])).not_to include(trajectory)
47
+ expect(JSON.parse(File.read(trajectory))['session_id']).to eq(sid)
48
+ legacy = row.except(:request_family, :attribution).merge(request: 'fixture request')
49
+ terminal = row.merge(score: nil, return: nil, steps: [{ state: 's', action: 'final', next_state: 's', reward: 0.0, terminal: true, credit_mode: 'terminal_attribution', credit_eligible: false }])
50
+ File.write(trajectory, [legacy, terminal].map { |record| JSON.generate(record) }.join("\n"))
51
+ expect(described_class.dependency_index[:dependencies].fetch(sid, [])).not_to include(trajectory)
52
+ File.write(trajectory, "#{JSON.generate(session_id: sid)}\n")
53
+ expect(described_class.dependency_index[:dependencies][sid]).to include(trajectory)
54
+ end
55
+
56
+ it 'shows the active provisional session without granting summary retention or hiding latest pages' do
57
+ allow(Dir).to receive(:home).and_return(@tmp)
58
+ ids = 4.times.map do |index|
59
+ sid = described_class.create[:id]
60
+ described_class.append(session_id: sid, role: 'user', content: "Fixture topic #{index}")
61
+ allow(PWN::AI::Router).to receive(:summarize).and_return(JSON.generate(title: "Topic #{index}", summary: "Conversation #{index}"))
62
+ described_class.refresh_title(session_id: sid)
63
+ File.utime(Time.at(index), Time.at(index), File.join(described_class.sessions_dir, "#{sid}.jsonl"))
64
+ sid
65
+ end
66
+ active = described_class.create[:id]
67
+ described_class.provisional_title(session_id: active, request: 'Investigate active topic')
68
+ page = described_class.catalog(current_session_id: active, limit: 2)
69
+ expect(page).to include(total: 5, offset: 3, has_more: false)
70
+ expect(page[:sessions].map { |row| row[:id] }).to eq([ids.last, active])
71
+ expect(page[:sessions].last).to include(active: true, title: 'Investigate active topic')
72
+ older = described_class.catalog(current_session_id: active, offset: 0, limit: 2)
73
+ expect(older[:sessions].map { |row| row[:id] }).to eq([*ids.first(2), active])
74
+ expect(older[:has_more]).to be(true)
75
+ expect(described_class.title_status(session_id: active)).to include(is_summarized: false)
76
+ expect(described_class.retention_status(session_id: active)[:visible]).to be(false)
77
+ end
78
+
79
+ it 'summarizes the correct session through the captured provider route outside another request scope' do
80
+ allow(Dir).to receive(:home).and_return(@tmp)
81
+ sid = described_class.create[:id]
82
+ other = described_class.create[:id]
83
+ described_class.append(session_id: sid, role: 'user', content: 'Repair login certificate')
84
+ described_class.append(session_id: other, role: 'user', content: 'Unrelated other session')
85
+ config = { active: :openai, openai: { model: 'captured-model', key: 'fixture-key' } }
86
+ PWN::Env[:ai] = { active: :ollama, ollama: { model: 'different-model', base_uri: 'http://fixture.invalid' } }
87
+ previous = Thread.current[:pwn_request_runtime]
88
+ foreign = double('foreign request')
89
+ Thread.current[:pwn_request_runtime] = foreign
90
+ expect(foreign).not_to receive(:provider_config)
91
+ expect(PWN::AI::Ollama).not_to receive(:chat)
92
+ allow(PWN::AI::Router).to receive(:summarize).and_call_original
93
+ expect(PWN::AI::OpenAI).to receive(:open_ai_rest_call) do |opts|
94
+ expect(opts[:http_body][:model]).to eq('captured-model')
95
+ prompt = opts[:http_body][:messages].last[:content]
96
+ expect(prompt).to include('Repair login certificate')
97
+ expect(prompt).not_to include('Unrelated other session')
98
+ JSON.generate(choices: [{ message: { role: 'assistant', content: JSON.generate(title: 'Login certificate recovery', summary: 'Repaired login certificates.') } }])
99
+ end
100
+ result = described_class.refresh_title(session_id: sid, ai_config: config)
101
+ expect(result).to include(title: 'Login certificate recovery', title_source: 'summary', summary_turns: 1)
102
+ expect(Thread.current[:pwn_request_runtime]).to equal(foreign)
103
+ expect(described_class.metadata(session_id: other)[:title_source]).not_to eq('summary')
104
+ ensure
105
+ Thread.current[:pwn_request_runtime] = previous
106
+ end
107
+
10
108
  it 'rejects provider echoed placeholder titles without advancing summary provenance' do
11
109
  session = described_class.create
12
110
  sid = session[:id]
13
111
  described_class.append(session_id: sid, role: 'user', content: 'Explain session locking')
14
112
  allow(PWN::AI::Router).to receive(:summarize).and_return(JSON.generate(title: "pwn-ai session #{sid}", summary: 'Session locking explained'))
15
113
  original = described_class.metadata(session_id: sid)
16
- expect(described_class.refresh_title(session_id: sid)).to eq(original)
114
+ failures = []
115
+ expect(described_class.refresh_title(session_id: sid, on_error: failures.method(:push))).to eq(original)
116
+ expect(failures).to eq(['ArgumentError'])
17
117
  expect(described_class.metadata(session_id: sid)).to eq(original)
18
118
  end
19
119
 
@@ -23,10 +123,10 @@ describe PWN::Sessions do
23
123
  described_class.create(id: id)
24
124
  observer = described_class.create(id: '20260709_172057_49594079')
25
125
  25.times do
26
- listing = JSON.generate(described_class.list)
126
+ listing = JSON.generate(described_class.list(include_hidden: true))
27
127
  File.open(observer[:path], 'a') { |file| file.puts(JSON.generate(role: 'tool', content: listing)) }
28
128
  end
29
- result = described_class.list.find { |row| row[:id] == id }
129
+ result = described_class.list(include_hidden: true).find { |row| row[:id] == id }
30
130
  expect(result[:dependencies]).to eq([])
31
131
  expect(result[:dependency_errors]).to eq([])
32
132
  end
@@ -100,7 +200,7 @@ describe PWN::Sessions do
100
200
  'artifacts/manifest.jsonl' => { session: "#{sid}.extra", tags: [sid], source_path: "/tmp/#{sid}.jsonl" }
101
201
  }
102
202
  fixtures.each { |relative, value| dependency_fixture(relative, value) }
103
- expect(described_class.dependency_index).to eq(dependencies: {}, errors: [])
203
+ expect(described_class.dependency_index).to eq(dependencies: {}, errors: [], session_errors: {}, invalid_records: [])
104
204
  end
105
205
 
106
206
  it 'recognizes only exact session-owned paths and exact structured evidence paths' do
@@ -129,7 +229,7 @@ describe PWN::Sessions do
129
229
  session = described_class.create(id: sid)
130
230
  File.write(session[:path], JSON.generate(role: 'tool', content: { session_id: other }, session_id: other))
131
231
  File.write(session[:path].sub('.jsonl', '.meta.json'), JSON.generate(id: sid, title: other, source: other, summary: JSON.generate(session_id: other)))
132
- expect(described_class.dependency_index).to eq(dependencies: {}, errors: [])
232
+ expect(described_class.dependency_index).to eq(dependencies: {}, errors: [], session_errors: {}, invalid_records: [])
133
233
  end
134
234
 
135
235
  it 'reports unknown stores and malformed structural references without guessing' do
@@ -146,7 +246,7 @@ describe PWN::Sessions do
146
246
 
147
247
  it 'does not treat an extensionless session-looking evidence path as a transcript' do
148
248
  dependency_fixture('findings.jsonl', { evidence_paths: [File.join(described_class.sessions_dir, sid)] })
149
- expect(described_class.dependency_index).to eq(dependencies: {}, errors: [])
249
+ expect(described_class.dependency_index).to eq(dependencies: {}, errors: [], session_errors: {}, invalid_records: [])
150
250
  end
151
251
 
152
252
  it 'fails closed for null map entries, invalid JSON, unreadable stores and unsafe embeddings' do
@@ -154,8 +254,8 @@ describe PWN::Sessions do
154
254
  learning = dependency_fixture('learning.jsonl', {})
155
255
  File.write(learning, '{')
156
256
  memory = dependency_fixture('memory.json', {})
157
- allow(File).to receive(:read).and_call_original
158
- allow(File).to receive(:read).with(memory).and_raise(Errno::EACCES)
257
+ allow(File).to receive(:binread).and_call_original
258
+ allow(File).to receive(:binread).with(memory).and_raise(Errno::EACCES)
159
259
  database = File.join(Dir.home, '.pwn', 'embeddings', "#{sid}.db")
160
260
  FileUtils.mkdir_p(database)
161
261
  result = described_class.dependency_index
@@ -165,13 +265,13 @@ describe PWN::Sessions do
165
265
  it 'distinguishes swarm artifact IDs and unrelated observation tags from session provenance' do
166
266
  dependency_fixture('artifacts/manifest.jsonl', { session: sid, kind: 'swarm-bus' })
167
267
  dependency_fixture('extrospection.json', { observations: [{ source: 'auto_extrospect', tags: ['drift', 'unrelated', sid] }] })
168
- expect(described_class.dependency_index).to eq(dependencies: {}, errors: [])
268
+ expect(described_class.dependency_index).to eq(dependencies: {}, errors: [], session_errors: {}, invalid_records: [])
169
269
  end
170
270
 
171
271
  it 'does not accept session ID substrings, whitespace or trailing newlines as references' do
172
272
  ["prefix#{sid}", "#{sid}suffix", " #{sid}", "#{sid}\n", sid.upcase, 'unrelated-session'].each do |value|
173
273
  dependency_fixture('learning.jsonl', { session_id: value })
174
- expect(described_class.dependency_index).to eq(dependencies: {}, errors: [])
274
+ expect(described_class.dependency_index).to eq(dependencies: {}, errors: [], session_errors: {}, invalid_records: [])
175
275
  end
176
276
  end
177
277
  end
@@ -219,8 +319,8 @@ describe PWN::Sessions do
219
319
  stored = JSON.generate(title: long, title_source: 'summary', summary: 'Keep this complete summary.', summary_turns: 2)
220
320
  File.write(path, stored)
221
321
  transcript = File.binread(session[:path])
222
- expect(described_class.list.first[:title]).to eq('One two three four five six seven')
223
- expect(described_class.resolve(identifier: described_class.list.first[:title])).to eq(session[:id])
322
+ expect(described_class.list(include_hidden: true).first[:title]).to eq('One two three four five six seven')
323
+ expect(described_class.resolve(identifier: described_class.list(include_hidden: true).first[:title])).to eq(session[:id])
224
324
  expect(described_class.metadata(session_id: session[:id])[:summary]).to eq('Keep this complete summary.')
225
325
  expect(File.binread(path)).to eq(stored)
226
326
  expect(File.binread(session[:path])).to eq(transcript)
@@ -253,7 +353,7 @@ describe PWN::Sessions do
253
353
  it 'persists an early grounded title and resolves exact titles without changing ids' do
254
354
  session = described_class.create(id: 'title_test')
255
355
  described_class.append(session_id: session[:id], role: 'user', content: 'Investigate café "login" failures')
256
- row = described_class.list.find { |item| item[:id] == session[:id] }
356
+ row = described_class.list(include_hidden: true).find { |item| item[:id] == session[:id] }
257
357
  expect(row[:title]).to eq('Investigate café "login" failures')
258
358
  expect(described_class.resolve(identifier: row[:title])).to eq('title_test')
259
359
  expect(described_class.resolve(identifier: 'title_test')).to eq('title_test')
@@ -276,11 +376,11 @@ describe PWN::Sessions do
276
376
 
277
377
  it 'resumes a listed title after an asynchronous refresh and refuses ambiguous historical names' do
278
378
  sid = described_class.create(id: 'listed_before_refresh', title: 'Displayed café title')[:id]
279
- displayed = described_class.list.first[:title]
379
+ displayed = described_class.list(include_hidden: true).first[:title]
280
380
  described_class.append(session_id: sid, content: 'Repair login')
281
381
  allow(PWN::AI::Router).to receive(:summarize).and_return(JSON.generate(title: 'Updated login repair', summary: 'Repaired login'))
282
382
  described_class.refresh_title(session_id: sid)
283
- expect(described_class.list.first[:title]).to eq('Updated login repair')
383
+ expect(described_class.list(include_hidden: true).first[:title]).to eq('Updated login repair')
284
384
  expect(described_class.resolve(identifier: displayed)).to eq(sid)
285
385
  described_class.create(id: 'duplicate_old_title', title: displayed)
286
386
  expect { described_class.resolve(identifier: displayed) }.to raise_error(ArgumentError, /Ambiguous.*listed_before_refresh.*duplicate_old_title|Ambiguous.*duplicate_old_title.*listed_before_refresh/)
@@ -298,7 +398,7 @@ describe PWN::Sessions do
298
398
  expect(described_class.metadata(session_id: session[:id])).to include(id: 'legacy', title: 'Legacy title')
299
399
  File.write(session[:path], JSON.generate(role: 'user', content: 'old turn'))
300
400
  File.delete(path)
301
- expect(described_class.list.first[:title]).to eq('pwn-ai session legacy')
401
+ expect(described_class.list(include_hidden: true).first[:title]).to eq('pwn-ai session legacy')
302
402
  end
303
403
 
304
404
  it 'preserves the previous title and retries after invalid or unavailable summaries' do
@@ -2268,6 +2268,7 @@
2268
2268
  {"messages":[{"role":"user","content":"PWN::JSONText.help Usage"},{"role":"assistant","content":"`PWN::JSONText.help`: "}]}
2269
2269
  {"messages":[{"role":"user","content":"PWN::JSONText.prepare Usage"},{"role":"assistant","content":"`PWN::JSONText.prepare`: Supported Method Parameters\n\nsafe = PWN::JSONText.prepare(\n\nvalue: 'required - string, hash, or array that may contain binary-tagged text',\ndepth: 'optional - nesting already walked; containers stop at 100'\n\n)\n"}]}
2270
2270
  {"messages":[{"role":"user","content":"PWN::Memory.archive_expired! Usage"},{"role":"assistant","content":"`PWN::Memory.archive_expired!`: "}]}
2271
+ {"messages":[{"role":"user","content":"PWN::Memory.atomic_write Usage"},{"role":"assistant","content":"`PWN::Memory.atomic_write`: "}]}
2271
2272
  {"messages":[{"role":"user","content":"PWN::Memory.authors Usage"},{"role":"assistant","content":"`PWN::Memory.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
2272
2273
  {"messages":[{"role":"user","content":"PWN::Memory.clear Usage"},{"role":"assistant","content":"`PWN::Memory.clear`: Supported Method Parameters\n\nPWN::Memory.clear(force: true)\n"}]}
2273
2274
  {"messages":[{"role":"user","content":"PWN::Memory.current_session_id Usage"},{"role":"assistant","content":"`PWN::Memory.current_session_id`: "}]}
@@ -2290,6 +2291,8 @@
2290
2291
  {"messages":[{"role":"user","content":"PWN::Memory.save Usage"},{"role":"assistant","content":"`PWN::Memory.save`: Supported Method Parameters\n\nPWN::Memory.save(mem: memory_hash)\n"}]}
2291
2292
  {"messages":[{"role":"user","content":"PWN::Memory.session_turns Usage"},{"role":"assistant","content":"`PWN::Memory.session_turns`: "}]}
2292
2293
  {"messages":[{"role":"user","content":"PWN::Memory.to_context Usage"},{"role":"assistant","content":"`PWN::Memory.to_context`: Supported Method Parameters\n\ncontext = PWN::Memory.to_context(limit: 20) (used internally by pwn-ai hook to inject into system prompt)\n"}]}
2294
+ {"messages":[{"role":"user","content":"PWN::Memory.transaction Usage"},{"role":"assistant","content":"`PWN::Memory.transaction`: "}]}
2295
+ {"messages":[{"role":"user","content":"PWN::Memory.transaction_owned? Usage"},{"role":"assistant","content":"`PWN::Memory.transaction_owned?`: "}]}
2293
2296
  {"messages":[{"role":"user","content":"PWN::Memory.turn_pairs Usage"},{"role":"assistant","content":"`PWN::Memory.turn_pairs`: "}]}
2294
2297
  {"messages":[{"role":"user","content":"PWN::MemoryIndex.authors Usage"},{"role":"assistant","content":"`PWN::MemoryIndex.authors`: Author(s)\n\n0day Inc. <support@0dayinc.com>\n"}]}
2295
2298
  {"messages":[{"role":"user","content":"PWN::MemoryIndex.available? Usage"},{"role":"assistant","content":"`PWN::MemoryIndex.available?`: Supported Method Parameters\n\nbool = PWN::MemoryIndex.available?\n"}]}
@@ -4632,14 +4635,18 @@
4632
4635
  {"messages":[{"role":"user","content":"PWN::Sessions.append Usage"},{"role":"assistant","content":"`PWN::Sessions.append`: Supported Method Parameters\n\nPWN::Sessions.append(\n\nsession_id: 'required',\nrole: 'user|assistant|system|observation',\ncontent: 'the message or obs'\n\n)\n"}]}
4633
4636
  {"messages":[{"role":"user","content":"PWN::Sessions.authors Usage"},{"role":"assistant","content":"`PWN::Sessions.authors`: "}]}
4634
4637
  {"messages":[{"role":"user","content":"PWN::Sessions.bounded_title Usage"},{"role":"assistant","content":"`PWN::Sessions.bounded_title`: "}]}
4638
+ {"messages":[{"role":"user","content":"PWN::Sessions.catalog Usage"},{"role":"assistant","content":"`PWN::Sessions.catalog`: "}]}
4635
4639
  {"messages":[{"role":"user","content":"PWN::Sessions.cleanup_transcript_valid? Usage"},{"role":"assistant","content":"`PWN::Sessions.cleanup_transcript_valid?`: "}]}
4636
4640
  {"messages":[{"role":"user","content":"PWN::Sessions.compact_transcript! Usage"},{"role":"assistant","content":"`PWN::Sessions.compact_transcript!`: "}]}
4641
+ {"messages":[{"role":"user","content":"PWN::Sessions.complete_policy_trajectory? Usage"},{"role":"assistant","content":"`PWN::Sessions.complete_policy_trajectory?`: "}]}
4637
4642
  {"messages":[{"role":"user","content":"PWN::Sessions.create Usage"},{"role":"assistant","content":"`PWN::Sessions.create`: Supported Method Parameters\n\nsession = PWN::Sessions.create(\n\ntitle: 'optional - human title, capped at seven whitespace-separated words',\nsource: 'optional - e.g. pwn-ai',\nid: 'optional - fixed session id (tests / replay); default timestamp_hex',\nactive: 'optional - return an owned lease with the new session'\n\n)\n"}]}
4638
4643
  {"messages":[{"role":"user","content":"PWN::Sessions.deactivate Usage"},{"role":"assistant","content":"`PWN::Sessions.deactivate`: Supported Method Parameters\n\nPWN::Sessions.deactivate(lease: ‘required - handle returned by activate’)\n"}]}
4639
4644
  {"messages":[{"role":"user","content":"PWN::Sessions.delete Usage"},{"role":"assistant","content":"`PWN::Sessions.delete`: Supported Method Parameters\n\nPWN::Sessions.delete(\n\nsession_id: 'required',\nforce: 'optional - Boolean bypass pin policy (default false)'\n\n)\n"}]}
4645
+ {"messages":[{"role":"user","content":"PWN::Sessions.dependency_error_owners Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_error_owners`: "}]}
4640
4646
  {"messages":[{"role":"user","content":"PWN::Sessions.dependency_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_ids`: "}]}
4641
4647
  {"messages":[{"role":"user","content":"PWN::Sessions.dependency_index Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_index`: Supported Method Parameters\n\nreferences = PWN::Sessions.dependency_index\n"}]}
4642
4648
  {"messages":[{"role":"user","content":"PWN::Sessions.dependency_select Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_select`: "}]}
4649
+ {"messages":[{"role":"user","content":"PWN::Sessions.dependency_units Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_units`: "}]}
4643
4650
  {"messages":[{"role":"user","content":"PWN::Sessions.dependency_value Usage"},{"role":"assistant","content":"`PWN::Sessions.dependency_value`: "}]}
4644
4651
  {"messages":[{"role":"user","content":"PWN::Sessions.event_dependency_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.event_dependency_ids`: "}]}
4645
4652
  {"messages":[{"role":"user","content":"PWN::Sessions.expand_tokens Usage"},{"role":"assistant","content":"`PWN::Sessions.expand_tokens`: "}]}
@@ -4650,6 +4657,8 @@
4650
4657
  {"messages":[{"role":"user","content":"PWN::Sessions.load Usage"},{"role":"assistant","content":"`PWN::Sessions.load`: Supported Method Parameters\n\ntranscript = PWN::Sessions.load(session_id: ‘required’)\n"}]}
4651
4658
  {"messages":[{"role":"user","content":"PWN::Sessions.memory_dependency_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.memory_dependency_ids`: "}]}
4652
4659
  {"messages":[{"role":"user","content":"PWN::Sessions.metadata Usage"},{"role":"assistant","content":"`PWN::Sessions.metadata`: "}]}
4660
+ {"messages":[{"role":"user","content":"PWN::Sessions.mistake_dependency_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.mistake_dependency_ids`: "}]}
4661
+ {"messages":[{"role":"user","content":"PWN::Sessions.practice_dependency_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.practice_dependency_ids`: "}]}
4653
4662
  {"messages":[{"role":"user","content":"PWN::Sessions.previous_id Usage"},{"role":"assistant","content":"`PWN::Sessions.previous_id`: Supported Method Parameters\n\nid = PWN::Sessions.previous_id(\n\nexclude_session_id: 'optional - current session to skip'\n\n)\n"}]}
4654
4663
  {"messages":[{"role":"user","content":"PWN::Sessions.protected_session_ids Usage"},{"role":"assistant","content":"`PWN::Sessions.protected_session_ids`: "}]}
4655
4664
  {"messages":[{"role":"user","content":"PWN::Sessions.provisional_title Usage"},{"role":"assistant","content":"`PWN::Sessions.provisional_title`: "}]}
@@ -4658,12 +4667,15 @@
4658
4667
  {"messages":[{"role":"user","content":"PWN::Sessions.redact Usage"},{"role":"assistant","content":"`PWN::Sessions.redact`: "}]}
4659
4668
  {"messages":[{"role":"user","content":"PWN::Sessions.refresh_title Usage"},{"role":"assistant","content":"`PWN::Sessions.refresh_title`: "}]}
4660
4669
  {"messages":[{"role":"user","content":"PWN::Sessions.register_activity_owner Usage"},{"role":"assistant","content":"`PWN::Sessions.register_activity_owner`: "}]}
4670
+ {"messages":[{"role":"user","content":"PWN::Sessions.request_checkpoint_dependencies Usage"},{"role":"assistant","content":"`PWN::Sessions.request_checkpoint_dependencies`: "}]}
4661
4671
  {"messages":[{"role":"user","content":"PWN::Sessions.resolve Usage"},{"role":"assistant","content":"`PWN::Sessions.resolve`: "}]}
4662
4672
  {"messages":[{"role":"user","content":"PWN::Sessions.retain Usage"},{"role":"assistant","content":"`PWN::Sessions.retain`: "}]}
4673
+ {"messages":[{"role":"user","content":"PWN::Sessions.retention_status Usage"},{"role":"assistant","content":"`PWN::Sessions.retention_status`: Supported Method Parameters\n\nstatus = PWN::Sessions.retention_status(session_id: id, references: index)\n"}]}
4663
4674
  {"messages":[{"role":"user","content":"PWN::Sessions.sessions_dir Usage"},{"role":"assistant","content":"`PWN::Sessions.sessions_dir`: Supported Method Parameters\n\ndir = PWN::Sessions.sessions_dir\n"}]}
4664
4675
  {"messages":[{"role":"user","content":"PWN::Sessions.stats Usage"},{"role":"assistant","content":"`PWN::Sessions.stats`: Supported Method Parameters\n\nstats = PWN::Sessions.stats\n"}]}
4665
4676
  {"messages":[{"role":"user","content":"PWN::Sessions.stub_session? Usage"},{"role":"assistant","content":"`PWN::Sessions.stub_session?`: "}]}
4666
4677
  {"messages":[{"role":"user","content":"PWN::Sessions.summary_title_valid? Usage"},{"role":"assistant","content":"`PWN::Sessions.summary_title_valid?`: "}]}
4678
+ {"messages":[{"role":"user","content":"PWN::Sessions.support_path Usage"},{"role":"assistant","content":"`PWN::Sessions.support_path`: Supported Method Parameters\n\npath = PWN::Sessions.support_path(kind: :metadata, session_id: id)\n"}]}
4667
4679
  {"messages":[{"role":"user","content":"PWN::Sessions.title_status Usage"},{"role":"assistant","content":"`PWN::Sessions.title_status`: Supported Method Parameters\n\nstatus = PWN::Sessions.title_status(session_id: ‘required - canonical session ID’)\n"}]}
4668
4680
  {"messages":[{"role":"user","content":"PWN::Sessions.to_llm_messages Usage"},{"role":"assistant","content":"`PWN::Sessions.to_llm_messages`: "}]}
4669
4681
  {"messages":[{"role":"user","content":"PWN::Sessions.to_response_history Usage"},{"role":"assistant","content":"`PWN::Sessions.to_response_history`: Supported Method Parameters\n\nhistory_for_ai = PWN::Sessions.to_response_history(session_id:) (converts transcript to the response_history format used by PWN::AI::* .chat)\n"}]}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.782
4
+ version: 0.5.783
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.