Commit graph

675 commits

Author SHA1 Message Date
Nexus Dev
1cf1c1f038 feat(28-02,28-03): Ollama UI surface + Hermes runtime dashboard
28-02: ollamaApi client, model dropdown in config, skill badge
28-03: stateJson merge after heartbeat, HermesRuntimeCard in AgentOverview

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:49 +00:00
Nexus Dev
39327b7660 feat(28-03): merge Hermes runtime data into stateJson and add HermesRuntimeCard
- Add OllamaPsResponse interface and getOllamaMemoryUsage() to ollama.ts
- Import getOllamaMemoryUsage in heartbeat.ts
- Add hermes_local block in updateRuntimeState: COALESCE jsonb merge of hermesModel + hermesMemoryBytes
- Add HermesRuntimeCard component in AgentDetail.tsx
- Render HermesRuntimeCard in AgentOverview gated by adapterType === hermes_local
- Native skill count derived from agentsApi.skills entries with originLabel === Hermes skill
2026-04-04 03:55:49 +00:00
Nexus Dev
5345b67f92 feat(28-01): Ollama service, routes, model catalog
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:48 +00:00
Nexus Dev
9ef04fd1de feat(27-01): close Hermes adapter integration gaps
- Add hermes_local to SESSIONED_LOCAL_ADAPTERS (HERM-03)
- Fix create-mode toolsets field guard (HERM-02)
- Add hermes session codec round-trip tests (HERM-04)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:48 +00:00
Nexus Dev
4b9d267f46 fix(v1.3): close 3 integration gaps from milestone audit
1. Push notifications: call sendPushToAll after streaming completes
2. Mobile offline: add useOfflineQueue + banners to MobileChatView
3. New conversation streaming: call startStream in Path 1 handleSend

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:48 +00:00
Nexus Dev
66bbfbf766 feat(26-04): create push_subscriptions schema, migration, pushService, and push routes
- Add push_subscriptions pgTable with endpoint, p256dh, auth, userId, companyId, deviceLabel
- Add 0055_create_push_subscriptions.sql migration with CREATE TABLE and endpoint index
- Export pushSubscriptions from schema/index.ts
- Create pushService with initVapid, getVapidPublicKey, saveSubscription, removeSubscription, sendPushToAll
- sendPushToAll auto-deletes stale subscriptions on 410/404 response
- Create pushRoutes: GET /vapid-public-key, POST /subscribe, DELETE /subscribe
- Mount /api/push routes and call initVapid() in app.ts with graceful skip
- Install web-push and @types/web-push
2026-04-04 03:55:48 +00:00
Nexus Dev
dae0e3a3be feat(25-06): merge git file service and history endpoint from worktree
Adds gitFileService with commitFile/getLog, wires git commits into
upload flow, adds GET /files/:fileId/history endpoint, and exports
ChatFileHistoryEntry type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:48 +00:00
Nexus Dev
7ab49d9824 feat(25-07): add placeholder and agent-generated file routes
- Import placeholderService and resolveDefaultStorageDir in chat-files routes
- Track agent_generated project-scoped uploads in PLACEHOLDERS.md manifest
- Add POST /files/:fileId/replace endpoint for placeholder replacement
- Replace endpoint updates manifest and creates cross-reference chain
- Mark FILE-08 and FILE-11 Complete in REQUIREMENTS.md
2026-04-04 03:55:48 +00:00
Nexus Dev
859ba1707b feat(25-07): create placeholderService and add markAsPlaceholder method
- Create server/src/services/placeholder-service.ts with addEntry, replaceEntry, listEntries
- Generates PLACEHOLDERS.md with Active Placeholders and Replaced markdown tables
- Add ChatPlaceholderEntry interface to packages/shared/src/types/chat.ts
- Export ChatPlaceholderEntry from packages/shared/src/index.ts
- Add markAsPlaceholder method to chatFileService in chat-files.ts
2026-04-04 03:55:48 +00:00
Nexus Dev
03df062bec feat(25-04): create ChatCodeFilePreview with syntax highlighting
- Add ChatCodeFilePreview component with hljs syntax highlighting
- Fetch file content from contentPath with credentials
- Use DOMParser-based safe rendering (no dangerouslySetInnerHTML)
- Include copy button, language label, and ChatFileCard download below
- Add extToLang extension-to-language mapping
- Register 14 common languages with hljs
- Add highlight.js as direct dependency in ui/package.json
2026-04-04 03:55:48 +00:00
Nexus Dev
64a90c284e feat(25-08): create VoiceRecordButton and server transcription endpoint
- Add VoiceRecordButton with MediaRecorder API, recording/transcribing/idle states
- Add POST /transcribe endpoint to chat-files.ts using execFileAsync (safe, no shell)
- Tries whisper-cpp first, falls back to openai-whisper Python CLI
- Returns 503 with helpful message if whisper is not installed
2026-04-04 03:55:48 +00:00
Nexus Dev
939ebd6dc3 fix(25): handle missing chat_files table in listMessages and update addMessage test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:55:48 +00:00
Nexus Dev
9aee875239 feat(25-03): wire files into ChatMessage, ChatPanel, and server listMessages
- ChatMessage: files prop, renders ChatFilePreview for each attached file
- ChatMessageList: passes files prop through to ChatMessage
- ChatPanel: wires useChatFileUpload, passes pendingFiles/onRemoveFile/onFilesPicked to ChatInput
- ChatPanel handleSend: attaches uploaded files to message after creation, invalidates query
- chatApi: adds attachFilesToMessage (parallel PATCH /files/:fileId for each fileId)
- server/chat.ts: listMessages fetches chatFiles by messageId (inArray), attaches files array
- server/chat.ts: addMessage returns files: [] for consistency
2026-04-04 03:55:48 +00:00
Nexus Dev
928cefa189 feat(25-01): create chatFileRoutes and wire into app.ts
- Create chatFileRoutes with upload, list, content, references, attach endpoints
- Wire into app.ts after assetRoutes, export from routes/index.ts
- Real tests replacing todo stubs in chat-file-routes.test.ts
2026-04-04 03:55:48 +00:00
Nexus Dev
1cf231a540 feat(25-01): create chatFileService with DB operations and deriveCategory helper
- Implement chatFileService(db) with create, getById, listByConversation, listByMessage, createReference, listReferences, attachToMessage
- Export deriveCategory() helper mapping MIME types to image/code/document/other
- Add unit tests verifying service methods and category derivation with mocked DB
2026-04-04 03:55:48 +00:00
Nexus Dev
f335d3762b feat(25-00): add shared types, validators, and test stubs for file system
- Add ChatFile, ChatFileReference, ChatFileUploadResponse, ChatFileListResponse interfaces to types/chat.ts
- Add optional files?: ChatFile[] field to ChatMessage interface
- Add uploadChatFileSchema and createFileReferenceSchema Zod validators to validators/chat.ts
- Re-export all new types and validators from shared/src/index.ts
- Create test stubs for chat-file-service.test.ts and chat-file-routes.test.ts with it.todo() entries
2026-04-04 03:55:48 +00:00
Nexus Dev
505f5e2262 feat(24-01): add search, bookmark, branch, and export Express route handlers
- GET /companies/:companyId/messages/search: FTS search with ZodError 400 guard
- POST /conversations/:id/bookmarks: toggle bookmark with UUID validation
- GET /companies/:companyId/bookmarks: list bookmarks with optional conversationId filter
- POST /conversations/:id/branch: branch conversation from message point
- GET /conversations/:id/branches: list child conversations
- GET /conversations/:id/export: download Markdown or JSON with Content-Disposition header
2026-04-04 03:55:48 +00:00
Nexus Dev
61161a3561 feat(24-01): add searchMessages, toggleBookmark, getBookmarks, branchConversation, listBranches, exportConversation service methods
- searchMessages: tsvector FTS with ts_rank ordering, joins conversations for companyId scoping
- toggleBookmark: transactional insert-or-delete bookmark
- getBookmarks: joins bookmarks+messages+conversations, supports conversationId filter
- branchConversation: copies messages up to branch point into new child conversation
- listBranches: queries child conversations by parentConversationId
- exportConversation: LEFT JOINs agents for name resolution, produces Markdown or JSON with file headers
2026-04-04 03:55:48 +00:00
Nexus Dev
dc6316cf28 feat(24-00): shared types, validators, and Wave 0 test stubs for phase 24
- Add ChatMessageSearchResult, ChatMessageSearchResponse to shared types
- Add ChatBookmark, ChatBookmarkWithMessage, ChatBookmarkListResponse, ChatBookmarkToggleResponse
- Add parentConversationId + branchFromMessageId to ChatConversation and ChatConversationListItem
- Add searchMessagesSchema + branchConversationSchema to validators
- Re-export all new types and validators from shared/src/index.ts
- Add Wave 0 it.todo stubs: searchMessages, toggleBookmark, branchConversation, exportConversation
- Add Wave 0 it.todo stubs for 4 new route groups in chat-routes.test.ts
2026-04-04 03:55:48 +00:00
Nexus Dev
9205ee82e3 feat(23-01): add handoff and status-update routes to chat API
- POST /conversations/:id/handoff: resolves companyId, inserts handoff
  message, creates issue from spec, inserts task_created message
- POST /conversations/:id/status-update: inserts status_update message
- Import issueService and handoffSchema; instantiate issueSvc in chatRoutes
- Both routes use assertBoard for authentication
2026-04-04 03:55:48 +00:00
Nexus Dev
b2038e1884 feat(23-01): extend chat service with messageType support and addSystemMessage
- addMessage now accepts optional messageType parameter
- addSystemMessage helper inserts system-role messages with typed messageType
- Both methods bump conversation updatedAt for correct sort order
2026-04-04 03:55:48 +00:00
Nexus Dev
fcc143cc44 feat(22-01): add SSE streaming endpoint and edit/truncate service methods
- Add editMessage, truncateMessagesAfter, streamEcho methods to chatService
- Add POST /conversations/:id/stream SSE endpoint with flushHeaders before loop (PERF-02)
- Add PATCH /conversations/:id/messages/:msgId for message editing
- Add DELETE /conversations/:id/messages/after/:msgId for message truncation
- Import gt from drizzle-orm for createdAt comparison in truncateMessagesAfter
- Guard all res.write() calls with res.writable check (prevents write-after-end)
2026-04-04 03:55:47 +00:00
Nexus Dev
d6ff48c0f3 feat(21-06): add search and agentId filter to listConversations
- Add ilike import and search/agentId conditions in chatService.listConversations
- Extract search and agentId from req.query in GET /conversations route
- Extend chatApi.listConversations opts with search and agentId params
- Update useChatConversations to accept opts.search and include in queryKey
2026-04-04 03:55:47 +00:00
Nexus Dev
528ad001b5 feat(21-03): add chatRoutes, mount in app.ts, export chat schemas from shared
- chatRoutes factory with 7 REST endpoints for conversations and messages
- All routes gated by assertBoard; company-scoped routes also use assertCompanyAccess
- Mounted as api.use(chatRoutes(db)) after activityRoutes in app.ts
- Export createConversationSchema/updateConversationSchema/createMessageSchema
  from @paperclipai/shared (were missing from main package index)
- 11 vitest route tests passing
2026-04-04 03:55:47 +00:00
Nexus Dev
fb423b4d66 feat(21-03): implement chatService with full conversation + message CRUD
- createConversation, listConversations, getConversation, updateConversation
- softDeleteConversation, listMessages, addMessage
- cursor-based pagination with hasMore for both conversations and messages
- Pitfall 3: addMessage bumps conversation updatedAt after insert
- Pitfall 5: addMessage auto-sets title from first user message (IS NULL guard)
- 21 vitest tests passing
2026-04-04 03:55:47 +00:00
Nexus Dev
ecc293a49c test(21-00): add Wave 0 test stubs for chat service, routes, markdown, and input 2026-04-04 03:55:47 +00:00
8489057f05 [nexus] feat(19-02): adapter-aware route handlers with agentId resolution
- Add resolveSkillsDirForAgent helper to skill-registry.ts and skill-registry-groups.ts
- Install route accepts agentId in body (not agentSkillsDir)
- Uninstall route accepts agentId as query param; returns 403 for native skills
- Rollback route accepts agentId in body (not agentSkillsDir)
- Group assign/remove routes resolve dir from URL agentId param
- List agent skills route calls syncHermesNativeSkills for hermes_local agents
- skillRegistryRoutes(db) and skillGroupRoutes(db) factory signatures updated
- app.ts passes db to both route factories
2026-04-04 03:55:47 +00:00
58d07637fa fix(11): default agentSkillsDir server-side — GROUP-03/GROUP-04 gap closure 2026-04-04 03:55:47 +00:00
bcd5a391d7 feat(09-01): extract GitHub fetch helpers to shared module
- Create github-skill-helpers.ts with fetchText, fetchJson, resolveGitHubDefaultBranch, resolveGitHubCommitSha, parseGitHubSourceUrl, resolveGitHubPinnedRef, resolveRawGitHubUrl
- Update company-skills.ts to import from github-skill-helpers.js instead of defining locally
- All existing company-skill tests pass (15/15)
2026-04-04 03:55:47 +00:00
20ced27baf [nexus] test(19-02): route-level integration tests for adapter-aware skill routes
- Add 18 supertest tests covering install/uninstall/rollback/group routes
- Verify 400 (missing agentId), 404 (unknown agent), 422 (unsupported adapter)
- Verify 403 for native skill deletion
- Verify hermes_local agents trigger syncHermesNativeSkills before list
- Verify group assign resolves dir from URL agentId param
- Fix wildcard route syntax from :skillId(*) to *skillId (Express 5 / path-to-regexp v8)
  resolves pre-existing TS errors for these routes too
2026-04-04 03:55:42 +00:00
955dba52f4 [nexus] feat(19-02): adapter-aware route handlers with agentId resolution
- Add resolveSkillsDirForAgent helper to skill-registry.ts and skill-registry-groups.ts
- Install route accepts agentId in body (not agentSkillsDir)
- Uninstall route accepts agentId as query param; returns 403 for native skills
- Rollback route accepts agentId in body (not agentSkillsDir)
- Group assign/remove routes resolve dir from URL agentId param
- List agent skills route calls syncHermesNativeSkills for hermes_local agents
- skillRegistryRoutes(db) and skillGroupRoutes(db) factory signatures updated
- app.ts passes db to both route factories
2026-04-04 03:55:42 +00:00
d0fc8a3348 [nexus] feat(19-01): unit tests for adapter-aware install/uninstall and Hermes dual-source
- skill-registry-adapter-install.test.ts: 9 tests covering install/uninstall/rollback/assignGroup/removeGroup
- hermes-dual-source.test.ts: 7 tests covering syncHermesNativeSkills idempotency and listAgentSkills object shape
- Fix skill-registry-install.test.ts: update uninstall() callers to pass agentSkillsDir (new required param)
- Fix removeGroup() bug: removed incorrect 'individualSkills' guard that prevented file removal for group-installed skills
  (rule 1 auto-fix: group-installed skills were never removed because they appeared in agentSkills with no way to distinguish from direct installs)
- All 16 new tests pass, all existing tests still pass
2026-04-04 03:55:42 +00:00
666d91da8b [nexus] feat(19-01): adapter-aware skill service layer — source column, uninstall file removal, syncHermesNativeSkills
- agentSkills schema gets source TEXT NOT NULL DEFAULT 'managed' column
- Migration guard in getSkillRegistryDb() handles existing DBs via ALTER TABLE
- uninstall() now accepts agentSkillsDir and removes files before soft-deleting
- syncHermesNativeSkills() reads ~/.hermes/skills/, creates stub rows with source='native'
- listAgentSkills() returns typed objects {skillId, source, installedAt} not string[]
- Interim uninstall route fix: reads agentSkillsDir from query param until Plan 02 wires agentId
2026-04-04 03:55:42 +00:00
d7cff53ded [nexus] test(18-01): add failing tests for adapter skill config resolver
- Add AdapterSkillFormat type and AdapterSkillConfig interface to types.ts
- Create stub adapter-skill-config.ts (throws not implemented)
- Re-export new types and functions from index.ts
- Add comprehensive test file covering all 10 adapter types and fallback
2026-04-04 03:55:42 +00:00
de0f2940df [nexus] fix: restore upstream delegation and fact-extraction content lost during rebase 2026-04-04 03:55:42 +00:00
6244bcb246 feat(12-01): ratings routes, community ratings in fetcher, list/getById JOIN, heartbeat hook
- Add POST/GET /skill-registry/skills/:sourceId/:slug/ratings routes
- Import skillRatingService in skill-registry routes
- Add upsertCommunityRatingsStub() in fetcher, called after each skill upsert
- Import communityRatings from schema in fetcher
- Update list() and getById() in skill-registry.ts to LEFT JOIN communityRatings
- Include averageRating, ratingCount, taskCount, avgCostUsd, lastUsedAt in SkillListItem
- Add agentSkills usage aggregation via LEFT JOIN + SUM/AVG/MAX
- Add fire-and-forget recordUsageForAgent call in heartbeat after finalizeAgentStatus
- Dynamic import keeps skill-registry-ratings off critical startup path
- All 44 skill-registry tests pass, full server suite (536) green
2026-04-04 03:55:42 +00:00
c988bbe7c2 feat(12-01): personalRatings schema, DB DDL, skillRatingService, and tests
- Add personalRatings table to skill-registry-schema.ts
- Add taskCount, avgCostUsd, lastUsedAt columns to agentSkills in schema
- Add CREATE_PERSONAL_RATINGS_TABLE DDL constant in skill-registry-db.ts
- Add ALTER TABLE statements for new agent_skills usage columns (idempotent)
- Create skill-registry-ratings.ts with skillRatingService factory
- rate() appends personal rating, validates stars 1-5
- getRatings() returns ratings ordered by createdAt DESC
- recordUsageForAgent() atomically updates task_count, avg_cost_usd, last_used_at
- All 8 tests pass
2026-04-04 03:55:42 +00:00
f39be25bd2 fix(11): default agentSkillsDir server-side — GROUP-03/GROUP-04 gap closure 2026-04-04 03:55:42 +00:00
155b973e03 feat(11-03): add skill group routes, mount in app.ts, startup reconciliation
- Create server/src/routes/skill-registry-groups.ts with skillGroupRoutes() factory
- All 14 REST routes for group CRUD, members, export/import, and agent assignments
- Import route registered before :groupId param to avoid route collision
- assertBoard on every handler, error classification (400/404/409/500)
- Mount skillGroupRoutes() in app.ts after skillRegistryRoutes()
- Add pendingSkillGroups fire-and-forget reconciliation in index.ts startup
2026-04-04 03:55:42 +00:00
b455942e79 feat(11-02): skillGroupService() with CRUD, membership, inheritance, assignment, import/export
- Group CRUD: listGroups, getGroup, createGroup, updateGroup, deleteGroup (guards built-in)
- Member management: addMember, removeMember, listMembers
- Inheritance: addParent (with cycle detection BFS), removeParent, listParents
- resolveEffectiveSkills: BFS walk with visited-set guard for cycle safety
- assignGroup: installs all effective skills, tracks in agent_skills, returns installed/skipped/pendingPlugin
- removeGroup: set-difference uninstall with fs.rm() for file removal (not skillRegistryService.uninstall)
- listAgentGroups, listAgentSkills, getAgentEffectiveSkills
- exportGroup / importGroup: GroupExport v1 JSON with cycle check on import
2026-04-04 03:55:42 +00:00
e7e0ab7b87 feat(11-01): add group table DDL and built-in group seeding to skill-registry-db
- Import LibSQLClient type for seedBuiltinGroups parameter typing
- Add DDL constants for 5 new tables: skill_groups, skill_group_members,
  skill_group_inheritance, agent_skill_groups, agent_skills
- Add BUILTIN_GROUPS constant with 5 entries (pm-essentials, engineer-core,
  frontend, backend, creative)
- Add seedBuiltinGroups() using INSERT OR IGNORE for idempotent seeding
- Extend getSkillRegistryDb() to execute all 5 new DDL statements and seed
2026-04-04 03:55:42 +00:00
2956950cd2 feat(11-01): add five Drizzle table definitions for skill groups
- Add primaryKey import from drizzle-orm/sqlite-core
- Add skillGroups table with id, name, description, isBuiltin, timestamps
- Add skillGroupMembers junction table with composite PK (groupId, skillId)
- Add skillGroupInheritance table with composite PK (childGroupId, parentGroupId)
- Add agentSkillGroups table with composite PK (agentId, groupId)
- Add agentSkills table with composite PK (agentId, skillId)
2026-04-04 03:55:42 +00:00
4f6f85bb5a feat(09-04): implement skill registry REST routes and mount in app.ts (GREEN)
- Create skillRegistryRoutes() factory with 6 endpoints
- GET /api/skill-registry/skills (list, includeRemoved support)
- GET /api/skill-registry/skills/:sourceId/:slug (single skill, 404 on missing)
- GET /api/skill-registry/skills/:sourceId/:slug/versions (version history)
- POST /api/skill-registry/fetch (trigger fetchAllSources)
- POST /api/skill-registry/skills/:sourceId/:slug/install (copy to agent dir)
- POST /api/skill-registry/skills/:sourceId/:slug/rollback (restore prior version)
- DELETE /api/skill-registry/skills/:sourceId/:slug (soft-delete)
- assertBoard auth guard on every route
- Mount skillRegistryRoutes() in app.ts after companySkillRoutes
- Update tests to use two-segment path params (sourceId/slug) for Express 5 compatibility
- All 12 route tests pass
2026-04-04 03:55:42 +00:00
2137e1cf78 test(09-04): add failing tests for skill registry routes (RED)
- Tests for GET /api/skill-registry/skills (list, includeRemoved param)
- Tests for GET /api/skill-registry/skills/:id (found, 404)
- Tests for GET /api/skill-registry/skills/:id/versions
- Tests for POST /api/skill-registry/fetch
- Tests for POST /api/skill-registry/skills/:id/install (success, 400)
- Tests for POST /api/skill-registry/skills/:id/rollback (success, 400)
- Tests for DELETE /api/skill-registry/skills/:id
2026-04-04 03:55:42 +00:00
4468945e80 feat(09-03): wire skillRegistryService export and startup DB init
- Add skillRegistryService re-export to services/index.ts after companySkillService
- Add fire-and-forget skill registry DB init in server/src/index.ts after reconcile block
- Uses dynamic import to avoid adding libSQL to critical startup path
2026-04-04 03:55:42 +00:00
22ab1da17b feat(09-03): implement skillRegistryService with install, uninstall, rollback, list
- install() copies cached files to agent .claude/skills/<slug>/ dir
- install() returns pending_plugin_install for skills with file kind=plugin
- uninstall() soft-deletes via removed_at timestamp
- rollback() restores prior version from cache and updates active_version_id
- list() filters soft-deleted by default; includeRemoved=true returns all
- fetchAll() delegates to fetchAllSources for multi-source refresh
2026-04-04 03:55:42 +00:00
136155ad27 test(09-03): add failing tests for skillRegistryService install/rollback/uninstall/list 2026-04-04 03:55:42 +00:00
e443ea9411 feat(09-02): implement multi-source skill fetcher with file caching
- SkillSourceConfig type + BUILT_IN_SOURCES (3 sources: anthropic, schwepps, daymade)
- fetchAllSources() fetches from anthropic-marketplace and github-tree source types
- parseSkillFrontmatter() extracts name/description from SKILL.md YAML blocks
- Idempotency: checks version exists before fetching, skips re-download on same SHA
- Caches SKILL.md to skills/cache/<skill-id>/<sha>/SKILL.md on disk
- Inserts skills, skill_versions, and skill_files rows into registry.db
- All 7 tests passing (TDD GREEN)
2026-04-04 03:55:42 +00:00
9950091e0d test(09-02): add failing tests for skill-registry-fetcher
- 7 tests covering fetch from Anthropic marketplace and GitHub tree sources
- Tests DB insertion, file caching, idempotency, and BUILT_IN_SOURCES config
- All tests fail with ERR_MODULE_NOT_FOUND (expected TDD RED state)
2026-04-04 03:55:42 +00:00
b629235a02 feat(09-01): extract GitHub fetch helpers to shared module
- Create github-skill-helpers.ts with fetchText, fetchJson, resolveGitHubDefaultBranch, resolveGitHubCommitSha, parseGitHubSourceUrl, resolveGitHubPinnedRef, resolveRawGitHubUrl
- Update company-skills.ts to import from github-skill-helpers.js instead of defining locally
- All existing company-skill tests pass (15/15)
2026-04-04 03:55:42 +00:00