@superclawd-ai/pipelines 0.1.1 → 0.1.2
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.
package/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
7
7
|
<title>SuperClawd Pipelines</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-vUolqYQu.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-BD_mYPWG.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist-server/index.mjs
CHANGED
|
@@ -6,8 +6,8 @@ Debounce the input ~300ms with a trailing call, cancel in-flight requests on a n
|
|
|
6
6
|
Reserve holds an estimated amount up front, the fetch runs, then finalize settles the real cost and refunds the difference. Want the FOR-UPDATE details?`,ts:"11:20"}],starred:!1,createdAt:new Date(Date.now()-26*36e5).toISOString(),updatedAt:new Date(Date.now()-26*36e5).toISOString()},conv_3:{id:"conv_3",title:"Draft release notes for v2",workspaceId:"ws_front",workspaceName:"Frontend",tier:"Instant",effort:"low",sessionId:"a17d54c9-2be6-4f80-9c3a-6d0f8b2e1a44",messages:[{id:"m1",role:"user",text:"Draft short release notes for the v2 dashboard changes.",ts:"08:05"},{id:"m2",role:"assistant",text:`Running under Frontend (Instant \xB7 Haiku) \u2014 your team, guardrails and memory are in context.
|
|
7
7
|
|
|
8
8
|
Here\u2019s a first pass grouped by Added / Changed / Fixed. Want me to tighten the copy?`,ts:"08:05"}],starred:!1,createdAt:new Date(Date.now()-2*24*36e5).toISOString(),updatedAt:new Date(Date.now()-2*24*36e5).toISOString()}},te=["conv_3","conv_2","conv_1"],E={sched_1:{id:"sched_1",name:"Triage new bugs",prompt:"Triage new Linear bugs: reproduce, label severity, and open a follow-up for anything urgent.",workspaceId:"ws_front",workspaceName:"Frontend",assignmentKind:"team",teamId:"team_core",teamName:"Core",cadence:"Every 2 hours",enabled:!0,starred:!0,createdAt:new Date(Date.now()-8*24*36e5).toISOString(),lastRunAt:new Date(Date.now()-40*6e4).toISOString(),nextRunAt:new Date(Date.now()+80*6e4).toISOString()},sched_2:{id:"sched_2",name:"Nightly flaky-test sweep",prompt:"Run the test suite, detect flakes, and file an issue per flaky test with the failing output.",workspaceId:"ws_front",workspaceName:"Frontend",assignmentKind:"anyone",cadence:"Every 1 day",enabled:!1,starred:!1,createdAt:new Date(Date.now()-20*24*36e5).toISOString(),lastRunAt:new Date(Date.now()-14*36e5).toISOString(),nextRunAt:null},sched_3:{id:"sched_3",name:"Reconcile credit ledger",prompt:"Reconcile the credit ledger against Stripe: flag drift over $1 and open a dispute task for anything unexplained.",workspaceId:"ws_core",workspaceName:"Core Platform",assignmentKind:"agent",agentId:"agent_orch",agentName:"Orchestrator",cadence:"Every 6 hours",enabled:!0,starred:!0,createdAt:new Date(Date.now()-5*24*36e5).toISOString(),lastRunAt:new Date(Date.now()-2*36e5).toISOString(),nextRunAt:new Date(Date.now()+4*36e5).toISOString()}},H=["sched_1","sched_2","sched_3"],B={sched_1:Array.from({length:14},(e,t)=>({id:`srun_1_${14-t}`,scheduleId:"sched_1",status:t===0?"success":t%6===0?"failed":"success",sessionId:`a1b2c3${String(14-t).padStart(2,"0")}-6f27-4c95-90ab-1e7d32c8f0a5`,startedAt:new Date(Date.now()-(40+t*120)*6e4).toISOString(),finishedAt:new Date(Date.now()-(40+t*120)*6e4+95e3).toISOString(),output:t%6===0?"Failed: could not reach the Linear API (429). Will retry next tick.":`Triaged ${2+t%4} new issues \xB7 labeled severity \xB7 opened ${t%3===0?1:0} follow-up. (mocked output)`})),sched_2:Array.from({length:3},(e,t)=>({id:`srun_2_${3-t}`,scheduleId:"sched_2",status:"success",sessionId:`d4e5f6${String(3-t).padStart(2,"0")}-9c02-4b38-a7e1-5f0c2b83d419`,startedAt:new Date(Date.now()-(14+t*24)*36e5).toISOString(),finishedAt:new Date(Date.now()-(14+t*24)*36e5+22e4).toISOString(),output:`Ran the suite \xB7 ${t===0?"no":"1"} flaky test found${t===0?"":" \xB7 filed 1 issue"}. (mocked output)`})),sched_3:Array.from({length:7},(e,t)=>({id:`srun_3_${7-t}`,scheduleId:"sched_3",status:"success",sessionId:`c7d8e9${String(7-t).padStart(2,"0")}-4b38-4c95-90ab-1e7d32c8f0a5`,startedAt:new Date(Date.now()-(2+t*6)*36e5).toISOString(),finishedAt:new Date(Date.now()-(2+t*6)*36e5+18e4).toISOString(),output:`Reconciled ${180+t*12} charges \xB7 ${t%3===0?"no drift":"flagged 1 mismatch \xB7 opened dispute task"}. (mocked output)`}))},L={runSeq:500,convSeq:3,schedSeq:3,schedRunSeq:100,localSeq:2},q=[],P=[],C=[],G=[],J=[{id:"jira_9002",connectionId:"conn_jira_demo",provider:"jira",externalIdentifier:"PLAT-2",project:"Platform",title:"Add rate-limit headers to the public API",status:"todo",statusRaw:"To Do",assignee:{name:"Priya"},priority:3,labels:[{name:"api"}],url:"https://demo.atlassian.net/browse/PLAT-2",workspaceId:"ws_core",description:"Surface X-RateLimit-* so clients can back off."},{id:"s_150",connectionId:"conn_acme",provider:"linear",externalIdentifier:"ENG-150",project:"Frontend App",title:"Debounce the workspace search input",status:"todo",statusRaw:"Todo",assignee:{name:"Priya"},priority:3,labels:[{name:"ui"}],url:"https://linear.app/acme/issue/ENG-150",workspaceId:"ws_front",description:"The search fires a request per keystroke; debounce ~300ms."},{id:"s_151",connectionId:"conn_acme",provider:"linear",externalIdentifier:"ENG-151",project:"CI",title:"Flaky test: auth.session.spec times out on CI",status:"todo",statusRaw:"Todo",assignee:{name:"Sam"},priority:1,labels:[{name:"bug"},{name:"ci"}],url:"https://linear.app/acme/issue/ENG-151",workspaceId:"ws_front",description:"Intermittent 30s timeout; suspect a missing await."},{id:"s_152",connectionId:"conn_acme",provider:"linear",externalIdentifier:"ENG-152",project:"Public API",title:"Add rate-limit headers to the public API",status:"backlog",statusRaw:"Backlog",priority:2,labels:[{name:"api"}],url:"https://linear.app/acme/issue/ENG-152",workspaceId:"ws_front",description:"Expose X-RateLimit-* on responses."},{id:"s_160",connectionId:"conn_acme",provider:"linear",externalIdentifier:"ENG-160",project:"Auth",title:"Login page: remember-me checkbox does nothing",status:"todo",statusRaw:"Todo",assignee:{name:"Andy"},priority:2,labels:[{name:"bug"}],url:"https://linear.app/acme/issue/ENG-160",workspaceId:"ws_front",description:"Session still expires on browser close."},{id:"s_210",connectionId:"conn_personal",provider:"linear",externalIdentifier:"CORE-210",project:"Directives",title:"Batch the memory-read endpoint",status:"backlog",statusRaw:"Backlog",priority:2,labels:[{name:"perf"}],url:"https://linear.app/personal/issue/CORE-210",workspaceId:"ws_core",description:"Coalesce N per-memory fetches into one batch call."},{id:"s_211",connectionId:"conn_personal",provider:"linear",externalIdentifier:"CORE-211",project:"Docs",title:"Document the directives cache TTL",status:"todo",statusRaw:"Todo",priority:4,labels:[{name:"docs"}],url:"https://linear.app/personal/issue/CORE-211",workspaceId:"ws_core"}]});var Tn={};bi(Tn,{seedFromFixtures:()=>Si});async function Si(){let e=A();await $e.bulkCreate(y.map(n=>({...n,userId:e}))),await ke.bulkCreate(h.map((n,r)=>({...n,userId:e,column:S[n.id]??"backlog",position:r}))),await _e.bulkCreate(Object.values(I).map(n=>({...n,userId:e}))),await Me.bulkCreate(H.map(n=>({...E[n],userId:e})));let t=Object.keys(B).flatMap(n=>{let r=B[n];return r.map((s,o)=>({...s,userId:e,seq:r.length-o}))});await Ae.bulkCreate(t),await Ne.bulkCreate(te.map(n=>({...M[n],userId:e}))),await Ee.bulkCreate(q.map(n=>({...n,userId:e}))),await Le.bulkCreate(P.map(n=>({...n,userId:e}))),await Pe.bulkCreate(C.map((n,r)=>({...n,userId:e,position:n.position??r}))),await Ce.bulkCreate(G.map((n,r)=>({...n,userId:e,position:n.position??r}))),await He.create({userId:e,defaultAutonomy:l.defaultAutonomy,maxConcurrentRuns:l.maxConcurrentRuns??3,branchPrefix:l.branchPrefix??"feature",connectedWorkspaces:l.connectedWorkspaces??null,workspaceDirs:l.workspaceDirs??null,defaultModel:l.defaultModel??null,defaultEffort:l.defaultEffort??null})}var _n=Rn(()=>{"use strict";V();Je()});import Ii from"node:os";import Ar from"node:path";import xi from"node:fs";import{Sequelize as vi,DataTypes as a}from"sequelize";import{Umzug as Ri}from"umzug";function A(){return Nr}function qt(e){Nr=e}async function _r(e){try{return await e.count()}catch{return 0}}async function Cr(){if(xi.mkdirSync(Ar.dirname(Bt),{recursive:!0}),await k.authenticate(),await Ti.up(),await _r(ke)===0&&await _r(Ne)===0&&A()===xt){let{seedFromFixtures:t}=await Promise.resolve().then(()=>(_n(),Tn));await t()}}var Bt,xt,Nr,k,$e,ke,_e,Me,Ae,Ne,He,ze,Ee,Le,Ce,Pe,Er,Ti,Je=Rn(()=>{"use strict";Bt=process.env.PIPELINES_DB_PATH??Ar.join(Ii.homedir(),".superclawd","pipelines.db"),xt=process.env.PIPELINES_DEV_USER_ID??"dev-user",Nr=xt;k=new vi({dialect:"sqlite",storage:Bt,logging:!1}),$e=k.define("Connection",{id:{type:a.STRING,primaryKey:!0},userId:a.STRING,provider:a.STRING,providerAccountName:a.STRING,displayName:a.STRING,workspaceId:a.STRING,workspaceName:a.STRING,workingDir:a.STRING,linkStatus:a.STRING,linkLostReason:a.STRING,authStatus:a.STRING,lastSyncedAt:a.STRING,ticketCount:a.INTEGER,syncFilters:a.JSON,cloudId:a.STRING,providerAccountId:a.STRING},{tableName:"connections",underscored:!0,timestamps:!1}),ke=k.define("Ticket",{id:{type:a.STRING,primaryKey:!0},userId:a.STRING,connectionId:a.STRING,provider:a.STRING,externalIdentifier:a.STRING,title:a.STRING,description:a.TEXT,status:a.STRING,statusRaw:a.STRING,assignee:a.JSON,reporter:a.JSON,dueDate:a.STRING,priority:a.INTEGER,labels:a.JSON,project:a.STRING,parent:a.JSON,model:a.STRING,effort:a.STRING,blockedReason:a.TEXT,comments:a.JSON,additionalContext:a.TEXT,plan:a.TEXT,conclusion:a.TEXT,additionalContextUpdatedAt:a.STRING,planUpdatedAt:a.STRING,conclusionUpdatedAt:a.STRING,createdAt:a.STRING,updatedAt:a.STRING,prLinks:a.JSON,attempt:a.INTEGER,dependsOn:a.JSON,prMonitor:a.BOOLEAN,prMonitorCount:a.INTEGER,prMonitorLastAt:a.STRING,prMonitorNote:a.TEXT,url:a.STRING,workspaceId:a.STRING,workingDir:a.STRING,column:a.STRING,position:a.INTEGER},{tableName:"tickets",underscored:!0,timestamps:!1}),_e=k.define("Run",{id:{type:a.STRING,primaryKey:!0},userId:a.STRING,ticketId:a.STRING,ticketKey:a.STRING,title:a.STRING,provider:a.STRING,workspaceId:a.STRING,workspaceName:a.STRING,assignmentKind:a.STRING,teamName:a.STRING,agentName:a.STRING,autonomy:a.STRING,status:a.STRING,stopReason:a.STRING,sessionId:a.STRING,branchName:a.STRING,prUrl:a.STRING,worktrees:a.JSON,blocker:a.JSON,plan:a.JSON,events:a.JSON,resultText:a.TEXT,pid:a.INTEGER,pgid:a.INTEGER,createdAt:a.STRING,updatedAt:a.STRING},{tableName:"runs",underscored:!0,timestamps:!1}),Me=k.define("Schedule",{id:{type:a.STRING,primaryKey:!0},userId:a.STRING,name:a.STRING,prompt:a.TEXT,workspaceId:a.STRING,workspaceName:a.STRING,assignmentKind:a.STRING,teamId:a.STRING,teamName:a.STRING,agentId:a.STRING,agentName:a.STRING,cadence:a.STRING,workingDir:a.STRING,model:a.STRING,effort:a.STRING,enabled:a.BOOLEAN,starred:a.BOOLEAN,createdAt:a.STRING,lastRunAt:a.STRING,nextRunAt:a.STRING},{tableName:"schedules",underscored:!0,timestamps:!1}),Ae=k.define("ScheduleRun",{id:{type:a.STRING,primaryKey:!0},userId:a.STRING,scheduleId:a.STRING,status:a.STRING,sessionId:a.STRING,startedAt:a.STRING,finishedAt:a.STRING,output:a.TEXT,model:a.STRING,effort:a.STRING,seq:a.INTEGER},{tableName:"schedule_runs",underscored:!0,timestamps:!1}),Ne=k.define("Conversation",{id:{type:a.STRING,primaryKey:!0},userId:a.STRING,title:a.STRING,workspaceId:a.STRING,workspaceName:a.STRING,tier:a.STRING,effort:a.STRING,sessionId:a.STRING,workingDir:a.STRING,messages:a.JSON,starred:a.BOOLEAN,createdAt:a.STRING,updatedAt:a.STRING},{tableName:"conversations",underscored:!0,timestamps:!1}),He=k.define("Setting",{userId:{type:a.STRING,primaryKey:!0},defaultAutonomy:a.STRING,maxConcurrentRuns:a.INTEGER,branchPrefix:a.STRING,connectedWorkspaces:a.JSON,workspaceDirs:a.JSON,defaultModel:a.STRING,defaultEffort:a.STRING,prMonitorDefault:a.BOOLEAN,prMonitorIntervalMinutes:a.INTEGER,prMonitorMaxEngagements:a.INTEGER,prMonitorReplyToComments:a.BOOLEAN,sandboxWorktreeEdits:a.BOOLEAN,publicApiEnabled:a.BOOLEAN,apiKeyHash:a.STRING,apiKeyLast4:a.STRING,apiKeyCreatedAt:a.STRING,webhookEnabled:a.BOOLEAN,webhookUrl:a.STRING,webhookHeaders:a.JSON,webhookEvents:a.JSON,webhookSecret:a.TEXT},{tableName:"settings",underscored:!0,timestamps:!1}),ze=k.define("OAuthToken",{connectionId:{type:a.STRING,primaryKey:!0},userId:a.STRING,provider:a.STRING,accessToken:a.TEXT,refreshToken:a.TEXT,scope:a.STRING,expiresAt:a.STRING},{tableName:"oauth_tokens",underscored:!0,timestamps:!1}),Ee=k.define("RunResult",{id:{type:a.STRING,primaryKey:!0},userId:a.STRING,ticketId:a.STRING,runId:a.STRING,sessionId:a.STRING,prompt:a.TEXT,response:a.TEXT,status:a.STRING,model:a.STRING,effort:a.STRING,createdAt:a.STRING},{tableName:"run_results",underscored:!0,timestamps:!1}),Le=k.define("Note",{id:{type:a.STRING,primaryKey:!0},userId:a.STRING,ticketId:a.STRING,scheduleId:a.STRING,author:a.STRING,body:a.TEXT,createdAt:a.STRING,updatedAt:a.STRING},{tableName:"notes",underscored:!0,timestamps:!1}),Ce=k.define("MessagePreset",{id:{type:a.STRING,primaryKey:!0},userId:a.STRING,title:a.STRING,prompt:a.TEXT,enabled:a.BOOLEAN,position:a.INTEGER,createdAt:a.STRING,updatedAt:a.STRING},{tableName:"message_presets",underscored:!0,timestamps:!1}),Pe=k.define("OpenQuestion",{id:{type:a.STRING,primaryKey:!0},userId:a.STRING,ticketId:a.STRING,question:a.TEXT,answer:a.TEXT,resolved:a.BOOLEAN,position:a.INTEGER,createdAt:a.STRING,updatedAt:a.STRING},{tableName:"open_questions",underscored:!0,timestamps:!1}),Er={Connection:$e,Ticket:ke,Run:_e,Schedule:Me,ScheduleRun:Ae,Conversation:Ne,Setting:He,OAuthToken:ze,RunResult:Ee,Note:Le,MessagePreset:Ce,OpenQuestion:Pe},Ti=new Ri({context:k.getQueryInterface(),storage:{async logMigration({name:e}){await k.query("INSERT INTO pipelines_migrations (name) VALUES (:name)",{replacements:{name:e}})},async unlogMigration({name:e}){await k.query("DELETE FROM pipelines_migrations WHERE name = :name",{replacements:{name:e}})},async executed(){await k.query("CREATE TABLE IF NOT EXISTS pipelines_migrations (name TEXT PRIMARY KEY)");let[e]=await k.query("SELECT name FROM pipelines_migrations ORDER BY name");return e.map(t=>t.name)}},logger:void 0,migrations:[{name:"0001-init",async up(){await k.sync()}},{name:"0002-oauth-tokens",async up(){await ze.sync()}},{name:"0003-settings-branch-prefix",async up(){let e=k.getQueryInterface();(await e.describeTable("settings")).branch_prefix||await e.addColumn("settings","branch_prefix",{type:a.STRING,allowNull:!0})}},{name:"0004-settings-connected-workspaces",async up(){let e=k.getQueryInterface();(await e.describeTable("settings")).connected_workspaces||await e.addColumn("settings","connected_workspaces",{type:a.JSON,allowNull:!0})}},{name:"0005-runs-result-text",async up(){let e=k.getQueryInterface();(await e.describeTable("runs")).result_text||await e.addColumn("runs","result_text",{type:a.TEXT,allowNull:!0})}},{name:"0006-run-results",async up(){let e=k.getQueryInterface();(await e.showAllTables()).map(String).includes("run_results")||await e.createTable("run_results",{id:{type:a.STRING,primaryKey:!0},user_id:a.STRING,ticket_id:a.STRING,run_id:a.STRING,session_id:a.STRING,prompt:a.TEXT,response:a.TEXT,status:a.STRING,created_at:a.STRING})}},{name:"0007-comments",async up(){let e=k.getQueryInterface();(await e.showAllTables()).map(String).includes("comments")||await e.createTable("comments",{id:{type:a.STRING,primaryKey:!0},user_id:a.STRING,ticket_id:a.STRING,author:a.STRING,body:a.TEXT,created_at:a.STRING})}},{name:"0008-comments-updated-at",async up(){let e=k.getQueryInterface();(await e.describeTable("comments")).updated_at||await e.addColumn("comments","updated_at",{type:a.STRING,allowNull:!0})}},{name:"0009-conversations-working-dir",async up(){let e=k.getQueryInterface();(await e.describeTable("conversations")).working_dir||await e.addColumn("conversations","working_dir",{type:a.STRING,allowNull:!0})}},{name:"0010-settings-workspace-dirs",async up(){let e=k.getQueryInterface();(await e.describeTable("settings")).workspace_dirs||await e.addColumn("settings","workspace_dirs",{type:a.JSON,allowNull:!0})}},{name:"0011-tickets-working-dir",async up(){let e=k.getQueryInterface();(await e.describeTable("tickets")).working_dir||await e.addColumn("tickets","working_dir",{type:a.STRING,allowNull:!0})}},{name:"0012-schedules-working-dir",async up(){let e=k.getQueryInterface();(await e.describeTable("schedules")).working_dir||await e.addColumn("schedules","working_dir",{type:a.STRING,allowNull:!0})}},{name:"0013-rename-comments-to-notes",async up(){let e=k.getQueryInterface(),t=(await e.showAllTables()).map(String);t.includes("comments")&&!t.includes("notes")&&await e.renameTable("comments","notes")}},{name:"0014-notes-schedule-id",async up(){let e=k.getQueryInterface();(await e.describeTable("notes")).schedule_id||await e.addColumn("notes","schedule_id",{type:a.STRING,allowNull:!0})}},{name:"0015-connections-sync-filters",async up(){let e=k.getQueryInterface();(await e.describeTable("connections")).sync_filters||await e.addColumn("connections","sync_filters",{type:a.JSON,allowNull:!0})}},{name:"0016-tickets-parent",async up(){let e=k.getQueryInterface();(await e.describeTable("tickets")).parent||await e.addColumn("tickets","parent",{type:a.JSON,allowNull:!0})}},{name:"0017-conversations-effort",async up(){let e=k.getQueryInterface();(await e.describeTable("conversations")).effort||await e.addColumn("conversations","effort",{type:a.STRING,allowNull:!0})}},{name:"0018-model-effort",async up(){let e=k.getQueryInterface(),t={type:a.STRING,allowNull:!0},n=async(r,s)=>{(await e.describeTable(r))[s]||await e.addColumn(r,s,t)};await n("settings","default_model"),await n("settings","default_effort");for(let r of["tickets","schedules","run_results","schedule_runs"])await n(r,"model"),await n(r,"effort")}},{name:"0019-tickets-blocked-reason",async up(){let e=k.getQueryInterface();(await e.describeTable("tickets")).blocked_reason||await e.addColumn("tickets","blocked_reason",{type:a.TEXT,allowNull:!0})}},{name:"0020-message-presets",async up(){let e=k.getQueryInterface();(await e.showAllTables()).map(String).includes("message_presets")||await e.createTable("message_presets",{id:{type:a.STRING,primaryKey:!0},user_id:a.STRING,title:a.STRING,prompt:a.TEXT,enabled:a.BOOLEAN,position:a.INTEGER,created_at:a.STRING,updated_at:a.STRING})}},{name:"0021-ticket-context-fields",async up(){let e=k.getQueryInterface(),t=await e.describeTable("tickets"),n={type:a.TEXT,allowNull:!0};t.additional_context||await e.addColumn("tickets","additional_context",n),!t.tech_plan&&!t.plan&&await e.addColumn("tickets","tech_plan",n),t.conclusion||await e.addColumn("tickets","conclusion",n)}},{name:"0022-open-questions",async up(){let e=k.getQueryInterface();(await e.showAllTables()).map(String).includes("open_questions")||await e.createTable("open_questions",{id:{type:a.STRING,primaryKey:!0},user_id:a.STRING,ticket_id:a.STRING,question:a.TEXT,answer:a.TEXT,resolved:a.BOOLEAN,position:a.INTEGER,created_at:a.STRING,updated_at:a.STRING})}},{name:"0023-rename-tech-plan-to-plan",async up(){let e=k.getQueryInterface(),t=await e.describeTable("tickets");t.tech_plan&&!t.plan&&await e.renameColumn("tickets","tech_plan","plan")}},{name:"0024-ticket-context-timestamps",async up(){let e=k.getQueryInterface(),t=await e.describeTable("tickets"),n={type:a.STRING,allowNull:!0};t.additional_context_updated_at||await e.addColumn("tickets","additional_context_updated_at",n),t.plan_updated_at||await e.addColumn("tickets","plan_updated_at",n),t.conclusion_updated_at||await e.addColumn("tickets","conclusion_updated_at",n)}},{name:"0025-ticket-created-updated",async up(){let e=k.getQueryInterface(),t=await e.describeTable("tickets"),n={type:a.STRING,allowNull:!0};t.created_at||await e.addColumn("tickets","created_at",n),t.updated_at||await e.addColumn("tickets","updated_at",n)}},{name:"0026-ticket-pr-links",async up(){let e=k.getQueryInterface();(await e.describeTable("tickets")).pr_links||await e.addColumn("tickets","pr_links",{type:a.JSON,allowNull:!0})}},{name:"0027-run-worktrees",async up(){let e=k.getQueryInterface();(await e.describeTable("runs")).worktrees||await e.addColumn("runs","worktrees",{type:a.JSON,allowNull:!0})}},{name:"0028-ticket-attempt",async up(){let e=k.getQueryInterface();(await e.describeTable("tickets")).attempt||await e.addColumn("tickets","attempt",{type:a.INTEGER,allowNull:!0})}},{name:"0029-pr-monitor",async up(){let e=k.getQueryInterface(),t={type:a.INTEGER,allowNull:!0},n={type:a.BOOLEAN,allowNull:!0},r={type:a.STRING,allowNull:!0},s={type:a.TEXT,allowNull:!0},o=await e.describeTable("settings");o.pr_monitor_default||await e.addColumn("settings","pr_monitor_default",n),o.pr_monitor_interval_minutes||await e.addColumn("settings","pr_monitor_interval_minutes",t),o.pr_monitor_max_engagements||await e.addColumn("settings","pr_monitor_max_engagements",t),o.pr_monitor_reply_to_comments||await e.addColumn("settings","pr_monitor_reply_to_comments",n);let i=await e.describeTable("tickets");i.pr_monitor||await e.addColumn("tickets","pr_monitor",n),i.pr_monitor_count||await e.addColumn("tickets","pr_monitor_count",t),i.pr_monitor_last_at||await e.addColumn("tickets","pr_monitor_last_at",r),i.pr_monitor_note||await e.addColumn("tickets","pr_monitor_note",s)}},{name:"0030-ticket-depends-on",async up(){let e=k.getQueryInterface();(await e.describeTable("tickets")).depends_on||await e.addColumn("tickets","depends_on",{type:a.JSON,allowNull:!0})}},{name:"0031-settings-sandbox",async up(){let e=k.getQueryInterface();(await e.describeTable("settings")).sandbox_worktree_edits||await e.addColumn("settings","sandbox_worktree_edits",{type:a.BOOLEAN,allowNull:!0})}},{name:"0032-connection-cloud-id",async up(){let e=k.getQueryInterface();(await e.describeTable("connections")).cloud_id||await e.addColumn("connections","cloud_id",{type:a.STRING,allowNull:!0})}},{name:"0033-ticket-reporter-due-date",async up(){let e=k.getQueryInterface(),t=await e.describeTable("tickets");t.reporter||await e.addColumn("tickets","reporter",{type:a.JSON,allowNull:!0}),t.due_date||await e.addColumn("tickets","due_date",{type:a.STRING,allowNull:!0})}},{name:"0034-connection-provider-account-id",async up(){let e=k.getQueryInterface();(await e.describeTable("connections")).provider_account_id||await e.addColumn("connections","provider_account_id",{type:a.STRING,allowNull:!0})}},{name:"0035-settings-public-api",async up(){let e=k.getQueryInterface(),t=await e.describeTable("settings"),n=async(r,s)=>{t[r]||await e.addColumn("settings",r,{type:s,allowNull:!0})};await n("public_api_enabled",a.BOOLEAN),await n("api_key_hash",a.STRING),await n("api_key_last4",a.STRING),await n("api_key_created_at",a.STRING),await n("webhook_enabled",a.BOOLEAN),await n("webhook_url",a.STRING),await n("webhook_headers",a.JSON),await n("webhook_events",a.JSON),await n("webhook_secret",a.TEXT)}},{name:"0036-ticket-comments",async up(){let e=k.getQueryInterface();(await e.describeTable("tickets")).comments||await e.addColumn("tickets","comments",{type:a.JSON,allowNull:!0})}}]})});V();Je();import In from"express";import Jc from"cors";import{randomUUID as Ke}from"node:crypto";import Q from"node:path";import ve from"node:fs";import Sn from"node:os";import{fileURLToPath as zc}from"node:url";V();import Oe from"node:crypto";import An from"node:fs";import _i from"node:os";import Cn from"node:path";var En="enc:v1:",Ai=process.env.SUPERCLAWD_HOME||Cn.join(_i.homedir(),".superclawd"),Nn=process.env.PIPELINES_KEY_FILE||Cn.join(Ai,"pipelines.key"),vt=null;function Pr(){if(vt)return vt;An.mkdirSync(Cn.dirname(Nn),{recursive:!0});try{let t=An.readFileSync(Nn);if(t.length===32)return vt=t,vt}catch{}let e=Oe.randomBytes(32);return An.writeFileSync(Nn,e,{mode:384}),vt=e,e}function Xe(e){let t=Oe.randomBytes(12),n=Oe.createCipheriv("aes-256-gcm",Pr(),t),r=Buffer.concat([n.update(e,"utf8"),n.final()]),s=n.getAuthTag();return`${En}${t.toString("base64")}:${s.toString("base64")}:${r.toString("base64")}`}function Ye(e){if(!e.startsWith(En))return e;let[t,n,r]=e.slice(En.length).split(":"),s=Oe.createDecipheriv("aes-256-gcm",Pr(),Buffer.from(t,"base64"));return s.setAuthTag(Buffer.from(n,"base64")),Buffer.concat([s.update(Buffer.from(r,"base64")),s.final()]).toString("utf8")}function Ve(e){return Oe.createHash("sha256").update(e,"utf8").digest("hex")}function Ze(e="",t=32){return e+Oe.randomBytes(t).toString("base64url")}function Rt(e,t){let n=Buffer.from(e),r=Buffer.from(t);return n.length!==r.length?!1:Oe.timingSafeEqual(n,r)}function Or(e,t){return Oe.createHmac("sha256",e).update(t,"utf8").digest("hex")}Je();function Ni(e){let t={};for(let[n,r]of Object.entries(e))r!=null&&(t[n]=r);return t}var z=e=>e.get({plain:!0}),ne=(e,t)=>{let n={...e};for(let r of t)delete n[r];return Ni(n)};function Dr(e){let t={};for(let[n,r]of Object.entries(e))t[n]=r===void 0?null:r;return t}function Tt(e,t){let n=0;for(let r of e){let s=new RegExp(`^${t}_?(\\d+)$`).exec(r);s&&(n=Math.max(n,Number(s[1])))}return n}async function jr(){let e={where:{userId:A()}},t=await $e.findAll(e);y.length=0,y.push(...t.map(p=>ne(z(p),["userId"])));let n=await ke.findAll({...e,order:[["position","ASC"]]});h.length=0;for(let p of Object.keys(S))delete S[p];for(let p of n){let w=z(p);S[w.id]=w.column??"backlog",h.push(ne(w,["userId","column","position"]))}let r=await _e.findAll(e);for(let p of Object.keys(I))delete I[p];for(let p of Object.keys(x))delete x[p];for(let p of r){let w=ne(z(p),["userId","pid","pgid"]);I[w.id]=w,x[w.ticketId]=w.id}let s=await Me.findAll({...e,order:[["createdAt","ASC"]]});for(let p of Object.keys(E))delete E[p];H.length=0;for(let p of s){let w=ne(z(p),["userId"]);E[w.id]=w,H.push(w.id)}let o=await Ae.findAll({...e,order:[["seq","DESC"]]});for(let p of Object.keys(B))delete B[p];for(let p of H)B[p]=[];for(let p of o){let w=z(p),Y=ne(w,["userId","seq"]);(B[w.scheduleId]??=[]).push(Y)}let i=await Ne.findAll({...e,order:[["updatedAt","DESC"]]});for(let p of Object.keys(M))delete M[p];te.length=0;for(let p of i){let w=ne(z(p),["userId"]);w.messages||(w.messages=[]),M[w.id]=w,te.push(w.id)}let c=await Ee.findAll({...e,order:[["createdAt","DESC"]]});q.length=0;for(let p of c)q.push(ne(z(p),["userId"]));let d=await Le.findAll({...e,order:[["createdAt","ASC"]]});P.length=0;for(let p of d)P.push(ne(z(p),["userId"]));let u=await Ce.findAll({...e,order:[["position","ASC"]]});G.length=0;for(let p of u)G.push(ne(z(p),["userId"]));let m=await Pe.findAll({...e,order:[["position","ASC"]]});C.length=0;for(let p of m)C.push(ne(z(p),["userId"]));let g=await He.findByPk(A());if(g){let p=z(g);l.defaultAutonomy=p.defaultAutonomy??l.defaultAutonomy,typeof p.maxConcurrentRuns=="number"&&(l.maxConcurrentRuns=p.maxConcurrentRuns),typeof p.branchPrefix=="string"&&(l.branchPrefix=p.branchPrefix),Array.isArray(p.connectedWorkspaces)&&(l.connectedWorkspaces=p.connectedWorkspaces),p.workspaceDirs&&typeof p.workspaceDirs=="object"&&(l.workspaceDirs=p.workspaceDirs),typeof p.defaultModel=="string"&&(l.defaultModel=p.defaultModel),typeof p.defaultEffort=="string"&&(l.defaultEffort=p.defaultEffort),typeof p.prMonitorDefault=="boolean"&&(l.prMonitorDefault=p.prMonitorDefault),typeof p.prMonitorIntervalMinutes=="number"&&(l.prMonitorIntervalMinutes=p.prMonitorIntervalMinutes),typeof p.prMonitorMaxEngagements=="number"&&(l.prMonitorMaxEngagements=p.prMonitorMaxEngagements),typeof p.prMonitorReplyToComments=="boolean"&&(l.prMonitorReplyToComments=p.prMonitorReplyToComments),typeof p.sandboxWorktreeEdits=="boolean"&&(l.sandboxWorktreeEdits=p.sandboxWorktreeEdits),typeof p.publicApiEnabled=="boolean"&&(l.publicApiEnabled=p.publicApiEnabled),typeof p.apiKeyHash=="string"&&(l.apiKeyHash=p.apiKeyHash),typeof p.apiKeyLast4=="string"&&(l.apiKeyLast4=p.apiKeyLast4),typeof p.apiKeyCreatedAt=="string"&&(l.apiKeyCreatedAt=p.apiKeyCreatedAt),typeof p.webhookEnabled=="boolean"&&(l.webhookEnabled=p.webhookEnabled),typeof p.webhookUrl=="string"&&(l.webhookUrl=p.webhookUrl),Array.isArray(p.webhookHeaders)&&(l.webhookHeaders=p.webhookHeaders.map(w=>({key:w.key,value:Ye(String(w.value??""))}))),Array.isArray(p.webhookEvents)&&(l.webhookEvents=p.webhookEvents),typeof p.webhookSecret=="string"&&(l.webhookSecret=Ye(p.webhookSecret))}L.convSeq=Tt(Object.keys(M),"conv"),L.schedSeq=Tt(Object.keys(E),"sched"),L.localSeq=Math.max(L.localSeq,Tt(h.map(p=>p.id),"t_local")),L.schedRunSeq=Tt(o.map(p=>z(p).id),"srun"),L.runSeq=Tt(Object.keys(I),"run")}async function R(e){await $e.upsert({...e,userId:A()})}async function $r(e){await $e.destroy({where:{id:e}})}async function Ft(){for(let e of j){let t=`conn_local_${e.id}`;if(y.some(r=>r.provider==="local"&&r.workspaceId===e.id))continue;let n={id:t,provider:"local",providerAccountName:"Local",workspaceId:e.id,workspaceName:e.name,workingDir:null,linkStatus:"linked",authStatus:"connected",lastSyncedAt:null,ticketCount:0};y.push(n),await R(n)}}async function T(e){let t=h.find(n=>n.id===e);t&&await ke.upsert(Dr({...t,userId:A(),column:S[e]??"backlog",position:h.indexOf(t)}))}async function Mr(){await Promise.all(h.map((e,t)=>ke.update({position:t,column:S[e.id]??"backlog"},{where:{id:e.id}})))}async function Wt(e){await ke.destroy({where:{id:e}}),await _e.destroy({where:{ticketId:e}})}async function $(e){let t=I[e];t&&await _e.upsert({...t,userId:A()})}async function Lr(e){await _e.destroy({where:{id:e}})}async function _t(e){let t=E[e];t&&await Me.upsert({...t,userId:A()})}async function Gr(e){await Me.destroy({where:{id:e}}),await Ae.destroy({where:{scheduleId:e}})}async function Kt(e,t){await Ae.upsert({...e,userId:A(),seq:t})}async function Ge(e){let t=M[e];t&&await Ne.upsert({...t,userId:A()})}async function Ur(e){await Ne.destroy({where:{id:e}})}async function Qt(e){await Ee.upsert({...e,userId:A()})}async function Br(e){await Ee.destroy({where:{ticketId:e,userId:A()}})}async function qr(e,t,n){let{count:r,rows:s}=await Ee.findAndCountAll({where:{ticketId:e,userId:A()},order:[["createdAt","DESC"]],limit:t,offset:n});return{entries:s.map(o=>ne(z(o),["userId"])),total:r}}async function Fr(e,t,n){let{count:r,rows:s}=await Ae.findAndCountAll({where:{scheduleId:e,userId:A()},order:[["seq","DESC"]],limit:t,offset:n});return{runs:s.map(o=>ne(z(o),["userId","seq"])),total:r}}async function et(e){await Le.upsert({...e,userId:A()})}async function Ht(e){await Le.destroy({where:{id:e}})}async function Jt(e){let t=G.find(n=>n.id===e);t&&await Ce.upsert({...t,userId:A()})}async function Wr(e){await Ce.destroy({where:{id:e}})}async function Kr(){await Promise.all(G.map((e,t)=>Ce.update({position:t},{where:{id:e.id}})))}async function Pn(e){let t=C.find(n=>n.id===e);t&&await Pe.upsert(Dr({...t,userId:A()}))}async function zt(e){await Pe.destroy({where:{id:e}})}async function Qr(){await Promise.all(C.map((e,t)=>Pe.update({position:t},{where:{id:e.id}})))}async function X(){await He.upsert({userId:A(),defaultAutonomy:l.defaultAutonomy,maxConcurrentRuns:l.maxConcurrentRuns??3,branchPrefix:l.branchPrefix??"feature",connectedWorkspaces:l.connectedWorkspaces??null,workspaceDirs:l.workspaceDirs??null,defaultModel:l.defaultModel??null,defaultEffort:l.defaultEffort??null,prMonitorDefault:l.prMonitorDefault??null,prMonitorIntervalMinutes:l.prMonitorIntervalMinutes??null,prMonitorMaxEngagements:l.prMonitorMaxEngagements??null,prMonitorReplyToComments:l.prMonitorReplyToComments??null,sandboxWorktreeEdits:l.sandboxWorktreeEdits??null,publicApiEnabled:l.publicApiEnabled??null,apiKeyHash:l.apiKeyHash??null,apiKeyLast4:l.apiKeyLast4??null,apiKeyCreatedAt:l.apiKeyCreatedAt??null,webhookEnabled:l.webhookEnabled??null,webhookUrl:l.webhookUrl??null,webhookHeaders:l.webhookHeaders?l.webhookHeaders.map(e=>({key:e.key,value:Xe(e.value)})):null,webhookEvents:l.webhookEvents??null,webhookSecret:l.webhookSecret?Xe(l.webhookSecret):null})}async function Hr(){let e={where:{userId:A()}};await Promise.all(Object.values(Er).map(t=>t.destroy(e)))}async function Jr(){await Hr();let{seedFromFixtures:e}=await Promise.resolve().then(()=>(_n(),Tn));await e()}async function zr(){let e=new Set(j.map(o=>o.id)),t=[],n=new Set;for(let o of y)o.provider!=="local"||!o.workspaceId||!e.has(o.workspaceId)||n.has(o.workspaceId)||(n.add(o.workspaceId),t.push(o));let r=o=>{o.length=0},s=o=>{for(let i of Object.keys(o))delete o[i]};r(y),y.push(...t),r(h),r(J),r(q),r(P),r(C),r(H),r(te),s(I),s(x),s(S),s(E),s(B),s(M),await Hr();for(let o of t)await R(o);await Ft(),await X();for(let o of G)await Jt(o.id)}import Xt from"node:fs";import Ei from"node:os";import On from"node:path";function Ci(){let e=process.env.CLAUDE_CONFIG_DIR||On.join(Ei.homedir(),".claude");return On.join(e,"projects")}function Xr(e){let t=Ci(),n;try{n=Xt.readdirSync(t)}catch{return null}let r=`${e}.jsonl`;for(let s of n){let o=On.join(t,s,r);if(Xt.existsSync(o))return o}return null}function Pi(e){return Array.isArray(e)?e.filter(t=>!!t&&typeof t=="object"&&t.type==="text"&&typeof t.text=="string").map(t=>t.text).join("").trim():typeof e=="string"?e.trim():""}function Yt(e){return Dn(e).response}function Dn(e){let t=Xr(e);if(!t)return{prompt:null,response:null};let n;try{n=Xt.readFileSync(t,"utf8")}catch{return{prompt:null,response:null}}let r=null,s=null;for(let o of n.split(`
|
|
9
|
-
`)){let i=o.trim();if(!i)continue;let c;try{c=JSON.parse(i)}catch{continue}let d=c,u=Pi(d.message?.content);u&&(d.type==="user"&&r===null&&(r=u),d.type==="assistant"&&(s=u))}return{prompt:r,response:s}}function Oi(e,t){let n=typeof e=="string"?e:"tool",r=n.includes("__")?n.slice(n.lastIndexOf("__")+2):n,s=t??{},o=(i,c=80)=>{let u=(typeof i=="string"?i:i==null?"":JSON.stringify(i)).replace(/\s+/g," ").trim();return u.length>c?`${u.slice(0,c)}\u2026`:u};switch(r){case"Bash":return`$ ${o(s.command,120)}`;case"Read":return`Read ${o(s.file_path)}`;case"Edit":case"Write":case"NotebookEdit":return`${r} ${o(s.file_path)}`;case"Grep":return`Grep ${o(s.pattern)}`;case"Glob":return`Glob ${o(s.pattern)}`;case"Task":return`Task \u2192 ${o(s.subagent_type,40)}: ${o(s.description,80)}`;case"WebFetch":return`WebFetch ${o(s.url)}`;default:{let i=s.file_path??s.pattern??s.command??s.repo??s.query;return i!==void 0?`${r} ${o(i)}`:Object.keys(s).length?`${r}(${o(s,80)})`:r}}}function jn(e){let t=Xr(e);if(!t)return[];let n;try{n=Xt.readFileSync(t,"utf8")}catch{return[]}let r=[]
|
|
10
|
-
`)){let
|
|
9
|
+
`)){let i=o.trim();if(!i)continue;let c;try{c=JSON.parse(i)}catch{continue}let d=c,u=Pi(d.message?.content);u&&(d.type==="user"&&r===null&&(r=u),d.type==="assistant"&&(s=u))}return{prompt:r,response:s}}function Oi(e,t){let n=typeof e=="string"?e:"tool",r=n.includes("__")?n.slice(n.lastIndexOf("__")+2):n,s=t??{},o=(i,c=80)=>{let u=(typeof i=="string"?i:i==null?"":JSON.stringify(i)).replace(/\s+/g," ").trim();return u.length>c?`${u.slice(0,c)}\u2026`:u};switch(r){case"Bash":return`$ ${o(s.command,120)}`;case"Read":return`Read ${o(s.file_path)}`;case"Edit":case"Write":case"NotebookEdit":return`${r} ${o(s.file_path)}`;case"Grep":return`Grep ${o(s.pattern)}`;case"Glob":return`Glob ${o(s.pattern)}`;case"Task":return`Task \u2192 ${o(s.subagent_type,40)}: ${o(s.description,80)}`;case"WebFetch":return`WebFetch ${o(s.url)}`;default:{let i=s.file_path??s.pattern??s.command??s.repo??s.query;return i!==void 0?`${r} ${o(i)}`:Object.keys(s).length?`${r}(${o(s,80)})`:r}}}function jn(e){let t=Xr(e);if(!t)return[];let n;try{n=Xt.readFileSync(t,"utf8")}catch{return[]}let r=[];for(let s of n.split(`
|
|
10
|
+
`)){let o=s.trim();if(!o)continue;let i;try{i=JSON.parse(o)}catch{continue}let c=i,d=c.type,u=c.message?.content;if(typeof u=="string"){let m=u.trim();if(!m)continue;d==="user"?r.push({type:"prompt",text:m}):d==="assistant"&&r.push({type:"text",text:m});continue}if(Array.isArray(u))for(let m of u){if(!m||typeof m!="object")continue;let g=m;if(g.type==="text"&&typeof g.text=="string"&&g.text.trim()){let p=g.text.trim();d==="user"?r.push({type:"prompt",text:p}):d==="assistant"&&r.push({type:"text",text:p})}else g.type==="tool_use"&&r.push({type:"tool",text:Oi(g.name,g.input)})}}return r}Je();V();import Di from"node:fs";import ji from"node:os";import Zr from"node:path";import{randomUUID as es}from"node:crypto";var $i=process.env.SUPERCLAWD_HOME||Zr.join(ji.homedir(),".superclawd"),Mi=Zr.join($i,"config.json"),ts=process.env.SUPERCLAWD_MCP_API_URL||"https://mcp-api.superclawd.com",ns=process.env.PIPELINES_BACKEND==="mock"||process.env.SUPERCLAWD_BACKEND==="mock",en=3,$n="__logged_out__";function _(){return ns}var nt={loggedIn:!1,userId:$n,email:null};function ae(){return Mn()}function Mn(){let e=process.env.SUPERCLAWD_MCP_KEY,t=process.env.SUPERCLAWD_MCP_SECRET;if(e&&t)return{keyId:e,secret:t};try{let n=JSON.parse(Di.readFileSync(Mi,"utf8")),r=n?.credentials??n;if(typeof r?.keyId=="string"&&typeof r?.secret=="string")return{keyId:r.keyId,secret:r.secret}}catch{}return null}var Zt=[];function At(){return Zt}var Yr=new Map,Li=5*6e4;async function Nt(e){let t=Yr.get(e);if(t&&Date.now()-t.at<Li)return{agents:t.agents,teams:t.teams};let n=Mn();if(!n)return null;try{let r=await fetch(`${ts}/api/prompt/agents-teams`,{headers:{"content-type":"application/json","x-mcp-key-id":n.keyId,"x-mcp-secret":n.secret,"x-workspace-slug":e,"x-request-id":es()}});if(!r.ok)return null;let s=await r.json().catch(()=>null),o=s?.agents??[],i=s?.teams??[];return Yr.set(e,{agents:o,teams:i,at:Date.now()}),{agents:o,teams:i}}catch{return null}}function Gi(e){return e.map(t=>({id:t.slug,name:t.name,tier:t.tier==="paid"?"paid":"free"}))}function Vr(e){return e===401?"Your credentials are invalid or expired. Run `superclawd login`.":e===403?"This account isn't permitted to use Pipelines.":e===0||e>=500?"The SuperClawd backend is unreachable. Try again in a moment.":`Authentication failed (HTTP ${e}).`}function Vt(e){return qt($n),he.loggedIn=!1,delete he.account,j.length=0,Zt=[],nt={loggedIn:!1,userId:$n,email:null,error:e},nt}async function rs(){if(ns)return qt(xt),he.loggedIn=!0,Zt=[...j],nt={loggedIn:!0,userId:xt,email:he.account?.email??null},nt;let e=Mn();if(!e)return Vt("Not authenticated. Run `superclawd login` to get started.");let t=d=>new Promise(u=>setTimeout(u,d)),n=8,r=2e3,s=0,o=null,i=!1;for(let d=1;d<=n;d++){try{let u=await fetch(`${ts}/api/prompt/workspaces`,{headers:{"content-type":"application/json","x-mcp-key-id":e.keyId,"x-mcp-secret":e.secret,"x-request-id":es()}});if(s=u.status,o=await u.json().catch(()=>null),u.ok){i=!0;break}if(s<500)return Vt(Vr(s))}catch{s=0}d===1&&console.log("[pipelines] waiting for the SuperClawd backend to come up\u2026"),d<n&&await t(r)}if(!i)return Vt(Vr(s));let c=o?.userId;return c?(qt(c),he.loggedIn=!0,he.account={email:o?.email??"",org:"SuperClawd"},Zt=Gi(o?.workspaces??[]),j.length=0,nt={loggedIn:!0,userId:c,email:o?.email??null},nt):Vt("The backend didn't return an account id. Update the CLI/backend.")}V();import{execFile as Ui}from"node:child_process";import{existsSync as nn}from"node:fs";import{rm as Bi}from"node:fs/promises";import{homedir as qi}from"node:os";import{dirname as Fi,join as tn,resolve as ss}from"node:path";var Ln=tn(qi(),".superclawd","pipelines-worktrees");function Z(e,t){return new Promise(n=>{Ui("git",t,{cwd:e,maxBuffer:10*1024*1024},(r,s,o)=>{n({code:r&&typeof r.code=="number"?r.code:r?1:0,stdout:String(s??"").trim(),stderr:String(o??"").trim()})})})}async function os(e){if(!e||!nn(e))return!1;let t=await Z(e,["rev-parse","--is-inside-work-tree"]);return t.code===0&&t.stdout==="true"}async function De(e){if(!e||!nn(e))return[];if(await os(e))return[{name:".",path:ss(e)}];let{readdir:t}=await import("node:fs/promises"),n=await t(e,{withFileTypes:!0}).catch(()=>[]),r=[];for(let s of n){if(!s.isDirectory()||s.name.startsWith("."))continue;let o=tn(e,s.name);await os(o)&&r.push({name:s.name,path:ss(o)})}return r}async function is(e,t){let n=await De(e);if(!n.length)return null;let r=(t??"").trim();return!r||r==="."?n.length===1?n[0]:null:n.find(s=>s.name===r)??null}async function as(e){let t=await Z(e,["symbolic-ref","--short","refs/remotes/origin/HEAD"]);if(t.code===0&&t.stdout)return t.stdout.replace(/^origin\//,"");let n=await Z(e,["rev-parse","--abbrev-ref","HEAD"]);return n.code===0&&n.stdout&&n.stdout!=="HEAD"?n.stdout:"main"}async function Gn(e,t){await Z(e,["fetch","origin",t]);let n=`origin/${t}`;return(await Z(e,["rev-parse","--verify","--quiet",`refs/remotes/${n}`])).code===0?n:t}async function cs(e){if(nn(e.worktreePath)){let s=await Z(e.worktreePath,["rev-parse","--is-inside-work-tree"]);if(s.code===0&&s.stdout==="true")return{ok:!0,worktreePath:e.worktreePath}}let n=(await Z(e.repoPath,["rev-parse","--verify","--quiet",`refs/heads/${e.branch}`])).code===0?["worktree","add",e.worktreePath,e.branch]:["worktree","add","-b",e.branch,e.worktreePath,e.startPoint??e.base],r=await Z(e.repoPath,n);return r.code!==0?{ok:!1,error:r.stderr||r.stdout||"git worktree add failed"}:{ok:!0,worktreePath:e.worktreePath}}async function ds(e,t,n){let r=await Gn(e,n),s=await Z(e,["rev-list","--left-right","--count",`${r}...${t}`]);if(s.code!==0)return{behind:0,ahead:0};let[o,i]=s.stdout.split(/\s+/).map(c=>Number(c)||0);return{behind:o??0,ahead:i??0}}async function us(e,t){await Z(e,["branch","-D",t])}async function rn(e){let t=tn(Ln,e);if(!nn(t))return;let{readdir:n}=await import("node:fs/promises"),r=await n(t,{withFileTypes:!0}).catch(()=>[]);for(let s of r){if(!s.isDirectory())continue;let o=tn(t,s.name),i=await Z(o,["rev-parse","--path-format=absolute","--git-common-dir"]);if(i.code===0&&i.stdout){let c=Fi(i.stdout);await Z(c,["worktree","remove","--force",o])}}await Bi(t,{recursive:!0,force:!0}).catch(()=>{})}function Wi(e){let t=e.trim().replace(/\.git$/,""),n=/^git@([^:]+):(.+)$/.exec(t);return n?`https://${n[1]}/${n[2]}`:(n=/^ssh:\/\/git@([^/]+)\/(.+)$/.exec(t),n?`https://${n[1]}/${n[2]}`:/^https?:\/\//.test(t)?t:null)}async function ls(e,t,n){let r=await Z(e,["remote","get-url","origin"]);if(r.code!==0||!r.stdout)return null;let s=Wi(r.stdout);return s?`${s}/compare/${t}...${n}?expand=1`:null}import{spawn as Yi,spawnSync as Vi}from"node:child_process";import Bn from"node:fs";import qn from"node:os";import rt from"node:path";import{fileURLToPath as Zi}from"node:url";import{execFileSync as Ki}from"node:child_process";import{realpathSync as Qi}from"node:fs";function Hi(){if(process.platform!=="darwin")return!1;try{return Ki("which",["sandbox-exec"],{stdio:"ignore"}),!0}catch{return!1}}function Ji(e){try{return Qi(e)}catch{return e}}function zi(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Xi(e){let t=["(version 1)","(allow default)"];for(let n of e)t.push(`(deny file-write* (subpath "${zi(Ji(n))}"))`);return t.push('(allow file-write* (regex #"/\\.git/"))'),t.push('(allow file-write* (regex #"/\\.claude/"))'),t.join(`
|
|
11
11
|
`)}function ps(e){let{cmd:t,args:n,repoPaths:r,enabled:s}=e;return!s||!r.length||!Hi()?{cmd:t,args:n,sandboxed:!1}:{cmd:"sandbox-exec",args:["-p",Xi(r),t,...n],sandboxed:!0}}function Et(e){if(!e||!e.trim())return process.cwd();let t=e.trim();return t==="~"?t=qn.homedir():(t.startsWith("~/")||t.startsWith("~\\"))&&(t=rt.join(qn.homedir(),t.slice(2))),rt.resolve(t)}function ea(){return`http://127.0.0.1:${Number(process.env.PIPELINES_PORT||process.env.PIPELINES_MOCK_PORT||63210)}`}function ta(){let e=process.env.SUPERCLAWD_BIN;if(e)return{cmd:e,baseArgs:[]};let t=rt.dirname(Zi(import.meta.url));for(let n=0;n<8;n++){let r=rt.join(t,"apps","cli","dist","index.js");if(Bn.existsSync(r))return{cmd:process.execPath,baseArgs:[r]};let s=rt.dirname(t);if(s===t)break;t=s}return{cmd:"superclawd",baseArgs:[]}}function Fn(e){let{cmd:t,baseArgs:n}=ta(),r=[...n,"-p",e.prompt,"--pipelines"];e.pipelinesTools&&r.push(`--pipelines-tools=${e.pipelinesToolsMode??"board"}`),e.workspace&&r.push("--workspace",e.workspace),e.model&&r.push("--model",e.model),e.effort&&r.push("--effort",e.effort),e.noCapture&&r.push("--no-capture"),e.resume?r.push("--resume",e.resume):e.sessionId&&r.push("--session-id",e.sessionId);let s={};e.pipelinesTools&&(s.SUPERCLAWD_PIPELINES_URL=ea(),e.ticketId&&(s.SUPERCLAWD_PIPELINES_TICKET=e.ticketId));let o=Et(e.workingDir);if(!Bn.existsSync(o))return{pid:0,pgid:0,done:Promise.resolve({code:1,stdout:"",stderr:`working directory does not exist: ${o}${e.workingDir&&e.workingDir!==o?` (from "${e.workingDir}")`:""}`})};let i=ps({cmd:t,args:r,repoPaths:e.sandboxRepos??[],enabled:!!e.sandbox});if(process.env.PIPELINES_DEBUG){let p=`[pipelines] spawn (cwd=${o}${i.sandboxed?", sandboxed":""}): ${i.cmd} ${i.args.join(" ")}`;console.log(p);try{Bn.appendFileSync(rt.join(qn.homedir(),".superclawd","pipelines-debug.log"),`${new Date().toISOString()} ${p}
|
|
12
12
|
`)}catch{}}let c=Yi(i.cmd,i.args,{cwd:o,detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,...s}}),d="",u="";c.stdout?.on("data",p=>d+=String(p)),c.stderr?.on("data",p=>u+=String(p));let m=new Promise(p=>{c.on("error",w=>p({code:127,stdout:d,stderr:`${u}
|
|
13
13
|
${String(w)}`})),c.on("close",w=>p({code:w??137,stdout:d,stderr:u}))}),g=c.pid??0;return{pid:g,pgid:g,done:m}}function fs(e,t="SIGTERM"){if(e){if(process.platform==="win32"){try{Vi("taskkill",["/pid",String(e),"/T","/F"],{stdio:"ignore"})}catch{}return}try{process.kill(-e,t)}catch{try{process.kill(e,t)}catch{}}}}function Ue(e){return Fn(e).done}var na=["haiku","sonnet","opus","fable"],ra=["low","medium","high","xhigh","max"],ce="opus",de="high",ye=(e,t=ce)=>{let n=String(e??"").trim();return na.includes(n)?n:t},we=(e,t=de)=>{let n=String(e??"").trim();return ra.includes(n)?n:t};function sa(){let e=new Date;return`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`}function je(e,t,n){let r={id:`e${e.events.length+1}`,ts:sa(),kind:t,text:n};return e.events.push(r),r}V();import{randomUUID as gs}from"node:crypto";var oa=1e4,ms=3,ia=1e3,aa=new Set(["host","content-length","content-type","user-agent","x-superclawd-event","x-superclawd-signature","transfer-encoding","connection"]),ca=e=>new Promise(t=>setTimeout(t,e));function hs(e,t){let n={"content-type":"application/json","user-agent":"SuperClawd-Pipelines-Webhook/1","x-superclawd-event":e};l.webhookSecret&&(n["x-superclawd-signature"]=`sha256=${Or(l.webhookSecret,t)}`);for(let r of l.webhookHeaders??[])r.key&&!aa.has(r.key.toLowerCase())&&(n[r.key]=r.value);return n}async function ks(e,t,n){let r=new AbortController,s=setTimeout(()=>r.abort(),oa);try{return(await fetch(e,{method:"POST",headers:n,body:t,signal:r.signal})).status}catch{return 0}finally{clearTimeout(s)}}function ue(e,t,n={}){let r=l;if(!r.webhookEnabled||!r.webhookUrl||!r.webhookEvents||!r.webhookEvents.includes(e))return;let s=r.webhookUrl,o={id:`evt_${gs()}`,event:e,occurredAt:new Date().toISOString(),workspaceId:n.workspaceId,data:t},i=JSON.stringify(o),c=hs(e,i);(async()=>{for(let d=1;d<=ms;d++){let u=await ks(s,i,c);if(u>=200&&u<300)return;d<ms&&await ca(ia*d)}})().catch(()=>{})}async function ys(){let e=l.webhookUrl;if(!e)return{ok:!1,error:"no webhook URL configured"};let t={id:`evt_${gs()}`,event:"webhook.test",occurredAt:new Date().toISOString(),data:{message:"SuperClawd Pipelines test event"}},n=JSON.stringify(t),r=hs("webhook.test",n),s=await ks(e,n,r);return s>=200&&s<300?{ok:!0,status:s}:{ok:!1,...s?{status:s}:{error:"could not reach the webhook URL"}}}function se(e,t,n={}){return e.status=t,n.stopReason!==void 0&&(e.stopReason=n.stopReason===null?void 0:n.stopReason),n.clearBlocker&&(e.blocker=void 0),n.event&&je(e,n.event.kind,n.event.text),e.updatedAt=new Date().toISOString(),n.webhookEvent&&ue(n.webhookEvent,{runId:e.id,ticketId:e.ticketId,ticketKey:e.ticketKey,title:e.title,status:e.status,stopReason:e.stopReason},{workspaceId:e.workspaceId}),e}import{randomUUID as da}from"node:crypto";var ua=3,la=1,pa=10,st=new Map,ot=[];function fa(){let e=l.maxConcurrentRuns??ua;return Math.max(la,Math.min(pa,e))}function be(e,t=!1,n){st.has(e)||ot.some(r=>r.runId===e)||(ot.push({runId:e,resume:t,prompt:n}),ws())}function ws(){for(;st.size<fa()&&ot.length>0;){let e=ot.shift();ha(e.runId,e.resume,e.prompt)}}function ma(e,t,n){let r=e?`You are working on SuperClawd Pipelines ticket ${e.externalIdentifier} \u2014 "${e.title}" (ticket id: ${e.id}).`:`You are working on SuperClawd Pipelines run "${t.title}".`,o=!!e&&e.provider!=="local"?"- Start by calling read_ticket to read the full ticket (description, vendor comments, context, plan, open questions, conclusion, notes). On this run you can call it with no arguments \u2014 it defaults to this ticket. Read the vendor comments too \u2014 the real acceptance criteria and decisions often live in the discussion, not the description.":"- Start by calling read_ticket to read the full ticket (description, context, plan, open questions, conclusion, notes). On this run you can call it with no arguments \u2014 it defaults to this ticket.",i=[r,"","Use the SuperClawd Pipelines tools for this task:",o,"- Write your plan with set_plan (use the tool; do not create a plan file unless the ticket explicitly asks for one).","- If this task changes code: your working directory may be an umbrella folder containing several git repositories. Call list_repos to see them, research to decide which you need, then \u2014 BEFORE editing any repo \u2014 call start_repo_work({repo}) to get an isolated worktree. Make ALL changes for that repo inside the returned worktreePath and commit there; NEVER edit the repo in the working directory directly (other runs may be working on it at the same time). Claim each repo you touch. When done, push the branch and record the PR with add_pr_link (if you can't open a PR, push the branch and pass the compareUrl to add_pr_link so a human can).","- If you need something that isn't in the ticket, record it with add_open_question rather than guessing \u2014 and if it blocks progress, also call block_ticket with a reason.","- Keep durable findings or decisions on the ticket with add_note.","- When you've fully completed what the ticket asked, write a short wrap-up of what you did (and any results) with set_conclusion."];if(t.autonomy==="autonomous"&&i.push("","This run is AUTONOMOUS \u2014 no one is available to answer questions while it runs. Do NOT guess on any decision that materially changes the outcome. When you hit a genuine unknown, record it with add_open_question AND call block_ticket with a short reason, then stop \u2014 a human will resolve it and the ticket will be re-run. Only make assumptions for trivial, low-risk gaps, and state them clearly."),t.assignmentKind==="agent"&&t.agentName)i.push("",`DELEGATION \u2014 this ticket is assigned to the "${t.agentName}" agent. Use the Task tool to hand the ENTIRE ticket to the subagent for "${t.agentName}" (available in this session), let it complete the work, then report its result. Do NOT do the work yourself. If you cannot find that subagent, proceed yourself and add_note that the assigned agent was unavailable.`);else if(t.assignmentKind==="team"&&t.teamName){let u=t.teamLeadName;i.push("",u?`DELEGATION \u2014 this ticket is assigned to the "${t.teamName}" team. Use the Task tool to hand the ENTIRE ticket to the team's LEAD subagent, "${u}" (available in this session); it will coordinate its members. Do NOT do the work yourself. If you cannot find it, proceed yourself and add_note that the assigned team was unavailable.`:`DELEGATION \u2014 this ticket is assigned to the "${t.teamName}" team. Use the Task tool to hand the ENTIRE ticket to that team's lead-agent subagent, which coordinates its members. Do NOT do the work yourself. If you cannot find it, proceed yourself and add_note that the assigned team was unavailable.`)}i.push("","Then do the work the ticket asks for.");let c=i.join(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superclawd-ai/pipelines",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Turn your board into an autonomous pipeline — a local, opt-in SuperClawd extension that runs your own Claude on your tickets and opens PRs for review.",
|
|
6
6
|
"author": "SuperClawd <support@superclawd.com>",
|