@harborppm/cli 0.75.0 → 0.76.0
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/app.mjs +20 -9
- package/lib/cli.mjs +2 -2
- package/package.json +1 -1
package/dist/app.mjs
CHANGED
|
@@ -18813,10 +18813,17 @@ function harborExport(data, harbor, now) {
|
|
|
18813
18813
|
* through Import.
|
|
18814
18814
|
*/
|
|
18815
18815
|
function allTasksCsv(data) {
|
|
18816
|
+
return tasksSheetCsv(data, data.tasks);
|
|
18817
|
+
}
|
|
18818
|
+
/**
|
|
18819
|
+
* These tasks, one row each, as `allTasksCsv` lays them out: the whole
|
|
18820
|
+
* harbor's, or a program's for a sheet link (src/lib/sheet-feed.ts).
|
|
18821
|
+
*/
|
|
18822
|
+
function tasksSheetCsv(data, rows) {
|
|
18816
18823
|
const projects = byId(data.projects);
|
|
18817
18824
|
const programs = byId(data.programs);
|
|
18818
18825
|
const people = byId(data.people);
|
|
18819
|
-
const tasks = byId(
|
|
18826
|
+
const tasks = byId(rows);
|
|
18820
18827
|
const keyOf = (t) => taskKey(t, projects.get(t.projectId)) ?? t.title;
|
|
18821
18828
|
return toCsv([
|
|
18822
18829
|
"Key",
|
|
@@ -18831,7 +18838,7 @@ function allTasksCsv(data) {
|
|
|
18831
18838
|
"Blocked by",
|
|
18832
18839
|
"Created",
|
|
18833
18840
|
"Description"
|
|
18834
|
-
],
|
|
18841
|
+
], rows.map((t) => {
|
|
18835
18842
|
const project = projects.get(t.projectId);
|
|
18836
18843
|
const program = project ? programs.get(project.programId) : void 0;
|
|
18837
18844
|
return [
|
|
@@ -21340,10 +21347,11 @@ function viewerUpdate(state, partial) {
|
|
|
21340
21347
|
}
|
|
21341
21348
|
/**
|
|
21342
21349
|
* Whether this saved harbor can't be changed from here: the person is a
|
|
21343
|
-
* viewer,
|
|
21350
|
+
* viewer, its free trial has ended with nobody keeping it (keep.ts), or it
|
|
21351
|
+
* was opened offline from this device's copy (`offlineCopy`).
|
|
21344
21352
|
*/
|
|
21345
21353
|
function readOnlyHarbor(s) {
|
|
21346
|
-
return s.cloud && (s.myRole === "viewer" || Boolean(s.keepPaused));
|
|
21354
|
+
return s.cloud && (s.myRole === "viewer" || Boolean(s.keepPaused) || Boolean(s.offlineCopy));
|
|
21347
21355
|
}
|
|
21348
21356
|
var VIEWER_LOCAL, documentKeys;
|
|
21349
21357
|
var init_view_only = __esmMin((() => {
|
|
@@ -21798,6 +21806,7 @@ function sessionSlice({ set, get, write }) {
|
|
|
21798
21806
|
}),
|
|
21799
21807
|
setWorkspaceVersion: (workspaceVersion) => set({ workspaceVersion }),
|
|
21800
21808
|
setPhase: (phase) => set({ phase }),
|
|
21809
|
+
setOfflineCopy: (offlineCopy) => set({ offlineCopy }),
|
|
21801
21810
|
setMyRole: (myRole) => set({ myRole }),
|
|
21802
21811
|
setHarborName: (harborName) => set({ harborName }),
|
|
21803
21812
|
setKeep: (k) => set({
|
|
@@ -24828,6 +24837,7 @@ function shoreService(raw) {
|
|
|
24828
24837
|
if ((host === "discord.com" || host === "discordapp.com" || host === "ptb.discord.com" || host === "canary.discord.com") && /^\/api\/webhooks\/\d+\/[\w-]+$/.test(path)) return "discord";
|
|
24829
24838
|
if (/^[a-z0-9-]+\.webhook\.office\.com$/.test(host) && path.startsWith("/webhookb2/")) return "teams";
|
|
24830
24839
|
if ((/^[a-z0-9.-]+\.logic\.azure\.com$/.test(host) || /^[a-z0-9.-]+\.environment\.api\.powerplatform\.com$/.test(host)) && path.includes("/workflows/")) return "teams-workflow";
|
|
24840
|
+
if (host === "chat.googleapis.com" && /^\/v1\/spaces\/[\w-]+\/messages$/.test(path) && url.searchParams.get("key") && url.searchParams.get("token")) return "google-chat";
|
|
24831
24841
|
return null;
|
|
24832
24842
|
}
|
|
24833
24843
|
/** "hooks.slack.com/…8f2Q": enough to recognise an address without showing the secret in it. */
|
|
@@ -24846,7 +24856,8 @@ var init_shore = __esmMin((() => {
|
|
|
24846
24856
|
slack: "Slack",
|
|
24847
24857
|
discord: "Discord",
|
|
24848
24858
|
teams: "Teams",
|
|
24849
|
-
"teams-workflow": "Teams"
|
|
24859
|
+
"teams-workflow": "Teams",
|
|
24860
|
+
"google-chat": "Google Chat"
|
|
24850
24861
|
};
|
|
24851
24862
|
SHORE_KINDS = [
|
|
24852
24863
|
{
|
|
@@ -24938,7 +24949,7 @@ function memoryHarbor(start, opts) {
|
|
|
24938
24949
|
}
|
|
24939
24950
|
let row = hooks.get(program.id);
|
|
24940
24951
|
if (ask.url || ask.on?.length || ask.off?.length) {
|
|
24941
|
-
if (ask.url && !shoreService(ask.url)) throw new TransportError("That isn’t a Slack, Discord or
|
|
24952
|
+
if (ask.url && !shoreService(ask.url)) throw new TransportError("That isn’t a Slack, Discord, Teams or Google Chat incoming-webhook address.", 400);
|
|
24942
24953
|
const url = ask.url || row?.url;
|
|
24943
24954
|
if (!url) throw new TransportError("Paste the channel’s address first.", 400);
|
|
24944
24955
|
row = {
|
|
@@ -26555,7 +26566,7 @@ function LifeboatsPanel({ id, width, height, go, active, onClose }) {
|
|
|
26555
26566
|
|
|
26556
26567
|
// src/tui/views/shore.tsx
|
|
26557
26568
|
/**
|
|
26558
|
-
* Ship to shore in the terminal: a program's Slack, Discord or
|
|
26569
|
+
* Ship to shore in the terminal: a program's Slack, Discord, Teams or Google Chat channel
|
|
26559
26570
|
* and which posts go there, as the website's dialog sets it (shore.ts). The
|
|
26560
26571
|
* address is a secret, so once saved only a hint of it shows. Asks /api/app's
|
|
26561
26572
|
* `shore` (the in-memory server keeps a pretend one).
|
|
@@ -26608,7 +26619,7 @@ function ShorePanel({ id, width, height, go, active, onClose }) {
|
|
|
26608
26619
|
if (input === "p") return go.ask("The channel's incoming-webhook address", (text) => {
|
|
26609
26620
|
const url = text.trim();
|
|
26610
26621
|
if (!url) return;
|
|
26611
|
-
if (!shoreService(url)) return go.notify("That isn't a Slack, Discord or
|
|
26622
|
+
if (!shoreService(url)) return go.notify("That isn't a Slack, Discord, Teams or Google Chat incoming-webhook address. It starts https://hooks.slack.com/, https://discord.com/api/webhooks/, https://chat.googleapis.com/ or a Teams workflow address.");
|
|
26612
26623
|
send({ url }, (a) => `Connected to ${a.hook?.service ?? "the channel"}. Turn on what it posts.`);
|
|
26613
26624
|
});
|
|
26614
26625
|
if (!hook) return;
|
|
@@ -26654,7 +26665,7 @@ function ShorePanel({ id, width, height, go, active, onClose }) {
|
|
|
26654
26665
|
/* @__PURE__ */ jsx(Text, {
|
|
26655
26666
|
color: theme.muted,
|
|
26656
26667
|
wrap: "wrap",
|
|
26657
|
-
children: "Harbor posts into one Slack, Discord or
|
|
26668
|
+
children: "Harbor posts into one Slack, Discord, Teams or Google Chat channel for this program instead of sending mail. Each post links back here."
|
|
26658
26669
|
}),
|
|
26659
26670
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
26660
26671
|
failed ? /* @__PURE__ */ jsx(Text, {
|
package/lib/cli.mjs
CHANGED
|
@@ -769,8 +769,8 @@ const DETAIL = {
|
|
|
769
769
|
shore: [
|
|
770
770
|
" harbor shore PROGRAM reads the program's chat channel and",
|
|
771
771
|
" which posts go there",
|
|
772
|
-
" harbor shore PROGRAM --url URL writes: posts go to this Slack, Discord",
|
|
773
|
-
" or
|
|
772
|
+
" harbor shore PROGRAM --url URL writes: posts go to this Slack, Discord,",
|
|
773
|
+
" Teams or Google Chat webhook address",
|
|
774
774
|
" harbor shore PROGRAM --on KINDS writes: turns posts on; KINDS are",
|
|
775
775
|
" forecast, health and notes, with commas",
|
|
776
776
|
" harbor shore PROGRAM --off KINDS writes: turns them off",
|