artifactpass 0.1.12-rc.3 → 0.1.12-rc.4
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/cli.mjs +1 -1
- package/dist/deployment/index.js +1 -1
- package/dist/marketplace/plugins/artifactpass/.claude-plugin/plugin.json +1 -1
- package/dist/marketplace/plugins/artifactpass/.codex-plugin/plugin.json +1 -1
- package/dist/marketplace/plugins/artifactpass/plugin-metadata.json +1 -1
- package/dist/slack-wizard.html +89 -20
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -43424,7 +43424,7 @@ var startSlackArchiveWizard = async (options) => {
|
|
|
43424
43424
|
// package.json
|
|
43425
43425
|
var package_default = {
|
|
43426
43426
|
name: "artifactpass",
|
|
43427
|
-
version: "0.1.12-rc.
|
|
43427
|
+
version: "0.1.12-rc.4",
|
|
43428
43428
|
description: "Install and connect ArtifactPass for compatible AI agent systems.",
|
|
43429
43429
|
homepage: "https://artifactpass.com",
|
|
43430
43430
|
keywords: [
|
package/dist/deployment/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "artifactpass",
|
|
3
|
-
"version": "0.1.12-rc.
|
|
3
|
+
"version": "0.1.12-rc.4",
|
|
4
4
|
"displayName": "ArtifactPass",
|
|
5
5
|
"description": "Share temporary Markdown, HTML, and PDF links between people and AI agents.",
|
|
6
6
|
"longDescription": "Publishes files from an approved workspace for people or agents to open, and reads supported ArtifactPass links created by either people or agents.",
|
package/dist/slack-wizard.html
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*{box-sizing:border-box}html{min-width:320px;background:var(--void)}body{min-width:320px;min-height:100dvh;margin:0;color:var(--bone);background:var(--void);-webkit-font-smoothing:antialiased}button,input,textarea{font:inherit}button{cursor:pointer}button:disabled{cursor:not-allowed}a{color:var(--bone)}button:focus-visible,a:focus-visible,input:focus-visible,textarea:focus-visible{outline:2px solid var(--white);outline-offset:3px}[hidden]{display:none!important}
|
|
10
10
|
.shell{width:min(920px,calc(100% - 40px));margin:auto}.top{display:flex;align-items:center;justify-content:space-between;gap:16px;height:68px;border-bottom:1px solid var(--line)}.brand{display:inline-flex;align-items:center;font-size:15px;font-weight:600;letter-spacing:-.03em}.brand svg{width:20px;height:20px;margin-right:9px}.brand small{margin-left:9px;color:var(--slate);font:400 11px var(--mono)}.top-right{display:flex;align-items:center;gap:18px}.local{color:var(--slate);font:400 10px var(--mono)}
|
|
11
11
|
.layout{padding:28px 0 64px}.setup-heading{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-bottom:16px}h1{margin:0;font-size:27px;font-weight:500;letter-spacing:-.045em;line-height:1.2}.setup-heading p{margin:0;color:var(--slate);font:400 10px var(--mono)}
|
|
12
|
-
.rail{margin-bottom:12px}.rail details{border:1px solid var(--line);border-radius:10px;background:var(--graphite)}.rail summary{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:42px;padding:0 15px;cursor:pointer;list-style:none}.rail summary::-webkit-details-marker{display:none}.rail summary:focus-visible{outline:2px solid var(--white);outline-offset:3px}.rail-current{color:var(--bone);font-size:12px}.rail-current small{margin-right:12px;color:var(--slate);font:400 10px var(--mono)}.rail-toggle{color:var(--ash);font:400 10px var(--mono)}.
|
|
12
|
+
.rail{margin-bottom:12px}.rail details{border:1px solid var(--line);border-radius:10px;background:var(--graphite)}.rail summary{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:42px;padding:0 15px;cursor:pointer;list-style:none}.rail summary::-webkit-details-marker{display:none}.rail summary:focus-visible{outline:2px solid var(--white);outline-offset:3px}.rail-current{color:var(--bone);font-size:12px}.rail-current small{margin-right:12px;color:var(--slate);font:400 10px var(--mono)}.rail-toggle{display:inline-flex;align-items:center;gap:10px;flex:none;color:var(--ash);font:400 10px var(--mono)}.chevron{display:inline-block;flex:none;width:7px;height:7px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg);transition:transform 150ms ease}.rail details[open] .chevron,.codebox[open] .chevron,.manifest-details[open] .chevron{transform:rotate(225deg)}.stage-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:2px 16px;padding:10px 15px 13px;border-top:1px solid var(--line)}.stage{display:flex;align-items:center;gap:9px;min-height:32px;padding:4px 0;border:0;color:var(--ash);background:none;text-align:left;font-size:11px}.stage.active{color:var(--bone)}.stage.done .number{color:var(--good)}.number{color:var(--slate);font:400 10px var(--mono)}
|
|
13
13
|
.card{overflow:hidden;border:1px solid var(--line);border-radius:20px;background:linear-gradient(145deg,rgba(185,132,88,.045),transparent 35%),linear-gradient(325deg,rgba(85,127,189,.055),transparent 42%),var(--graphite);box-shadow:0 28px 80px rgba(0,0,0,.18)}.card-head{padding:22px 24px 20px;border-bottom:1px solid var(--line)}.card-head h2{margin:0;font-size:20px;font-weight:500;letter-spacing:-.035em}.card-head p{max-width:510px;margin:6px 0 0;color:var(--ash);font-size:12px;line-height:1.5}.card-body{padding:24px}.card-foot{display:flex;align-items:center;justify-content:space-between;gap:15px;padding:18px 24px 24px;border-top:1px solid var(--line)}.card-foot.first-step{justify-content:space-between}.foot-left{display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:7px;min-width:0;min-height:46px}.foot-right{display:flex;align-items:center;gap:16px}.operation-status{max-width:520px;color:var(--ash);font-size:11px;line-height:1.45;overflow-wrap:anywhere}.operation-status:empty{display:none}.operation-status.error{color:var(--bad)}.operation-status.good{color:var(--good)}.button{position:relative;display:inline-flex;align-items:center;justify-content:center;min-height:42px;padding:8px 16px;border:1px solid var(--line-strong);border-radius:10px;color:var(--bone);background:var(--panel);font-size:12px;font-weight:500;line-height:1.35;text-align:center;text-decoration:none;white-space:nowrap;transition:background-color 150ms ease,border-color 150ms ease,color 150ms ease,transform 130ms ease}.button[data-action]{padding-right:36px}.button:hover:not(:disabled){border-color:var(--bone);background:var(--panel-strong)}.button:active:not(:disabled){transform:scale(.98)}.button:disabled:not(.loading){border-color:var(--line);color:var(--ash);background:var(--panel);opacity:.7}.button.primary{min-height:46px;padding:9px 20px;border-color:var(--white);color:var(--ink);background:var(--white);font-size:13px}.button.primary[data-action]{padding-right:40px}.button.primary:hover:not(:disabled){border-color:#dededb;background:#dededb}.button.primary:disabled:not(.loading){border-color:var(--line-strong);color:var(--ash);background:var(--panel);opacity:1}.button.loading:disabled{opacity:1;cursor:progress}.button .spinner{position:absolute;right:13px;top:50%;margin-top:-7px}.button.primary .spinner{right:15px;border-color:rgba(23,24,26,.25);border-top-color:var(--ink)}.button.small{min-height:30px;padding:5px 10px;border-radius:7px;font-size:11px}.text-btn{padding:3px 0;border:0;border-bottom:1px solid var(--line-strong);color:var(--ash);background:none;font-size:11px;text-decoration:none}.text-btn:hover{color:var(--bone)}
|
|
14
14
|
.label{display:block;margin:0 0 9px;color:var(--ash);font-size:12px}.help{margin:8px 0 0;color:var(--ash);font-size:11px;line-height:1.5}.field{width:100%;min-height:46px;padding:0 12px;border:1px solid var(--line);border-radius:10px;color:var(--bone);background:#17191d;font:500 12px/1.5 var(--mono)}.field::placeholder{color:var(--slate)}textarea.field{min-height:110px;padding:12px;resize:vertical}.form-row{margin:0 0 21px}.note{margin:19px 0;padding:11px 13px;border:1px solid var(--line);border-radius:10px;color:var(--ash);background:var(--panel);font-size:11px;line-height:1.55}.note strong{color:var(--bone);font-weight:500}.note.warn{border-color:rgba(185,132,88,.42);color:#d2af90;background:rgba(185,132,88,.08)}.note.good{border-color:var(--good);color:var(--good);background:rgba(102,153,104,.11)}.note.error{border-color:var(--bad);color:var(--bad);background:rgba(185,88,88,.1)}.check{display:flex;align-items:flex-start;gap:10px;padding:12px 0;color:var(--bone);font-size:12px}.check input{flex:none;width:16px;height:16px;margin:1px 0 0;accent-color:var(--bone)}.check small{display:block;margin-top:5px;color:var(--ash);font-size:11px;line-height:1.45}.item-list{overflow:hidden;display:grid;margin:15px 0 20px;border:1px solid var(--line);border-radius:12px}.item{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:12px 14px;color:var(--ash);font-size:12px}.item+.item{border-top:1px solid var(--line)}.item strong{color:var(--bone);font-weight:500;overflow-wrap:anywhere}.item small{display:block;margin-top:3px;color:var(--slate);font-size:11px}.status{flex:none;color:var(--good);font:400 10px var(--mono)}.status.pending{color:#d2af90}.codebox{overflow:hidden;margin:17px 0;border:1px solid var(--line);border-radius:10px;background:#17191d}.codebox-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 11px;border-bottom:1px solid var(--line);color:var(--slate);font:400 10px var(--mono);white-space:pre-wrap;overflow-wrap:anywhere}.progress{display:flex;align-items:center;gap:10px;margin:12px 0;padding:11px 13px;border:1px solid var(--line);border-radius:10px;color:var(--ash);font-size:11px}.spinner{width:14px;height:14px;border:2px solid var(--line-strong);border-top-color:var(--bone);border-radius:50%;animation:turn .8s linear infinite}@keyframes turn{to{transform:rotate(360deg)}}.page-footer{display:flex;justify-content:space-between;gap:20px;padding:26px 0 34px;border-top:1px solid var(--line);color:var(--slate);font-size:11px}.actions{display:flex;flex-wrap:wrap;gap:9px;margin:18px 0}.plain-link{color:var(--bone);font-size:12px;text-underline-offset:3px}.guide-steps{margin:10px 0 18px;padding-left:19px;color:var(--ash);font-size:12px;line-height:1.65}.guide-steps li+li{margin-top:7px}
|
|
15
15
|
.setup-steps{margin:0 0 22px;padding-left:24px;font-size:13px;line-height:1.55}.setup-steps li{padding-left:7px}.setup-steps li+li{margin-top:22px}.setup-steps strong{color:var(--bone);font-weight:500}.setup-steps p{margin:5px 0 10px;color:var(--ash)}.setup-steps .button{display:inline-flex;align-items:center;text-decoration:none}.manifest-details{margin:0 0 19px;color:var(--ash);font-size:11px}.manifest-details summary{cursor:pointer}.manifest-details ul{margin:10px 0 0;padding-left:20px;line-height:1.6}
|
|
@@ -19,6 +19,74 @@
|
|
|
19
19
|
.card-head,.card-foot{flex:none}
|
|
20
20
|
.card-body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-gutter:stable}
|
|
21
21
|
@media(max-width:580px){.card{height:clamp(420px,calc(100dvh - 188px),620px)}}
|
|
22
|
+
.button[data-action],.button.primary[data-action]{gap:10px;padding-right:16px}.button.primary[data-action]{padding-right:20px}.button .spinner,.button.primary .spinner{position:static;flex:none;margin:0}.button[data-action="copy-manifest"]{min-width:0}.button.primary{min-height:42px}.foot-right .button{min-width:0}.actions{align-items:center}.actions .button{flex:none}.check{display:grid;grid-template-columns:18px minmax(0,1fr);align-items:start;column-gap:12px;line-height:1.4}.check input{width:18px;height:18px;margin:0;align-self:start}.check span{min-width:0}.check small{margin-top:4px}.field-select{position:relative}.field-select:after{position:absolute;right:17px;top:50%;width:7px;height:7px;border-right:1.5px solid var(--ash);border-bottom:1.5px solid var(--ash);content:"";pointer-events:none;transform:translateY(-65%) rotate(45deg)}select.field{appearance:none;padding:0 40px 0 13px;font-family:var(--sans);font-size:13px;font-weight:400;line-height:1.4}select.field:disabled{color:var(--slate)}.account-actions{margin:12px 0 0}.account-actions .text-btn{font-size:12px}.account-loading{display:flex;align-items:center;gap:10px;min-height:46px;color:var(--ash);font-size:12px}.setup-steps{padding-left:25px;list-style:none;counter-reset:setup}.setup-steps li{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:18px;align-items:center;padding:0 0 16px;counter-increment:setup}.setup-steps li:not(:last-child){border-bottom:1px solid var(--line)}.setup-steps li:before{position:absolute;left:-25px;top:0;color:var(--slate);font:400 11px/1.8 var(--mono);content:counter(setup) "."}.setup-steps li+li{margin-top:16px}.setup-steps p{margin:4px 0 0}.step-control{display:flex;align-items:center;justify-content:flex-end}.step-control .button{margin:0}.codebox summary,.manifest-details summary{display:flex;align-items:center;justify-content:space-between;gap:14px;min-height:42px;padding:10px 13px;cursor:pointer;list-style:none}.codebox summary::-webkit-details-marker,.manifest-details summary::-webkit-details-marker{display:none}.codebox summary:focus-visible,.manifest-details summary:focus-visible{outline:2px solid var(--white);outline-offset:-3px}.codebox-head{border-bottom:0;color:var(--ash);font:400 12px/1.4 var(--sans)}.codebox[open] .codebox-head{border-bottom:1px solid var(--line)}.manifest-details{overflow:hidden;border:1px solid var(--line);border-radius:10px}.manifest-details summary{color:var(--ash);font-size:12px}.manifest-details ul{margin:0;padding:8px 16px 14px 34px;border-top:1px solid var(--line)}@media(max-width:580px){.actions .button{width:auto;max-width:100%;white-space:normal}.card-foot .button.primary{width:100%}.rail-toggle{gap:7px}.setup-steps li{grid-template-columns:1fr;row-gap:10px}.step-control{justify-content:flex-start}}
|
|
23
|
+
.setup-steps:not(.slack-app-steps) li{display:block}.setup-steps:not(.slack-app-steps) p{margin:5px 0 10px}.setup-steps:not(.slack-app-steps) .check{margin-top:12px}
|
|
24
|
+
.button.loading>span:first-child{visibility:hidden}.button.loading .spinner,.button.primary.loading .spinner{position:absolute;left:calc(50% - 7px);top:calc(50% - 7px);margin:0}
|
|
25
|
+
/* Shared control patterns for the self-contained CLI wizard. */
|
|
26
|
+
.button,.field,.check input,.disclosure{border-radius:9px}
|
|
27
|
+
.button{min-height:40px;padding:8px 14px;font-size:12px;line-height:1.3}
|
|
28
|
+
.button.primary{min-height:40px;padding:8px 16px;font-size:12px}
|
|
29
|
+
.card-foot{min-height:78px;padding:14px 24px}
|
|
30
|
+
.foot-left{min-height:40px}.foot-right{justify-content:flex-end}
|
|
31
|
+
.check{grid-template-columns:18px minmax(0,1fr);align-items:start;gap:10px;padding:10px 0;cursor:pointer}
|
|
32
|
+
.check input{width:17px;height:17px;margin:1px 0 0}
|
|
33
|
+
.check span{line-height:1.4}.check small{line-height:1.45}
|
|
34
|
+
.field-select{max-width:100%}.field-select:after{right:18px;top:calc(50% - 2px);transform:rotate(45deg)}
|
|
35
|
+
select.field{min-height:44px;padding-right:42px;background:#1a1c20;color:var(--bone)}
|
|
36
|
+
.rail summary{min-height:44px}.rail-toggle{min-width:76px;justify-content:flex-end;line-height:1}
|
|
37
|
+
.stage{min-height:36px;padding:5px 8px;border-radius:8px}
|
|
38
|
+
.stage .number{flex:none;width:23px}
|
|
39
|
+
.stage.active{padding-left:8px;border-radius:8px}
|
|
40
|
+
@media(hover:hover) and (pointer:fine){.stage:not(:disabled):hover:not(.active){background:rgba(255,255,255,.035)}.account-choice:hover{border-color:var(--line-strong);background:rgba(255,255,255,.045)}}
|
|
41
|
+
.account-choices{min-width:0;margin:0;padding:0;border:0}
|
|
42
|
+
.account-choices legend{margin-bottom:9px;color:var(--ash);font-size:12px}
|
|
43
|
+
.account-choice{display:grid;grid-template-columns:18px minmax(0,1fr);align-items:center;gap:12px;min-height:60px;margin-top:8px;padding:11px 13px;border:1px solid var(--line);border-radius:9px;background:#17191d;cursor:pointer}
|
|
44
|
+
.account-choice:first-of-type{margin-top:0}
|
|
45
|
+
.account-choice:has(input:checked){border-color:var(--line-strong);background:var(--panel-strong)}
|
|
46
|
+
.account-choice:focus-within{outline:2px solid var(--white);outline-offset:2px}
|
|
47
|
+
.account-choice input{width:17px;height:17px;margin:0;accent-color:var(--bone)}
|
|
48
|
+
.account-choice-name{display:block;color:var(--bone);font-size:13px;line-height:1.35;overflow-wrap:anywhere}
|
|
49
|
+
.account-choice-id{display:block;margin-top:3px;color:var(--slate);font:11px/1.35 var(--mono);overflow-wrap:anywhere}
|
|
50
|
+
.rail-toggle .chevron,.disclosure .chevron{width:7px;height:7px;margin:0 1px 4px;transform:rotate(45deg);transform-origin:50% 50%}
|
|
51
|
+
.rail details[open] .rail-toggle .chevron,.disclosure[open] .chevron{margin:4px 1px 0;transform:rotate(225deg)}
|
|
52
|
+
.setup-steps.slack-app-steps li{grid-template-columns:minmax(0,1fr) auto;gap:16px}
|
|
53
|
+
.setup-steps.slack-app-steps .step-control{justify-content:flex-end;align-self:center}
|
|
54
|
+
.setup-steps.slack-app-steps .step-control .button{min-width:0;white-space:normal}
|
|
55
|
+
.disclosure{overflow:hidden;margin:14px 0;border:1px solid var(--line);background:#17191d}
|
|
56
|
+
.disclosure summary{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:44px;padding:10px 14px;cursor:pointer;list-style:none;color:var(--bone);font-size:12px;font-weight:500}
|
|
57
|
+
.disclosure summary::-webkit-details-marker{display:none}
|
|
58
|
+
.disclosure summary:focus-visible{outline:2px solid var(--white);outline-offset:-3px}
|
|
59
|
+
.disclosure[open] summary{border-bottom:1px solid var(--line)}
|
|
60
|
+
.disclosure pre{max-height:340px;margin:0;padding:14px;overflow:auto;color:var(--bone);font:11px/1.55 var(--mono)}
|
|
61
|
+
.disclosure ul{margin:0;padding:12px 20px 14px 34px;color:var(--ash);font-size:12px;line-height:1.65}
|
|
62
|
+
@media(max-width:580px){
|
|
63
|
+
.shell{width:100%}
|
|
64
|
+
.layout{padding-top:12px;padding-bottom:24px}
|
|
65
|
+
.top,.setup-heading,.card-head,.card-body,.card-foot,.page-footer{padding-left:16px;padding-right:16px}
|
|
66
|
+
.setup-heading{position:absolute;width:1px;height:1px;margin:0;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
|
|
67
|
+
.rail{margin:0 16px 4px}
|
|
68
|
+
.rail details{border:0;border-radius:0;background:transparent}
|
|
69
|
+
.rail summary{min-height:38px;padding:0 0 12px}
|
|
70
|
+
.stage-list{padding-left:0;padding-right:0}
|
|
71
|
+
.card{display:block;height:auto;min-height:0;overflow:visible;border:0;border-radius:0;background:transparent;box-shadow:none}
|
|
72
|
+
.card-body{min-height:0;overflow:visible;scrollbar-gutter:auto}
|
|
73
|
+
.codebox pre,.disclosure pre{max-height:none;overflow:visible;white-space:pre-wrap;overflow-wrap:anywhere}
|
|
74
|
+
.card-head{padding-top:18px;padding-bottom:18px;border-top:1px solid var(--line)}
|
|
75
|
+
.card-body{padding-top:18px;padding-bottom:18px}
|
|
76
|
+
.card-foot{min-height:0;gap:12px;padding-top:16px;padding-bottom:16px}
|
|
77
|
+
.foot-left{min-height:0}
|
|
78
|
+
.setup-steps{padding-left:0}
|
|
79
|
+
.setup-steps li{padding-left:0}
|
|
80
|
+
.setup-steps li:before{display:none}
|
|
81
|
+
.setup-steps.slack-app-steps li{grid-template-columns:1fr;gap:9px}
|
|
82
|
+
.setup-steps.slack-app-steps .step-control{justify-content:flex-start}
|
|
83
|
+
.note{margin:14px 0;padding:10px 12px}
|
|
84
|
+
.page-footer{display:none}
|
|
85
|
+
.button.primary{width:100%}
|
|
86
|
+
}
|
|
87
|
+
/* Navigation and prose use interface type; reserve mono for IDs, URLs, and code. */
|
|
88
|
+
.brand small,.local,.setup-heading p,.rail-current small,.rail-toggle,.number,.status,.setup-steps li:before{font-family:var(--sans)}
|
|
89
|
+
.local,.setup-heading p,.rail-current small,.rail-toggle,.number,.status{font-size:11px}
|
|
22
90
|
</style>
|
|
23
91
|
</head>
|
|
24
92
|
<body>
|
|
@@ -37,34 +105,35 @@
|
|
|
37
105
|
<script>
|
|
38
106
|
(()=>{
|
|
39
107
|
const token=location.hash.slice(1);const labels=['Choose sources','Cloudflare account','Approve resources','Slack app','Connect Slack','Private origin','Channels','Add app to channels','Verify','Ready'];
|
|
40
|
-
let config=null,manifestReady=false,operation=null,accounts=[],step=0,renderedStep=-1,includePrivate=false,accountId='',privateOrigin='',appId='',channelsText='',joinedChannels=[],approved=false,resetApproved=false,appInstalled=false,manifestCopied=false,inspected=false,verification=null,manifest=null,error='',notice='',busy=false,busyAction='',exited=false;
|
|
108
|
+
let config=null,manifestReady=false,operation=null,accounts=[],accountsChecked=false,accountsChecking=false,accountError='',step=0,renderedStep=-1,includePrivate=false,accountId='',privateOrigin='',appId='',channelsText='',joinedChannels=[],approved=false,resetApproved=false,appInstalled=false,manifestCopied=false,inspected=false,verification=null,manifest=null,error='',notice='',busy=false,busyAction='',exited=false;
|
|
41
109
|
const $=id=>document.getElementById(id);const esc=value=>String(value??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
|
42
110
|
const api=async(path,method='GET',body)=>{const response=await fetch('/api/'+path,{method,headers:{'X-ArtifactPass-Setup-Token':token,...(body===undefined?{}:{'Content-Type':'application/json'})},...(body===undefined?{}:{body:JSON.stringify(body)})});const data=await response.json();if(!response.ok)throw Error(data.error||'Setup could not continue');return data};
|
|
111
|
+
const checkAccounts=async()=>{accountsChecked=true;accountsChecking=true;accountError='';render();try{const result=await api('accounts','POST',{});accounts=result.accounts;accountId=accounts.some(account=>account.id===accountId)?accountId:config?.account_id||(accounts.length===1?accounts[0].id:'')}catch(caught){accounts=[];accountError=caught.message}finally{accountsChecking=false;render()}};
|
|
43
112
|
const note=(text,type='')=>`<div class="note ${type}">${text}</div>`;
|
|
44
113
|
const head=(_number,title,copy)=>`<div class="card-head"><h2>${title}</h2><p>${copy}</p></div>`;
|
|
45
114
|
const pending=()=>operation?.status==='working';
|
|
46
115
|
const loading=action=>busyAction===action||pending()&&operation.kind===action;
|
|
47
|
-
const actionButton=(label,action,primary=false,disabled=false
|
|
48
|
-
const foot=(action,label,disabled=false)=>`<div class="card-foot ${step?'':'first-step'}"><div class="foot-left">${step?'<button class="text-btn" data-back type="button"
|
|
116
|
+
const actionButton=(label,action,primary=false,disabled=false)=>{const active=loading(action),copy={accounts:'Checking accounts',login:operation?.authorizationUrl?'Waiting for approval':'Connecting Cloudflare','save-sources':'Saving sources','save-account':'Saving account',deploy:'Deploying resources',reset:'Removing old archive',manifest:'Loading manifest','copy-manifest':'Copying manifest',activate:'Connecting Slack app',source:'Updating source',channels:'Enabling channels',verify:'Checking deliveries',finish:'Finishing setup',exit:'Saving progress'};return `<button class="button ${primary?'primary':''} ${active?'loading':''}" data-action="${action}" type="button" ${active?`aria-busy="true" aria-label="${copy[action]||'Working'}"`:''} ${disabled||busy||pending()&&action!=='copy-login-link'?'disabled':''}><span>${label}</span>${active?'<span class="spinner" aria-hidden="true"></span>':''}</button>`};
|
|
117
|
+
const foot=(action,label,disabled=false)=>`<div class="card-foot ${step?'':'first-step'}"><div class="foot-left">${step?'<button class="text-btn" data-back type="button">Back</button>':''}<span class="operation-status" id="operation" role="status" aria-live="polite"></span></div><div class="foot-right">${actionButton(label,action,true,disabled)}</div></div>`;
|
|
49
118
|
const item=(title,detail,right,klass='')=>`<div class="item"><span><strong>${title}</strong><small>${detail}</small></span><span class="status ${klass}">${right}</span></div>`;
|
|
50
119
|
const button=(label,action,primary=false,disabled=false)=>actionButton(label,action,primary,disabled);
|
|
51
120
|
const slackAppStep=(app,worker,team)=>{
|
|
52
121
|
const existing=Boolean(app);
|
|
53
122
|
if(existing&&!manifestReady)return head(3,'Repair an earlier Slack app','This app was created before the complete first-run manifest. Update this same app once to turn on link delivery.')+`<div class="card-body">
|
|
54
123
|
<p class="help">App ID: <strong>${esc(app)}</strong>. Do not create another app.</p>
|
|
55
|
-
<ol class="setup-steps"><li><strong>Copy the complete settings</strong><p>They include your registered link domains and the event address.</p>${button(
|
|
124
|
+
<ol class="setup-steps slack-app-steps"><li><div><strong>Copy the complete settings</strong><p>They include your registered link domains and the event address.</p></div><div class="step-control">${button('Copy manifest','copy-manifest')}</div></li><li><div><strong>Save in the existing app</strong><p>Open App Manifest, select JSON, replace the old JSON and save.</p></div><div class="step-control"><a class="button" href="https://app.slack.com/app-settings/${encodeURIComponent(team||'')}/${encodeURIComponent(app)}/app-manifest" target="_blank" rel="noopener noreferrer">Open app manifest</a></div></li><li><div><strong>Verify event delivery</strong><p>In Event Subscriptions, click Retry if the request URL is unverified. Wait for <strong>Verified</strong>, then click <strong>Save Changes</strong>.</p></div></li></ol>
|
|
56
125
|
<label class="check"><input id="slack-app-installed" type="checkbox" ${appInstalled?'checked':''}><span>The request URL says Verified and I clicked Save Changes in Slack<small>Verified alone is not enough. Slack must save the Event Subscriptions page before it sends links.</small></span></label>
|
|
57
126
|
</div>`+foot('manifest-applied','Choose channels',!manifestCopied||!appInstalled);
|
|
58
127
|
if(existing)return head(3,'Slack app connected','The initial manifest already includes the link domains and event receiver.')+`<div class="card-body"><p class="help">App ID: <strong>${esc(app)}</strong>.</p></div>`+foot('next','Choose channels');
|
|
59
128
|
return head(3,'Create and install your Slack app','Follow these steps in order. You need permission to install apps in your Slack workspace.')+`<div class="card-body">
|
|
60
|
-
<ol class="setup-steps">
|
|
61
|
-
<li><strong>Copy the app settings</strong><p>This copies JSON for Slack’s app manifest form.</p>${button(
|
|
62
|
-
<li><strong>Create the app in Slack</strong><p>Choose From a manifest, select your workspace, paste into the JSON tab, then review and create the app.</p><a class="button" href="https://api.slack.com/apps?new_app=1" target="_blank" rel="noopener noreferrer">Open Slack app creation
|
|
63
|
-
<li><strong>Verify and save event delivery</strong><p>In the new app’s Event Subscriptions page, the request URL must say <strong>Verified</strong>. If it does not, click <strong>Retry</strong>. Once it says Verified, click <strong>Save Changes</strong>.</p></li>
|
|
64
|
-
<li><strong>Install in your workspace</strong><p>Open Install App, choose Install to Workspace, then Allow.</p></li>
|
|
129
|
+
<ol class="setup-steps slack-app-steps">
|
|
130
|
+
<li><div><strong>Copy the app settings</strong><p>This copies JSON for Slack’s app manifest form.</p></div><div class="step-control">${button('Copy manifest','copy-manifest')}</div></li>
|
|
131
|
+
<li><div><strong>Create the app in Slack</strong><p>Choose From a manifest, select your workspace, paste into the JSON tab, then review and create the app.</p></div><div class="step-control"><a class="button" href="https://api.slack.com/apps?new_app=1" target="_blank" rel="noopener noreferrer">Open Slack app creation</a></div></li>
|
|
132
|
+
<li><div><strong>Verify and save event delivery</strong><p>In the new app’s Event Subscriptions page, the request URL must say <strong>Verified</strong>. If it does not, click <strong>Retry</strong>. Once it says Verified, click <strong>Save Changes</strong>.</p></div></li>
|
|
133
|
+
<li><div><strong>Install in your workspace</strong><p>Open Install App, choose Install to Workspace, then Allow.</p></div></li>
|
|
65
134
|
</ol>
|
|
66
|
-
${manifest?`<details class="
|
|
67
|
-
<details class="
|
|
135
|
+
${manifest?`<details class="disclosure"><summary><span>Manifest JSON (expand to inspect)</span><span class="chevron" aria-hidden="true"></span></summary><pre>${esc(JSON.stringify(manifest,null,2))}</pre></details>`:''}
|
|
136
|
+
<details class="disclosure"><summary><span>Permissions this app requests (expand to inspect)</span><span class="chevron" aria-hidden="true"></span></summary><ul><li><code>links:read</code> to receive matching links</li><li><code>links:write</code> to warn about unavailable links</li><li><code>files:write</code> to copy a file into its thread</li></ul></details>
|
|
68
137
|
${note('This is the complete manifest. It already includes your link domains and the event address. You will not replace it later.')}
|
|
69
138
|
<label class="check"><input id="slack-app-installed" type="checkbox" ${appInstalled?'checked':''}><span>I installed this app, its request URL says Verified, and I clicked Save Changes<small>Do this in Slack’s Event Subscriptions page before connecting the app here.</small></span></label>
|
|
70
139
|
</div>`+foot('next','Connect Slack to Worker',!worker||!appInstalled);
|
|
@@ -73,7 +142,7 @@
|
|
|
73
142
|
if(app)return head(4,'Slack app connected','This app is already connected to your archive Worker.')+`<div class="card-body">App ID: <code>${esc(app)}</code></div>`+foot('next','Choose channels');
|
|
74
143
|
return head(4,'Connect ArtifactPass Archive','Enter three values from the Slack app you created. ArtifactPass will configure Cloudflare for you.')+`<div class="card-body">
|
|
75
144
|
<p class="help">In Slack’s app list, select <strong>ArtifactPass Archive</strong> in your chosen workspace, not an older POC app.</p>
|
|
76
|
-
<p><a class="plain-link" href="https://api.slack.com/apps" target="_blank" rel="noopener noreferrer">Open your Slack apps
|
|
145
|
+
<p><a class="plain-link" href="https://api.slack.com/apps" target="_blank" rel="noopener noreferrer">Open your Slack apps</a></p>
|
|
77
146
|
<div class="form-row"><label class="label" for="app-id">App ID</label><input class="field" id="app-id" value="${esc(appId)}" placeholder="A1234567890" autocomplete="off"><p class="help">Copy the A… ID from that app’s row or Basic Information page.</p></div>
|
|
78
147
|
<div class="form-row"><label class="label" for="bot-token">Bot User OAuth Token</label><input class="field" id="bot-token" type="password" placeholder="xoxb-…" autocomplete="off" spellcheck="false"><p class="help">In that app: OAuth & Permissions → Bot User OAuth Token.</p></div>
|
|
79
148
|
<div class="form-row"><label class="label" for="signing-secret">Signing Secret</label><input class="field" id="signing-secret" type="password" placeholder="Paste signing secret" autocomplete="off" spellcheck="false"><p class="help">In that app: Basic Information → App Credentials → Signing Secret.</p></div>
|
|
@@ -84,35 +153,35 @@
|
|
|
84
153
|
const channelsAcknowledged=()=>!!config?.enabled_channels?.length&&config.enabled_channels.every(id=>joinedChannels.includes(id));
|
|
85
154
|
const canOpen=index=>index<2||index===2&&!!config?.account_id||index===3&&!!config?.worker_url||index===4&&!!config?.worker_url&&(appInstalled||!!config?.app_id)||index===6&&manifestReady||index===7&&manifestReady&&!!config?.enabled_channels?.length||index===8&&(config?.stage==='ready'||manifestReady&&channelsAcknowledged())||index===9&&(config?.stage==='ready'||verification?.verified===true&&inspected);
|
|
86
155
|
const go=number=>{if(!canOpen(number))return;step=number;error='';notice='';render();scrollTo({top:0,behavior:'auto'})};
|
|
87
|
-
const renderRail=()=>{const visible=labels.map((label,index)=>({label,index})).filter(x=>x.index!==5);const current=visible.findIndex(x=>x.index===step)+1;const wasOpen=renderedStep===step&&$('rail').querySelector('details')?.open;renderedStep=step;$('rail').innerHTML=`<details ${wasOpen?'open':''}><summary><span class="rail-current"><small>Step ${current} of ${visible.length}</small>${esc(labels[step])}</span><span class="rail-toggle">All steps
|
|
156
|
+
const renderRail=()=>{const visible=labels.map((label,index)=>({label,index})).filter(x=>x.index!==5);const current=visible.findIndex(x=>x.index===step)+1;const wasOpen=renderedStep===step&&$('rail').querySelector('details')?.open;renderedStep=step;$('rail').innerHTML=`<details ${wasOpen?'open':''}><summary><span class="rail-current"><small>Step ${current} of ${visible.length}</small>${esc(labels[step])}</span><span class="rail-toggle">All steps<span class="chevron" aria-hidden="true"></span></span></summary><div class="stage-list">${visible.map(({label,index},n)=>`<button class="stage ${index===step?'active':index<step?'done':''}" data-step="${index}" type="button" ${index===step?'aria-current="step"':''} ${canOpen(index)?'':'disabled'}><span class="number">${String(n+1).padStart(2,'0')}</span><span class="stage-title">${esc(label)}</span></button>`).join('')}</div></details>`};
|
|
88
157
|
const render=()=>{$('exit-top').disabled=busy||pending()||exited;renderRail();if(exited){$('card').innerHTML=head(step,'Progress saved','Run artifactpass slack setup again to continue from your local configuration.')+'<div class="card-body">You can close this tab.</div>';return}const account=config?.account_id,worker=config?.worker_url,app=config?.app_id,enabled=config?.enabled_channels||[],privateSources=(config?.sources||[]).filter(source=>source!=='https://artifactpass.com'),loginLink=operation?.kind==='login'&&operation.status==='working'?operation.authorizationUrl:null;let content='';
|
|
89
158
|
if(step===0){
|
|
90
159
|
if(worker)content=head(0,'Link sources already saved','This archive already has Cloudflare resources. Review its sources here or continue the saved setup.')+`<div class="card-body"><div class="item-list">${(config?.sources||[]).map(source=>item(esc(source),'Registered link domain','Saved')).join('')}</div>${note('Deleting the Slack app does not reset this archive. To choose different domains in a fresh setup, start over below.','warn')}<div class="item-list">${item('Worker',esc(config?.worker_name||worker),'Delete','pending')}${item('Queue',esc(config?.queue_name||'None'),'Delete','pending')}${item('D1 delivery history',esc(config?.worker_name?config.worker_name+'-db':'None'),'Delete','pending')}</div><label class="check"><input id="approve-reset" type="checkbox" ${resetApproved?'checked':''}><span>I understand starting over permanently deletes these Cloudflare resources and D1 delivery history<small>Slack files already posted are not deleted. You must create a new Slack app after resetting.</small></span></label><div class="actions">${button('Delete old archive and start over','reset',false,!resetApproved)}</div></div>`+foot('next','Continue saved setup');
|
|
91
160
|
else content=head(0,'Choose link sources','Choose every link domain before creating the Slack app. Slack registers these domains in its initial manifest.')+`<div class="card-body"><div class="item-list">${item('Public ArtifactPass','https://artifactpass.com','Included')}</div><label class="check"><input id="include-private" type="checkbox" ${includePrivate?'checked':''}><span>Also add a private deployment<small>For example, https://artifacts.example.com.</small></span></label>${includePrivate?`<div class="form-row"><label class="label" for="private-origin">Private deployment origins, one per line</label><textarea class="field" id="private-origin" placeholder="https://artifacts.example.com">${esc(privateOrigin||privateSources.join('\n'))}</textarea><p class="help">Enter the origin only, not an artifact link. You can include up to four private domains.</p></div>`:''}</div>`+foot('save-sources','Choose Cloudflare account',includePrivate&&!privateOrigin.trim()&&!privateSources.length);
|
|
92
161
|
}
|
|
93
|
-
else if(step===1)content=head(1,'Use your Cloudflare account','Choose the account that will own this separate Worker, Queue, and D1 database.')+`<div class="card-body"><div class="
|
|
162
|
+
else if(step===1){const selectedAccount=accountId||account||'';content=head(1,'Use your Cloudflare account','Choose the account that will own this separate Worker, Queue, and D1 database.')+`<div class="card-body">${accountsChecking?'<div class="account-loading" role="status"><span class="spinner" aria-hidden="true"></span>Finding Cloudflare accounts on this computer…</div>':accounts.length?`<div class="form-row"><fieldset class="account-choices"><legend>Cloudflare account</legend>${accounts.map(a=>`<label class="account-choice"><input type="radio" name="account" value="${esc(a.id)}" ${a.id===selectedAccount?'checked':''}><span><span class="account-choice-name">${esc(a.name)}</span><span class="account-choice-id">${esc(a.id)}</span></span></label>`).join('')}</fieldset></div><div class="account-actions"><button class="text-btn" data-action="login" type="button">Use a different Cloudflare sign-in</button></div>`:`<p class="help">${accountError?'No connected Cloudflare account was found. Sign in to continue.':'Sign in to the Cloudflare account that should own this archive.'}</p><div class="actions">${button('Connect Cloudflare','login',true)}</div>`}${loginLink?`<div class="note good"><strong>Complete Cloudflare sign-in</strong><p>Open this link in the browser profile for the right account. Your accounts will appear here after approval.</p><div class="actions"><a class="button primary" href="${esc(loginLink)}" target="_blank" rel="noopener noreferrer">Open Cloudflare sign-in</a>${button('Copy link','copy-login-link')}</div></div>`:''}${accountError&&accounts.length?`<p class="help">${esc(accountError)}</p>`:''}${note('A Cloudflare account with a workers.dev subdomain is required. This does not transfer your domain or create an ArtifactPass deployment.','warn')}</div>`+foot('save-account','Review resources',!accounts.some(a=>a.id===selectedAccount))}
|
|
94
163
|
else if(step===2)content=head(2,'Review what will be created','Only these three resources are created in the selected Cloudflare account.')+`<div class="card-body"><div class="item-list">${item('Worker','Receives signed Slack link events',worker?'Created':'To create',worker?'':'pending')}${item('Queue','Processes archive requests',worker?'Created':'To create',worker?'':'pending')}${item('D1 database','Delivery and deduplication metadata, not file bytes',worker?'Created':'To create',worker?'':'pending')}</div>${worker?note('Worker is deployed: <strong>'+esc(worker)+'</strong>','good'):`<label class="check"><input id="approve-resources" type="checkbox" ${approved?'checked':''}><span>I approve creating these resources<small>Cloudflare may count their usage against this account’s plan.</small></span></label>`}${note('No R2 bucket, private ArtifactPass deployment, registrar change, or plan upgrade is requested.')}</div>`+foot(worker?'next':'deploy',worker?'Set up Slack app':'Approve and deploy',!worker&&!approved);
|
|
95
164
|
else if(step===3)content=slackAppStep(app,worker,config?.team_id);
|
|
96
165
|
else if(step===4)content=workerSecretsStep(app);
|
|
97
166
|
else if(step===6)content=head(6,'Choose channels','Choose where ArtifactPass Archive should work. This saves the channel list in your Worker; the next step adds the app in Slack.')+`<div class="card-body"><div class="form-row"><label class="label" for="channels">Slack channel links or IDs, one per line</label><textarea class="field" id="channels" placeholder="https://example.slack.com/archives/C1234567890 https://example.slack.com/archives/G1234567890">${esc(channelsText)}</textarea></div><div class="actions">${button('Save selected channels','channels',false,!channelsText.trim())}</div>${enabled.length?`<div class="item-list">${enabled.map(id=>item(esc(id),'Selected channel','Saved')).join('')}</div>`:''}</div>`+foot('next','Add app to channels',!enabled.length);
|
|
98
|
-
else if(step===7)content=head(7,'Add the app to each Slack channel','Installing the app in your workspace does not add it to channels. Complete each channel below before testing a link.')+`<div class="card-body"><p class="help">Use the same <strong>ArtifactPass Archive</strong> app (ID <code>${esc(app||'')}</code>) in every selected channel. In Slack, open the channel details, then Agents and apps → Add agent or app.</p><ol class="setup-steps">${enabled.map(id=>`<li><strong>${esc(id)}</strong><p>Add ArtifactPass Archive to this channel, then check that it appears under Agents and apps.</p><a class="button" href="https://app.slack.com/client/${esc(config?.team_id||'')}/${esc(id)}" target="_blank" rel="noreferrer noopener">Open channel in Slack
|
|
167
|
+
else if(step===7)content=head(7,'Add the app to each Slack channel','Installing the app in your workspace does not add it to channels. Complete each channel below before testing a link.')+`<div class="card-body"><p class="help">Use the same <strong>ArtifactPass Archive</strong> app (ID <code>${esc(app||'')}</code>) in every selected channel. In Slack, open the channel details, then Agents and apps → Add agent or app.</p><ol class="setup-steps">${enabled.map(id=>`<li><strong>${esc(id)}</strong><p>Add ArtifactPass Archive to this channel, then check that it appears under Agents and apps.</p><a class="button" href="https://app.slack.com/client/${esc(config?.team_id||'')}/${esc(id)}" target="_blank" rel="noreferrer noopener">Open channel in Slack</a><label class="check"><input data-joined-channel="${esc(id)}" type="checkbox" ${joinedChannels.includes(id)?'checked':''}><span>I can see ArtifactPass Archive in this channel’s Agents and apps</span></label></li>`).join('')}</ol>${note('These checkboxes record your confirmation, not an automatic Slack membership check. The next step verifies a real file arrives in each channel.','warn')}</div>`+foot('next','Test link delivery',!channelsAcknowledged());
|
|
99
168
|
else if(step===8){const ready=config?.stage==='ready'&&!!config?.verified_at;const distinctFailures=[...new Map((verification?.failures||[]).map(f=>[f.channel_id+':'+f.last_error_code,f])).values()];content=head(8,'Verify each channel and source',ready?'These channels and sources were confirmed during setup. You can check delivery history again at any time.':'Check a real file in Slack before completing setup. Verification needs a new delivery after your latest setup change.')+
|
|
100
169
|
`<div class="card-body"><ol class="guide-steps"><li>Create a small test file and share it from each source: ${(config?.sources||[]).map(origin=>`<a href="${esc(origin)}/upload" target="_blank" rel="noreferrer noopener">${esc(origin)}/upload</a>`).join(' and ')}. Sign in there if asked, then copy the new link.</li><li>Post the link in an enabled channel. For multiple channels, post a link in each. The bot should reply with the file in that message’s thread.</li><li>Open and download the Slack file. Confirm its contents match, then choose <strong>Check real deliveries</strong>. One post can count for both its source and its channel.</li></ol><div class="item-list">${enabled.map(id=>{const verified=ready||verification?.channels?.find(c=>c.channel_id===id)?.verified;return item(`<a href="https://app.slack.com/client/${esc(config?.team_id||'')}/${esc(id)}" target="_blank" rel="noreferrer noopener">${esc(id)}</a>`,'A new file should appear in the original thread',verified?'Verified':'Waiting for new file',verified?'':'pending')}).join('')}</div>`+
|
|
101
170
|
`<div class="item-list">${(config?.sources||[]).map(origin=>{const verified=ready||verification?.verified_sources?.find(source=>source.origin===origin)?.verified;return item(esc(origin),'Post one new link from this source',verified?'Verified':'Waiting for new file',verified?'':'pending')}).join('')}</div>`+
|
|
102
171
|
`<div class="actions">${button('Check real deliveries','verify')}</div>${verification?`<p class="help">Archive delivery history: ${verification.counts?.succeeded||0} copied, ${verification.counts?.failed||0} failed, ${verification.counts?.needs_review||0} need review. Earlier failures do not block a new successful test.</p>${!ready&&verification.counts&&Object.values(verification.counts).every(count=>count===0)?note('<strong>No file has reached the archive.</strong> In Slack, open <a href="https://api.slack.com/apps/'+encodeURIComponent(app||'')+'/event-subscriptions" target="_blank" rel="noopener noreferrer">Event Subscriptions for app '+esc(app||'')+'</a>. Make sure the request URL says Verified, <code>link_shared</code> is subscribed, and click <strong>Save Changes</strong>. Then open each selected channel above and add this same app under <strong>Agents and apps</strong>. Post a fresh link after those changes; old posts are not replayed.','warn'):''}${verification.verified||ready?'':distinctFailures.map(f=>note('Channel '+esc(f.channel_id)+': '+(f.last_error_code==='source_expired'||f.last_error_code==='source_unavailable'?'This link has expired or is unavailable. Create and post a fresh link.':f.last_error_code==='source_not_approved'?'Add this source to the Worker and apply the updated Slack app manifest, then post a fresh link.':'Check <code>pnpm dlx artifactpass slack status</code> for the next action ('+esc(f.last_error_code||'unknown')+').'),'error')).join('')}`:''}${ready?'':`<label class="check"><input id="inspected" type="checkbox" ${inspected?'checked':''}><span>I checked the actual Slack threads and downloaded files<small>Confirm the file opens and matches the shared source before inviting a wider team.</small></span></label>`}${note('An expired or inaccessible link cannot be copied. Post a fresh link. Setup is complete only after each selected channel and source has a confirmed delivery.')}</div>`+foot(ready?'next':'finish',ready?'Back to Ready':'Finish',!ready&&(!verification?.verified||!inspected))}
|
|
103
172
|
else content=head(9,'Archive is ready','Real deliveries have been verified for the enabled channels.')+`<div class="card-body">${note('<strong>Setup complete.</strong> The bot runs in your Cloudflare account. A fresh ArtifactPass link posted in an enabled channel should be copied into that message thread.','good')}<div class="item-list">${item('Worker',esc(worker||''),'Active')}${item('Sources',esc((config?.sources||[]).join(', ')),'Approved')}${item('Channels',esc(enabled.join(', ')),'Verified')}</div>${note('The Slack copy follows your workspace retention policy, even after the ArtifactPass link expires. Use <code>pnpm dlx artifactpass slack status</code> to inspect later deliveries.')}</div>`+foot('exit','Close setup');
|
|
104
|
-
$('card').innerHTML=content;const status=$('operation');if(status){status.textContent=pending()?operation.message+'…':operation?.status==='failed'?operation.message:error||notice||(operation?.status==='complete'?operation.message:'');status.className='operation-status'+(operation?.status==='failed'||error?' error':notice||operation?.status==='complete'?' good':'')}
|
|
173
|
+
$('card').innerHTML=content;const status=$('operation');if(status){status.textContent=pending()?operation.message+'…':operation?.status==='failed'?operation.message:error||notice||(operation?.status==='complete'?operation.message:'');status.className='operation-status'+(operation?.status==='failed'||error?' error':notice||operation?.status==='complete'?' good':'')}if(step===1&&!accountsChecked&&!accountsChecking)void checkAccounts()
|
|
105
174
|
};
|
|
106
|
-
const refresh=async()=>{const result=await api('state');const before=JSON.stringify([config,manifestReady,operation,accounts]);const wasRunning=pending();config=result.configuration;manifestReady=result.manifest_ready;operation=result.operation;accounts=result.accounts||[];includePrivate=includePrivate||(config?.sources?.length||0)>1;if(wasRunning&&operation?.status==='complete'){const kind=operation.kind;if(kind==='deploy'){step=3;manifest=null;appInstalled=false;manifestCopied=false}else if(kind==='activate'){step=6;manifest=null;appInstalled=false;manifestCopied=false}else if(kind==='channels'){step=7;joinedChannels=[]}else if(kind==='source'){step=3;manifest=null;appInstalled=false;manifestCopied=false}else if(kind==='reset'){step=0;includePrivate=false;accountId='';privateOrigin='';appId='';channelsText='';joinedChannels=[];approved=false;resetApproved=false;appInstalled=false;manifestCopied=false;inspected=false;verification=null;manifest=null}}if(before!==JSON.stringify([config,manifestReady,operation,accounts]))render()};
|
|
175
|
+
const refresh=async()=>{const result=await api('state');const before=JSON.stringify([config,manifestReady,operation,accounts]);const wasRunning=pending();config=result.configuration;manifestReady=result.manifest_ready;operation=result.operation;accounts=result.accounts||[];if(accounts.length){accountsChecked=true;accountError=''}includePrivate=includePrivate||(config?.sources?.length||0)>1;if(wasRunning&&operation?.status==='complete'){const kind=operation.kind;if(kind==='deploy'){step=3;manifest=null;appInstalled=false;manifestCopied=false}else if(kind==='activate'){step=6;manifest=null;appInstalled=false;manifestCopied=false}else if(kind==='channels'){step=7;joinedChannels=[]}else if(kind==='source'){step=3;manifest=null;appInstalled=false;manifestCopied=false}else if(kind==='reset'){step=0;includePrivate=false;accountId='';privateOrigin='';appId='';channelsText='';joinedChannels=[];approved=false;resetApproved=false;appInstalled=false;manifestCopied=false;inspected=false;verification=null;manifest=null}}if(before!==JSON.stringify([config,manifestReady,operation,accounts]))render()};
|
|
107
176
|
const act=async (action,credentials)=>{error='';notice='';if(action==='next'){next();return}if(action==='exit'){await api('exit','POST',{});exited=true;render();return}if(action==='reset'){if(!resetApproved||!config?.worker_name)throw Error('Confirm deletion of the exact old archive first');await api('reset','POST',{confirmedResourceName:config.worker_name});await refresh();return}if(action==='save-sources'){const privateOrigins=includePrivate?privateOrigin.split(/[\n,]+/).map(s=>s.trim()).filter(Boolean):[];if(includePrivate&&!privateOrigins.length)throw Error('Enter at least one private deployment origin');await api('initial-sources','POST',{privateOrigins});await refresh();go(1);return}if(action==='accounts'){const result=await api('accounts','POST',{});accounts=result.accounts;accountId=config?.account_id||accountId;render();return}if(action==='login'){await api('login','POST',{});await refresh();return}if(action==='copy-login-link'){if(!operation?.authorizationUrl)throw Error('The Cloudflare sign-in link is not ready yet');await navigator.clipboard.writeText(operation.authorizationUrl);notice='Cloudflare sign-in link copied.';render();return}if(action==='save-account'){if(!config?.account_id||accountId!==config.account_id)await api('account','POST',{accountId});await refresh();go(2);return}if(action==='deploy'){if(!approved)throw Error('Approve the exact resources first');await api('deploy','POST',{approved:true});await refresh();return}if(action==='manifest'||action==='copy-manifest'){const result=await api('manifest');manifest=result.manifest;if(action==='copy-manifest'){await navigator.clipboard.writeText(JSON.stringify(manifest,null,2));manifestCopied=true;notice=config?.app_id?'Manifest copied. Save it in the existing Slack app.':'Complete manifest copied. In Slack, choose From a manifest and paste it into the JSON tab.'}render();return}if(action==='activate'){await api('activate','POST',{appId,initialManifestInstalled:true,...credentials});await refresh();return}if(action==='manifest-applied'){if(!manifestCopied||!appInstalled)throw Error('Save the complete manifest in Slack before continuing');await api('manifest-applied','POST',{applied:true});await refresh();go(6);return}if(action==='source'){await api('source','POST',{origin:privateOrigin||(config?.sources||[]).find(source=>source!=='https://artifactpass.com')||''});await refresh();return}if(action==='channels'){const channels=channelsText.split(/[\n,]+/).map(s=>s.trim()).filter(Boolean);await api('channels','POST',{channels});await refresh();return}if(action==='verify'){const result=await api('verify','POST',{});verification=result.status;await refresh();return}if(action==='finish'){await api('finish','POST',{inspected:true});await refresh();go(9);return}};
|
|
108
177
|
const showBusy=target=>{const buttons=[...$('card').querySelectorAll('button[data-action],button[data-back]'),...$('rail').querySelectorAll('button[data-step]'),$('exit-top')];const previous=buttons.map(button=>[button,button.disabled]);for(const button of buttons)button.disabled=true;target.classList.add('loading');target.setAttribute('aria-busy','true');target.insertAdjacentHTML('beforeend','<span class="spinner" aria-hidden="true"></span>');return()=>{for(const [button,disabled] of previous)if(button.isConnected)button.disabled=disabled;if(target.isConnected){target.classList.remove('loading');target.removeAttribute('aria-busy');target.querySelector('.spinner')?.remove()}}};
|
|
109
178
|
$('card').addEventListener('click',async event=>{const target=event.target.closest('[data-action],[data-back]');if(!target||busy)return;if(target.hasAttribute('data-back')){go(step===6?4:Math.max(0,step-1));return}for(const oldError of $('card').querySelectorAll('.action-error'))oldError.remove();const action=target.dataset.action;const credentials=action==='activate'?{botToken:$('bot-token').value.trim(),signingSecret:$('signing-secret').value.trim()}:undefined;busy=true;busyAction=action;const restore=showBusy(target);try{await act(action,credentials);busy=false;busyAction='';render()}catch(caught){busy=false;busyAction='';restore();error=caught.message;const status=$('operation');if(status){status.textContent=error;status.className='operation-status error'}if(!target.closest('.card-foot'))target.insertAdjacentHTML('afterend',`<span class="action-error" role="alert">${esc(error)}</span>`)}});
|
|
110
|
-
$('card').addEventListener('input',event=>{const field=event.target;if(field.
|
|
179
|
+
$('card').addEventListener('input',event=>{const field=event.target;if(field.name==='account')accountId=field.value;if(field.id==='app-id')appId=field.value.trim();if(field.id==='private-origin')privateOrigin=field.value.trim();if(field.id==='channels')channelsText=field.value;const action=$('card').querySelector('.card-foot [data-action]');if(action){if(step===0)action.disabled=includePrivate&&!privateOrigin.trim();if(step===1)action.disabled=!accounts.some(account=>account.id===accountId);if(step===4)action.disabled=!config?.app_id&&(!appId||!$('bot-token')?.value.trim()||!$('signing-secret')?.value.trim())}if(step===6&&field.id==='channels'){const add=$('card').querySelector('[data-action="channels"]');if(add)add.disabled=!channelsText.trim()}});
|
|
111
180
|
$('card').addEventListener('change',event=>{if(event.target.id==='include-private'){includePrivate=event.target.checked;render();if(includePrivate)$('private-origin')?.focus()}if(event.target.id==='approve-resources'){approved=event.target.checked;$('card').querySelector('[data-action="deploy"]').disabled=!approved}if(event.target.id==='approve-reset'){resetApproved=event.target.checked;$('card').querySelector('[data-action="reset"]').disabled=!resetApproved}if(event.target.id==='slack-app-installed'){appInstalled=event.target.checked;const action=$('card').querySelector('.card-foot [data-action]');if(action)action.disabled=!!config?.app_id?!appInstalled||!manifestCopied:!appInstalled}if(event.target.hasAttribute('data-joined-channel')){const id=event.target.dataset.joinedChannel;joinedChannels=event.target.checked?[...new Set([...joinedChannels,id])]:joinedChannels.filter(channel=>channel!==id);$('card').querySelector('.card-foot [data-action]').disabled=!channelsAcknowledged()}if(event.target.id==='inspected'){inspected=event.target.checked;$('card').querySelector('[data-action="finish"]').disabled=!verification?.verified||!inspected}});
|
|
112
181
|
$('rail').addEventListener('click',event=>{const target=event.target.closest('[data-step]');if(target&&!busy&&!pending())go(Number(target.dataset.step))});
|
|
113
182
|
$('exit-top').addEventListener('click',async()=>{if(busy||pending())return;const exitButton=$('exit-top');busy=true;exitButton.disabled=true;exitButton.textContent='Saving…';try{await act('exit')}catch(caught){error=caught.message;const status=$('operation');if(status){status.textContent=error;status.className='operation-status error'}}finally{busy=false;exitButton.textContent='Save and exit';exitButton.disabled=exited;if(exited)render()}});
|
|
114
183
|
const resumeStep=()=>{if(config?.stage==='ready')step=9;else if(config?.app_id&&!manifestReady)step=3;else if(config?.enabled_channels?.length)step=7;else if(config?.app_id)step=6;else if(config?.worker_url)step=3;else if(config?.account_id)step=2;else step=0};
|
|
115
|
-
api('state').then(result=>{config=result.configuration;manifestReady=result.manifest_ready;operation=result.operation;accounts=result.accounts||[];includePrivate=(config?.sources?.length||0)>1;privateOrigin=(config?.sources||[]).filter(source=>source!=='https://artifactpass.com').join('\n');accountId=config?.account_id||'';appId=config?.app_id||'';resumeStep();render()}).catch(caught=>{$('card').innerHTML=head(0,'Setup link unavailable','Re-run the CLI and open its latest local link.')+`<div class="card-body">${esc(caught.message)}</div>`});
|
|
184
|
+
api('state').then(result=>{config=result.configuration;manifestReady=result.manifest_ready;operation=result.operation;accounts=result.accounts||[];accountsChecked=accounts.length>0;includePrivate=(config?.sources?.length||0)>1;privateOrigin=(config?.sources||[]).filter(source=>source!=='https://artifactpass.com').join('\n');accountId=config?.account_id||(accounts.length===1?accounts[0].id:'');appId=config?.app_id||'';resumeStep();render()}).catch(caught=>{$('card').innerHTML=head(0,'Setup link unavailable','Re-run the CLI and open its latest local link.')+`<div class="card-body">${esc(caught.message)}</div>`});
|
|
116
185
|
setInterval(()=>{if(pending())void refresh().catch(caught=>{error=caught.message;render()})},1200);
|
|
117
186
|
})();
|
|
118
187
|
</script>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "artifactpass",
|
|
3
|
-
"version": "0.1.12-rc.
|
|
3
|
+
"version": "0.1.12-rc.4",
|
|
4
4
|
"description": "Install and connect ArtifactPass for compatible AI agent systems.",
|
|
5
5
|
"homepage": "https://artifactpass.com",
|
|
6
6
|
"keywords": [
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"@types/node": "^24.10.14",
|
|
43
43
|
"typescript": "^7.0.2",
|
|
44
44
|
"vitest": "^4.1.10",
|
|
45
|
+
"artifact-service": "0.0.0",
|
|
45
46
|
"agent-bridge": "0.0.0",
|
|
46
|
-
"artifact-protocol": "0.0.0"
|
|
47
|
-
"artifact-service": "0.0.0"
|
|
47
|
+
"artifact-protocol": "0.0.0"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "pnpm --dir ../../apps/artifact-service build && node ../../scripts/build-setup-package.mjs",
|