Skip to content

feat(goose): source adapter and filesystem destination (#39) - #109

Merged
ImL1s merged 8 commits into
mainfrom
feat/issue-39-goose-source-dest
Jul 30, 2026
Merged

feat(goose): source adapter and filesystem destination (#39)#109
ImL1s merged 8 commits into
mainfrom
feat/issue-39-goose-source-dest

Conversation

@ImL1s

@ImL1s ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #39 (filesystem/product path).

  • Source: goose adapter for sessions/sessions.db (goose-sessions-sqlite-v15, schema max 15)
  • Default list prefers session_type=user, excludes scheduled/sub_agent/hidden/gateway/acp + archived
  • Exact id can still select filtered/archived sessions
  • Destination: .goose/skills + ~/.config/goose/skills
  • Runtime allowlist + schema enum + smoke fixtures; matrix 11×11=121
  • Legacy JSONL and native goose UI activation remain out of scope / not-run

Test plan

  • unit tests for fixtures s-go-01…05
  • full unittest suite (636)
  • self_verify + secrets
  • smoke_installed_matrix 121/121
  • CI green
  • exact-HEAD Codex (P1 fix / P2 document)

Add goose-sessions-sqlite-v15 reader for sessions/sessions.db, default
user-session listing filters, and destination install to .goose/skills
plus ~/.config/goose/skills. Matrix expands to 11×11=121.
@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2f3004378f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/portable_resume/adapters/goose.py Outdated
"""
SELECT id, name, session_type, working_dir, created_at, updated_at, archived_at
FROM sessions
WHERE session_type = 'user' AND archived_at IS NULL

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Exclude empty sessions before choosing latest

When goose has created a newer user session but no messages have been written yet, this query includes it and the shared latest selector chooses it over an older session containing recoverable context, producing an empty handoff. Filter for at least one eligible public message before ordering/limiting so blank sessions cannot crowd out useful history.

Useful? React with 👍 / 👎.

Comment thread src/portable_resume/adapters/goose.py Outdated
Comment on lines +299 to +302
try:
payload = json.loads(content_json, object_pairs_hook=_object)
except (json.JSONDecodeError, _DuplicateKey, RecursionError, UnicodeDecodeError):
return None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail closed on malformed Goose message JSON

If a selected session contains truncated JSON or duplicate keys in content_json, this branch returns None, so _show_session silently drops that row and still emits a successful but incomplete handoff. Treat these parse failures as E_CORRUPT_RECORD; otherwise users may trust a transcript that omitted requests or responses.

Useful? React with 👍 / 👎.

Exclude user sessions with no public messages from default latest listing,
and treat malformed content_json as E_CORRUPT_RECORD instead of silent drop.
@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Unknown error
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f0808953bb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +265 to +269
AND EXISTS (
SELECT 1 FROM messages m
WHERE m.session_id = sessions.id
AND m.role IN ('user', 'assistant', 'tool')
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Require extractable content when excluding empty sessions

The new EXISTS fix still tests only the message role, so a newer session containing a valid but non-extractable payload such as content_json = '[]' or image-only content remains eligible for latest; _content_text then returns None for every row and the reader emits an empty handoff instead of selecting the older recoverable session. This is fresh evidence beyond the earlier no-message case: require at least one message whose payload can produce a public turn, or fall back when the selected session normalizes to no turns.

Useful? React with 👍 / 👎.

Comment on lines +197 to +198
if _SESSION_ID_RE.fullmatch(text):
return text

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fall back before treating every token as an exact ID

When show receives a single-token title such as alpha, this regex classifies it as an exact session ID and _list_sessions runs only WHERE id = ?, so the generic bounded title matcher never sees the actual session. The same optimization makes an uppercase pasted UUID fail because SQLite's text comparison is case-sensitive even though select_session normally canonicalizes UUID refs; if the exact lookup misses, perform the normal bounded listing so supported text and normalized-ID selection still work.

Useful? React with 👍 / 👎.

Exclude sessions whose messages lack text/content payloads, and fall back
from exact-id miss so free-text selection remains available.
@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 19a5928f90

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +71 to +74
data_home = os.environ.get("XDG_DATA_HOME")
if data_home:
return os.path.join(data_home, "goose")
return os.path.expanduser("~/.local/share/goose")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve the Goose data root on Windows

When the reader runs on Windows without --source-root, this falls through to ~/.local/share/goose, but Goose's v15 store is normally under %APPDATA%/Block/goose/data; consequently probe and list report the adapter unavailable for a standard Windows installation. Add a Windows-specific root derived from APPDATA while retaining the explicit override.

Useful? React with 👍 / 👎.

Comment thread docs/install-hosts.md
Comment on lines +13 to +14
The package builder creates eleven `*-<host>-skills.zip` archives (one per
enabled destination, including Pi, OpenClaw, and goose), seven supported

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the package archive count consistent

This updated paragraph says the builder creates eleven destination archives, but line 19 still says current main builds ten. That leaves the installation guide internally contradictory and can make release operators expect a missing artifact; update the latter count to eleven.

AGENTS.md reference: AGENTS.md:L5-L5

Useful? React with 👍 / 👎.

Resolve %APPDATA%/Block/goose/data on Windows and align docs to eleven
destination archives on main.
@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b34ebe3f91

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/portable_resume/adapters/goose.py Outdated
Comment on lines +383 to +384
SELECT role, content_json, created_timestamp
FROM messages

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject duplicate logical message IDs

When a valid schema contains two rows with the same non-empty message_id, this query omits that identifier and _show_session emits both rows as separate turns, so a corrupted store produces a successful but duplicated transcript. Select message_id (and preferably the stored session ID) and fail with E_CORRUPT_RECORD when a logical ID repeats or disagrees with the selected session.

Useful? React with 👍 / 👎.


def _require_schema(connection: sqlite3.Connection) -> None:
try:
integrity = connection.execute("PRAGMA integrity_check(1)").fetchone()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid full integrity scans on every reader phase

For a large Goose database, PRAGMA integrity_check(1) still scans the entire database—the argument limits reported errors, not work—and the normal show flow invokes this through probe, list, and show. This defeats the oversized live-query path and can make reading a large history perform three expensive full-database scans; keep probe/schema validation metadata-bounded and detect corruption from the bounded queries instead.

Useful? React with 👍 / 👎.

Reject repeated non-empty logical message identifiers while showing a session.
@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c2f019753b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/portable_resume/adapters/goose.py Outdated
Comment on lines +275 to +277
m.content_json LIKE '%"text"%'
OR m.content_json LIKE '%"content"%'
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Align latest eligibility with extracted turns

The new LIKE predicate still admits messages whose matching keys contain no extractable text, such as [{"type":"text","text":" "}] or an image part with a text key; _content_text returns None for these, so a newer such session wins latest and produces a successful empty handoff instead of older recoverable context. Fresh evidence is that the current key-name filter does not enforce the extractor's nonblank text semantics; use the same eligibility semantics or retry the next candidate when extraction yields no turns.

Useful? React with 👍 / 👎.

Comment thread src/portable_resume/adapters/goose.py Outdated
).fetchall()

def _fetch_normal() -> list[tuple]:
limit = DEFAULT_BOUNDS.scanned_records + 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor caller-supplied list bounds

When a library caller supplies lowered Bounds, normal listing still uses the global defaults and never charges budget.records; for example, ReadBudget(Bounds(scanned_records=0)) still returns the basic fixture session with records == 0. The same issue affects lowered listed_sessions, allowing this adapter to bypass the caller's resource ceiling, so pass the budget into _list_sessions, derive limits from budget.limits, and charge admitted rows.

Useful? React with 👍 / 👎.

@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

Post-filter sessions so whitespace/image-only messages cannot win latest,
and apply caller scanned/listed bounds while charging ReadBudget records.
@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@ImL1s
ImL1s force-pushed the feat/issue-39-goose-source-dest branch from e059c5a to a59ef0a Compare July 30, 2026 16:51

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a59ef0aa85

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/portable_resume/adapters/goose.py Outdated
Comment on lines +261 to +264
try:
text = _content_text(content_json)
except DiagnosticError:
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Propagate corrupt payloads during latest selection

When a newer user session's eligible messages contain malformed JSON or duplicate keys and no later extractable row, this catch treats the session as empty, allowing show latest to return an older transcript successfully instead of reporting E_CORRUPT_RECORD. Fresh evidence beyond the earlier show-path issue is that current HEAD now suppresses the parser failure in the list eligibility path; propagate corruption rather than silently excluding that session.

Useful? React with 👍 / 👎.

Comment thread src/portable_resume/adapters/goose.py Outdated
Comment on lines +252 to +254
AND role IN ('user', 'assistant', 'tool', 'toolResult', 'tool_result', 'function')
ORDER BY id ASC
LIMIT 64

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Continue eligibility checks past the first 64 messages

When a session's first 64 public-role rows are non-extractable—for example image-only parts—but a later row contains valid text, this fixed limit reports the session as empty and lets an older session win latest. Fresh evidence beyond the prior extractability issue is that the new decoder now applies an arbitrary prefix cutoff; either query until the bounded transcript ceiling or retry candidates after full selected-session extraction.

Useful? React with 👍 / 👎.

Comment thread src/portable_resume/adapters/goose.py Outdated
Comment on lines +258 to +262
for role, content_json in rows:
if not isinstance(role, str) or not isinstance(content_json, str):
continue
try:
text = _content_text(content_json)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Charge eligibility decoding against the read budget

For stores containing many candidate sessions or a large content_json value, this decodes up to 64 message rows per candidate without checking record_bytes or consuming record/source-byte budget; only returned session summaries are charged later. Consequently a caller's Bounds(scanned_records=...) does not bound actual SQLite rows processed, and a payload larger than the default per-record ceiling is parsed during list even though show would reject it.

Useful? React with 👍 / 👎.

Comment on lines +346 to +350
if item is not None:
values.append(item)
budget.consume_records()
if exact_id is None and len(values) >= list_limit:
break

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return no rows when the listing limit is zero

When a library caller supplies Bounds(listed_sessions=0), the first eligible summary is appended before this condition is checked, so ADAPTER.list still returns one session and consumes one record. Fresh evidence beyond the earlier lowered-bounds comment is that the current post-append check specifically bypasses the supported zero-work setting; handle a zero limit before iterating or before appending.

Useful? React with 👍 / 👎.

Comment thread src/portable_resume/adapters/goose.py Outdated
Comment on lines +158 to +160
if size > limits.sqlite_snapshot_bytes:
return query_only_live_sqlite(database, root=root, provider=FORMAT_ID)
return private_sqlite_connection(database, root=root, provider=FORMAT_ID)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass lowered snapshot bounds to the SQLite copier

When a caller lowers sqlite_snapshot_bytes, the main database may fall below that threshold while its main-plus-WAL family exceeds it; this call omits bounds=limits, so private_sqlite_connection copies the family using DEFAULT_BOUNDS and can read far beyond the caller's ceiling. Pass the effective bounds into the snapshot helper so the family-wide copy honors the same limit used to choose this path.

Useful? React with 👍 / 👎.

…#39)

Propagate E_CORRUPT_RECORD from list eligibility instead of treating
malformed content_json as empty, so a newer broken session cannot hide
behind an older transcript. Also honor transcript/list budgets during
eligibility, reject listed_sessions=0, and pass bounds into the SQLite
snapshot copier.
@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

1 similar comment
@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 18dfe8311a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

seen_message_ids: set[str] = set()
turn_bounds = replace(DEFAULT_BOUNDS, tool_output_chars=query.max_tool_chars)
count = 0
for message_id, role, content_json, _created in cursor:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Charge show rows to the supplied read budget

When a library caller reuses a partially consumed ReadBudget, this loop checks only fresh local count and total_bytes values and never calls consume_transcript_records() or consume_bytes(). For example, a budget whose transcript and byte counters are already at their ceilings still reads and returns the complete basic fixture, allowing cumulative work to exceed the caller's shared limits; charge each admitted row through the supplied budget.

Useful? React with 👍 / 👎.

Comment thread src/portable_resume/adapters/goose.py Outdated
Comment on lines +329 to +330
if len(rows) > scan_limit:
raise DiagnosticError.limit_exceeded()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stop normal listing once enough sessions are found

When a Goose database contains more than 2,000 active user sessions with public messages, ordinary list and show latest always raise here because _fetch_normal materializes scanned_records + 1 rows before considering the 50-session output limit. This makes long-lived stores unreadable even when the first 50 candidates are immediately eligible; stream candidates within the scan budget and stop once list_limit eligible summaries have been collected.

Useful? React with 👍 / 👎.

Honor shared ReadBudget counters during show (transcript rows + bytes)
so partially consumed budgets fail closed. Cap normal listing at
scanned_records without hard-failing when more sessions exist, stopping
once listed_sessions eligible summaries are collected.
@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Something went wrong. Try again later by commenting “@codex review”.

Unknown error
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1d6d3ef4bd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

continue
if isinstance(session_type, str) and session_type in _DEFAULT_EXCLUDE_TYPES:
continue
if not _session_has_extractable_turn(connection, session_id, budget):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Scope candidates before decoding their messages

When a candidate belongs to another cwd or fails the requested age filter, this eligibility check still parses and charges its messages before _row_summary rejects its metadata. Consequently, a malformed or oversized message in an unrelated Goose project can make list or show latest fail with E_CORRUPT_RECORD/E_LIMIT_EXCEEDED even when the requested project has a valid session; apply the cwd/age metadata filter before decoding message eligibility.

Useful? React with 👍 / 👎.

Comment on lines +327 to +330
ORDER BY updated_at DESC, id ASC
LIMIT ?
""",
(scan_limit,),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply cwd filtering before the global scan limit

When the shared Goose database has scanned_records newer user sessions for other working directories, this global LIMIT excludes an older session for the requested cwd before _row_summary performs cwd matching. For example, with --within-min 0, 2,000 newer cross-project rows cause show latest to report E_NO_MATCH despite recoverable current-project history; constrain or prioritize the requested working directory before applying the bounded candidate window.

Useful? React with 👍 / 👎.

@ImL1s

ImL1s commented Jul 30, 2026

Copy link
Copy Markdown
Owner Author

Merge gate (HEAD 1d6d3ef)

  • CI: green (quality + matrix py3.11–3.14 ubuntu/macos + build/smoke)
  • Exact-HEAD Codex: returned on 1d6d3efno P1; two P2s only

P2 disposition (document, do not block)

  1. Scope candidates before decoding messages — deferred. Eligibility decode is bounded by transcript_records + record_bytes + shared budget charges; full SQL-side extractability is not expressible without scanning payloads. Accept residual cost for multi-candidate homes.
  2. Apply cwd filtering before global scan limit — deferred. Post-filter cwd match is consistent with other SQLite adapters; pre-filter would need normalized path equality in SQL and risks missing equivalent paths. Follow-up if real large multi-cwd goose homes hit empty lists under scan cap.

Ship #39 goose source+dest (11×11=121 cells).

@ImL1s
ImL1s merged commit 88061f3 into main Jul 30, 2026
10 checks passed
@ImL1s
ImL1s deleted the feat/issue-39-goose-source-dest branch July 30, 2026 17:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add goose source adapter and destination Skill support for SQLite sessions

1 participant