@skrr-ai/cli 0.1.91 → 0.1.93
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/base-command.d.ts +44 -0
- package/dist/base-command.js +96 -0
- package/dist/commands/agents/badge.d.ts +41 -0
- package/dist/commands/agents/badge.js +158 -0
- package/dist/commands/agents/create.d.ts +24 -0
- package/dist/commands/agents/create.js +212 -0
- package/dist/commands/agents/embed.d.ts +20 -0
- package/dist/commands/agents/embed.js +61 -0
- package/dist/commands/agents/share.d.ts +27 -0
- package/dist/commands/agents/share.js +100 -0
- package/dist/commands/agents/vanity.d.ts +21 -0
- package/dist/commands/agents/vanity.js +77 -0
- package/dist/commands/agents/visibility.d.ts +21 -1
- package/dist/commands/agents/visibility.js +112 -0
- package/dist/commands/commands.d.ts +1 -0
- package/dist/commands/commands.js +22 -9
- package/dist/commands/earnings/attributions.d.ts +17 -0
- package/dist/commands/earnings/attributions.js +82 -0
- package/dist/commands/earnings/index.js +2 -1
- package/dist/commands/generate-recovery-code.js +4 -3
- package/dist/commands/github/allow-tools.d.ts +1 -0
- package/dist/commands/github/app/install.d.ts +1 -0
- package/dist/commands/github/app/status.d.ts +1 -0
- package/dist/commands/github/connect.d.ts +1 -0
- package/dist/commands/github/connections.d.ts +1 -0
- package/dist/commands/github/disconnect.d.ts +1 -0
- package/dist/commands/github/finalize.d.ts +1 -0
- package/dist/commands/github/reconnect.d.ts +1 -0
- package/dist/commands/github/run.d.ts +1 -0
- package/dist/commands/github/tools.d.ts +1 -0
- package/dist/commands/integrations/connections/connect.d.ts +1 -0
- package/dist/commands/integrations/connections/disconnect.d.ts +1 -0
- package/dist/commands/integrations/connections/finalize.d.ts +1 -0
- package/dist/commands/integrations/connections/list.d.ts +1 -0
- package/dist/commands/integrations/connections/reconnect.d.ts +1 -0
- package/dist/commands/integrations/execute.d.ts +1 -0
- package/dist/commands/integrations/search.d.ts +1 -0
- package/dist/commands/integrations/toolkits.d.ts +1 -0
- package/dist/commands/integrations/tools/allow.d.ts +1 -0
- package/dist/commands/integrations/tools/list.d.ts +1 -0
- package/dist/commands/login.js +12 -0
- package/dist/commands/machines/dedicated/logs.d.ts +19 -0
- package/dist/commands/machines/dedicated/logs.js +103 -0
- package/dist/commands/machines/dedicated/power/index.js +3 -2
- package/dist/commands/machines/dedicated/power/set.js +1 -1
- package/dist/commands/machines/dedicated/power/waiting.d.ts +13 -0
- package/dist/commands/machines/dedicated/power/waiting.js +36 -0
- package/dist/commands/open.d.ts +24 -0
- package/dist/commands/open.js +74 -0
- package/dist/commands/projects/archive.d.ts +1 -0
- package/dist/commands/projects/archive.js +23 -0
- package/dist/commands/projects/delete.d.ts +1 -0
- package/dist/commands/projects/delete.js +23 -0
- package/dist/commands/projects/list.d.ts +3 -0
- package/dist/commands/projects/list.js +12 -2
- package/dist/commands/spaces/actions/add.js +4 -3
- package/dist/commands/spaces/actions/available.js +3 -2
- package/dist/commands/spaces/actions/list.js +5 -4
- package/dist/commands/spaces/actions/replace.js +6 -5
- package/dist/commands/spaces/archive.js +3 -2
- package/dist/commands/spaces/auto-executor/preview.js +4 -3
- package/dist/commands/spaces/auto-executor/run.js +4 -3
- package/dist/commands/spaces/auto-executor/runs.js +3 -2
- package/dist/commands/spaces/auto-executor/update.js +4 -3
- package/dist/commands/spaces/bootstrap.js +3 -2
- package/dist/commands/spaces/briefs/delete.js +3 -2
- package/dist/commands/spaces/briefs/get.js +3 -2
- package/dist/commands/spaces/briefs/list.js +3 -2
- package/dist/commands/spaces/briefs/set.js +5 -4
- package/dist/commands/spaces/capacity.js +5 -4
- package/dist/commands/spaces/conversations.js +3 -2
- package/dist/commands/spaces/cycles/create.js +3 -2
- package/dist/commands/spaces/cycles/graph.js +2 -1
- package/dist/commands/spaces/cycles/list.js +3 -2
- package/dist/commands/spaces/cycles/settings.js +4 -3
- package/dist/commands/spaces/cycles/show.js +3 -2
- package/dist/commands/spaces/cycles/update.js +3 -2
- package/dist/commands/spaces/delete.js +4 -3
- package/dist/commands/spaces/expertise-suggestions.js +4 -3
- package/dist/commands/spaces/files/delete.js +3 -2
- package/dist/commands/spaces/files/folders/create.js +3 -2
- package/dist/commands/spaces/files/folders/delete.js +3 -2
- package/dist/commands/spaces/files/folders/list.js +3 -2
- package/dist/commands/spaces/files/folders/update.js +3 -2
- package/dist/commands/spaces/files/list.js +3 -2
- package/dist/commands/spaces/files/move.js +3 -2
- package/dist/commands/spaces/files/rename.js +3 -2
- package/dist/commands/spaces/files/upload.js +6 -5
- package/dist/commands/spaces/github-automations/set.js +3 -2
- package/dist/commands/spaces/github-automations/show.js +3 -2
- package/dist/commands/spaces/goals.js +2 -1
- package/dist/commands/spaces/heartbeats/create.js +4 -3
- package/dist/commands/spaces/heartbeats/delete.js +4 -3
- package/dist/commands/spaces/heartbeats/list.js +4 -3
- package/dist/commands/spaces/heartbeats/status.js +3 -2
- package/dist/commands/spaces/heartbeats/update.js +4 -3
- package/dist/commands/spaces/insights.js +5 -4
- package/dist/commands/spaces/labels/add.js +4 -3
- package/dist/commands/spaces/labels/list.js +2 -1
- package/dist/commands/spaces/labels/remove.js +4 -3
- package/dist/commands/spaces/list.d.ts +3 -0
- package/dist/commands/spaces/list.js +11 -2
- package/dist/commands/spaces/live/cards/create.js +3 -2
- package/dist/commands/spaces/live/cards/list.js +3 -2
- package/dist/commands/spaces/live/cards/reorder.js +7 -2
- package/dist/commands/spaces/live/scene.js +4 -3
- package/dist/commands/spaces/members/add.js +7 -6
- package/dist/commands/spaces/members/list.js +4 -3
- package/dist/commands/spaces/members/remove.js +7 -6
- package/dist/commands/spaces/move.js +3 -2
- package/dist/commands/spaces/pin.js +5 -4
- package/dist/commands/spaces/preferences/show.js +4 -3
- package/dist/commands/spaces/preferences/tabs.js +4 -3
- package/dist/commands/spaces/revisions.js +3 -2
- package/dist/commands/spaces/room/ensure.js +5 -4
- package/dist/commands/spaces/room/messages.js +3 -2
- package/dist/commands/spaces/room/show.js +5 -4
- package/dist/commands/spaces/skills/add.js +4 -3
- package/dist/commands/spaces/skills/list.js +3 -2
- package/dist/commands/spaces/skills/pin.js +4 -3
- package/dist/commands/spaces/skills/remove.js +4 -3
- package/dist/commands/spaces/snapshot.js +3 -2
- package/dist/commands/spaces/states/archive.js +3 -2
- package/dist/commands/spaces/states/create.js +3 -2
- package/dist/commands/spaces/states/list.js +3 -2
- package/dist/commands/spaces/states/reorder.js +2 -1
- package/dist/commands/spaces/states/update.js +3 -2
- package/dist/commands/spaces/summary.js +4 -3
- package/dist/commands/spaces/tasks.d.ts +3 -0
- package/dist/commands/spaces/tasks.js +14 -3
- package/dist/commands/spaces/triggers/delete.js +5 -4
- package/dist/commands/spaces/triggers/set.js +4 -3
- package/dist/commands/spaces/triggers/show.js +4 -3
- package/dist/commands/spaces/unarchive.js +3 -2
- package/dist/commands/spaces/update.js +5 -4
- package/dist/commands/spaces/views/create.js +3 -2
- package/dist/commands/spaces/views/list.js +3 -2
- package/dist/commands/spaces/views/reorder.js +6 -3
- package/dist/commands/spaces/views/subscribe.js +2 -1
- package/dist/commands/spaces/views/subscriptions.js +1 -0
- package/dist/commands/spaces/views/unsubscribe.js +2 -1
- package/dist/commands/spaces/widgets/add.js +4 -3
- package/dist/commands/spaces/widgets/list.js +3 -2
- package/dist/commands/spaces/widgets/remove.js +5 -4
- package/dist/commands/spaces/work-graph.js +2 -1
- package/dist/commands/store/install.d.ts +1 -1
- package/dist/commands/store/install.js +24 -8
- package/dist/commands/store/show.d.ts +25 -0
- package/dist/commands/store/show.js +203 -0
- package/dist/commands/store/stats.d.ts +33 -0
- package/dist/commands/store/stats.js +258 -0
- package/dist/commands/tasks/actions/attach.js +1 -1
- package/dist/commands/tasks/actions/detach.js +4 -3
- package/dist/commands/tasks/activity.js +3 -2
- package/dist/commands/tasks/ancestors.js +2 -1
- package/dist/commands/tasks/approvals/create.js +2 -1
- package/dist/commands/tasks/approvals/delete.js +3 -2
- package/dist/commands/tasks/approvals/list.js +5 -4
- package/dist/commands/tasks/approvals/resolve.js +2 -1
- package/dist/commands/tasks/archive.js +3 -2
- package/dist/commands/tasks/assign.js +4 -3
- package/dist/commands/tasks/attachments/delete.js +3 -2
- package/dist/commands/tasks/attachments/download.d.ts +1 -0
- package/dist/commands/tasks/attachments/download.js +20 -1
- package/dist/commands/tasks/attachments/list.js +2 -1
- package/dist/commands/tasks/attachments/set-role.js +2 -1
- package/dist/commands/tasks/attachments/upload.js +2 -1
- package/dist/commands/tasks/bulk-update.d.ts +1 -0
- package/dist/commands/tasks/bulk-update.js +106 -15
- package/dist/commands/tasks/cancel-cascade.d.ts +1 -0
- package/dist/commands/tasks/cancel-cascade.js +13 -3
- package/dist/commands/tasks/cascade-status.js +2 -1
- package/dist/commands/tasks/chat/send.d.ts +44 -0
- package/dist/commands/tasks/chat/send.js +112 -0
- package/dist/commands/tasks/checkout.js +3 -2
- package/dist/commands/tasks/children.js +2 -1
- package/dist/commands/tasks/comments/add.js +7 -6
- package/dist/commands/tasks/comments/anchor.js +8 -7
- package/dist/commands/tasks/comments/delete.js +3 -2
- package/dist/commands/tasks/comments/list.js +2 -1
- package/dist/commands/tasks/comments/reopen.js +3 -2
- package/dist/commands/tasks/comments/resolve.js +3 -2
- package/dist/commands/tasks/create-tree.d.ts +63 -0
- package/dist/commands/tasks/create-tree.js +197 -4
- package/dist/commands/tasks/delete.js +5 -4
- package/dist/commands/tasks/descendants.js +2 -1
- package/dist/commands/tasks/dri-plan.js +3 -2
- package/dist/commands/tasks/dri-run.js +3 -2
- package/dist/commands/tasks/dri-status.js +2 -1
- package/dist/commands/tasks/duplicate-pipeline.js +2 -1
- package/dist/commands/tasks/execution-summary.js +2 -1
- package/dist/commands/tasks/execution-timeline.js +2 -1
- package/dist/commands/tasks/fork.js +1 -0
- package/dist/commands/tasks/forward.js +4 -3
- package/dist/commands/tasks/handover.js +1 -0
- package/dist/commands/tasks/interrupt.js +3 -2
- package/dist/commands/tasks/labels/attach.js +4 -3
- package/dist/commands/tasks/labels/detach.js +4 -3
- package/dist/commands/tasks/labels/suggest.js +5 -4
- package/dist/commands/tasks/list.d.ts +27 -1
- package/dist/commands/tasks/list.js +101 -3
- package/dist/commands/tasks/move.js +4 -3
- package/dist/commands/tasks/output.js +6 -5
- package/dist/commands/tasks/pause-schedule.js +3 -2
- package/dist/commands/tasks/promote.js +1 -0
- package/dist/commands/tasks/prompt-log.js +2 -1
- package/dist/commands/tasks/release.js +5 -4
- package/dist/commands/tasks/remind.js +2 -1
- package/dist/commands/tasks/replay.js +3 -2
- package/dist/commands/tasks/report.js +1 -0
- package/dist/commands/tasks/resume-schedule.js +3 -2
- package/dist/commands/tasks/retry-schedule.js +3 -2
- package/dist/commands/tasks/retry.js +10 -9
- package/dist/commands/tasks/revisions.js +2 -1
- package/dist/commands/tasks/runs.js +6 -5
- package/dist/commands/tasks/schedule.js +3 -2
- package/dist/commands/tasks/self-schedule.js +6 -5
- package/dist/commands/tasks/skills/pin.js +3 -2
- package/dist/commands/tasks/skills/unpin.js +3 -2
- package/dist/commands/tasks/snooze.js +6 -5
- package/dist/commands/tasks/start-all.js +5 -4
- package/dist/commands/tasks/subscribe.js +1 -0
- package/dist/commands/tasks/tags/add.js +4 -3
- package/dist/commands/tasks/tags/remove.js +4 -3
- package/dist/commands/tasks/timeline.js +3 -2
- package/dist/commands/tasks/today.d.ts +4 -1
- package/dist/commands/tasks/today.js +12 -2
- package/dist/commands/tasks/transcript.js +6 -5
- package/dist/commands/tasks/unschedule.js +3 -2
- package/dist/commands/tasks/unsnooze.js +3 -2
- package/dist/commands/tasks/unsubscribe.js +2 -1
- package/dist/commands/tasks/update.js +5 -4
- package/dist/commands/tasks/wait.js +5 -4
- package/dist/lib/agent-distribution.d.ts +37 -0
- package/dist/lib/agent-distribution.js +63 -0
- package/dist/lib/agent-ref.d.ts +69 -0
- package/dist/lib/agent-ref.js +168 -0
- package/dist/lib/api-fetch.d.ts +2 -0
- package/dist/lib/api-fetch.js +14 -3
- package/dist/lib/command-hygiene.d.ts +13 -0
- package/dist/lib/command-hygiene.js +62 -2
- package/dist/lib/dedicated-power.d.ts +16 -1
- package/dist/lib/dedicated-power.js +153 -2
- package/dist/lib/dry-run-plans.d.ts +50 -0
- package/dist/lib/dry-run-plans.js +85 -0
- package/dist/lib/json-output.d.ts +31 -0
- package/dist/lib/json-output.js +78 -0
- package/dist/lib/list-output.d.ts +75 -0
- package/dist/lib/list-output.js +266 -0
- package/dist/lib/machine-daemon-log.d.ts +36 -0
- package/dist/lib/machine-daemon-log.js +78 -0
- package/dist/lib/node-adapter.js +10 -1
- package/dist/lib/open-target.d.ts +12 -0
- package/dist/lib/open-target.js +108 -0
- package/dist/lib/rate-limit-retry.d.ts +45 -0
- package/dist/lib/rate-limit-retry.js +88 -0
- package/dist/lib/store-listing.d.ts +45 -0
- package/dist/lib/store-listing.js +186 -0
- package/dist/lib/task-batch.d.ts +67 -0
- package/dist/lib/task-batch.js +227 -0
- package/dist/lib/terminal-qr.d.ts +55 -0
- package/dist/lib/terminal-qr.js +119 -0
- package/dist/lib/web-url.d.ts +11 -0
- package/dist/lib/web-url.js +24 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +68 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +47 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +68 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +46 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +6615 -6112
- package/oclif.manifest.json +41499 -32585
- package/package.json +2 -1
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.funnelLines = funnelLines;
|
|
4
|
+
exports.adoptionLines = adoptionLines;
|
|
5
|
+
exports.outcomesLines = outcomesLines;
|
|
6
|
+
const core_1 = require("@oclif/core");
|
|
7
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
8
|
+
const base_command_1 = require("../../base-command");
|
|
9
|
+
const agent_ref_1 = require("../../lib/agent-ref");
|
|
10
|
+
const format_1 = require("../../lib/format");
|
|
11
|
+
const store_listing_1 = require("../../lib/store-listing");
|
|
12
|
+
const SECTIONS = ['funnel', 'adoption', 'outcomes'];
|
|
13
|
+
async function settle(read) {
|
|
14
|
+
try {
|
|
15
|
+
return { ok: true, value: await read() };
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
return { ok: false, error };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function errorMessage(error) {
|
|
22
|
+
return error?.message || 'unavailable';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The publisher's readouts for one of their own Store agents: how buyers move
|
|
26
|
+
* through the install funnel, which releases their copies are on, and how each
|
|
27
|
+
* release turns out in use.
|
|
28
|
+
*
|
|
29
|
+
* Every figure is k-anonymous and publisher-only (the author, or an owner/admin
|
|
30
|
+
* of the organisation the listing is published as) — the same readouts the web
|
|
31
|
+
* shows, under the same terms (I2): the seller side's own copies are excluded, a readout covering fewer buyers than its floor returns NO figures,
|
|
32
|
+
* and small rows are withheld. This command prints a withheld readout as
|
|
33
|
+
* withheld, with the floor it missed. It never prints 0 for one, because zero
|
|
34
|
+
* is a claim the server did not make.
|
|
35
|
+
*
|
|
36
|
+
* There is no `--since`. Each window is fixed by the server — a caller-chosen
|
|
37
|
+
* length would let `days=N` minus `days=N-1` isolate a single buyer — so the
|
|
38
|
+
* window a readout covers is printed with it instead.
|
|
39
|
+
*/
|
|
40
|
+
class StoreStats extends base_command_1.BaseCommand {
|
|
41
|
+
static description = 'Publisher analytics for your store agent: install funnel, release adoption and release outcomes (k-anonymous; small cohorts withheld)';
|
|
42
|
+
static examples = [
|
|
43
|
+
'<%= config.bin %> store stats agent_abc123',
|
|
44
|
+
'<%= config.bin %> store stats agent_abc123 --only funnel',
|
|
45
|
+
'<%= config.bin %> store stats agent_abc123 --json',
|
|
46
|
+
];
|
|
47
|
+
static args = {
|
|
48
|
+
agent: core_1.Args.string({
|
|
49
|
+
description: 'Your published store agent: its id or a link to it',
|
|
50
|
+
required: true,
|
|
51
|
+
ignoreStdin: true,
|
|
52
|
+
}),
|
|
53
|
+
};
|
|
54
|
+
static flags = {
|
|
55
|
+
json: core_1.Flags.boolean({ description: 'Output the three readouts as JSON' }),
|
|
56
|
+
only: core_1.Flags.string({
|
|
57
|
+
description: 'Read one readout instead of all three',
|
|
58
|
+
options: [...SECTIONS],
|
|
59
|
+
}),
|
|
60
|
+
};
|
|
61
|
+
async run() {
|
|
62
|
+
this.requireAuth();
|
|
63
|
+
const { args, flags } = await this.parse(StoreStats);
|
|
64
|
+
let agentId;
|
|
65
|
+
try {
|
|
66
|
+
({ agentId } = await (0, agent_ref_1.resolveAgentRef)(args.agent, { baseURL: this.cliConfig?.baseURL }));
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
if (err instanceof agent_ref_1.AgentRefError) {
|
|
70
|
+
this.failWithCliError({ message: err.message, code: err.code, exit: 1, retryable: false });
|
|
71
|
+
}
|
|
72
|
+
// Resolving a share code reads the server; its failure is an API failure.
|
|
73
|
+
this.handleApiError(err);
|
|
74
|
+
}
|
|
75
|
+
const wanted = (section) => !flags.only || flags.only === section;
|
|
76
|
+
const skipped = { ok: false, error: null };
|
|
77
|
+
const [funnel, adoption, outcomes] = await Promise.all([
|
|
78
|
+
wanted('funnel')
|
|
79
|
+
? settle(() => data_provider_1.dataService.getStoreAgentInstallFunnelSummary({ agentId }))
|
|
80
|
+
: skipped,
|
|
81
|
+
wanted('adoption')
|
|
82
|
+
? settle(() => data_provider_1.dataService.getStoreAgentReleaseAdoptionSummary(agentId))
|
|
83
|
+
: skipped,
|
|
84
|
+
wanted('outcomes')
|
|
85
|
+
? settle(() => data_provider_1.dataService.getStoreAgentReleaseOutcomes({ agentId }))
|
|
86
|
+
: skipped,
|
|
87
|
+
]);
|
|
88
|
+
// Every requested readout failed: that is one answer (not yours, not
|
|
89
|
+
// found, signed out), and the shared error handler words it.
|
|
90
|
+
const attempted = [funnel, adoption, outcomes].filter((r) => r.ok || r.error !== null);
|
|
91
|
+
if (attempted.length > 0 && attempted.every((r) => !r.ok)) {
|
|
92
|
+
this.handleApiError(attempted[0].error, {
|
|
93
|
+
subject: `store agent ${agentId}`,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
if (flags.json) {
|
|
97
|
+
const shape = (r) => r.ok ? r.value : r.error === null ? undefined : { error: errorMessage(r.error) };
|
|
98
|
+
this.log(JSON.stringify({
|
|
99
|
+
agentId,
|
|
100
|
+
funnel: shape(funnel),
|
|
101
|
+
adoption: shape(adoption),
|
|
102
|
+
outcomes: shape(outcomes),
|
|
103
|
+
}, null, 2));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const blocks = [];
|
|
107
|
+
if (wanted('funnel')) {
|
|
108
|
+
blocks.push(funnel.ok
|
|
109
|
+
? funnelLines(funnel.value.summary)
|
|
110
|
+
: ['Install funnel', ` unavailable (${errorMessage(funnel.error)})`]);
|
|
111
|
+
}
|
|
112
|
+
if (wanted('adoption')) {
|
|
113
|
+
blocks.push(adoption.ok
|
|
114
|
+
? adoptionLines(adoption.value.summary)
|
|
115
|
+
: ['Release adoption', ` unavailable (${errorMessage(adoption.error)})`]);
|
|
116
|
+
}
|
|
117
|
+
if (wanted('outcomes')) {
|
|
118
|
+
blocks.push(outcomes.ok
|
|
119
|
+
? outcomesLines(outcomes.value.outcomes)
|
|
120
|
+
: ['Release outcomes', ` unavailable (${errorMessage(outcomes.error)})`]);
|
|
121
|
+
}
|
|
122
|
+
blocks.forEach((lines, index) => {
|
|
123
|
+
if (index > 0)
|
|
124
|
+
this.log('');
|
|
125
|
+
for (const line of lines)
|
|
126
|
+
this.log(line);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
exports.default = StoreStats;
|
|
131
|
+
function table(rows, columns) {
|
|
132
|
+
const out = [];
|
|
133
|
+
(0, format_1.renderTable)(rows, columns, (line) => out.push(` ${line}`));
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
function funnelLines(summary) {
|
|
137
|
+
const lines = [`Install funnel — ${(0, store_listing_1.funnelWindowLine)(summary)}`];
|
|
138
|
+
const testEvents = summary.excluded?.publisherTestEvents;
|
|
139
|
+
if (summary.suppressed) {
|
|
140
|
+
lines.push(` ${(0, store_listing_1.withheldLine)(summary.minimumCohort, 'buyers')}`);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
lines.push(...table(summary.funnel.map((step) => ({
|
|
144
|
+
step: step.label,
|
|
145
|
+
sessions: String(step.sessions),
|
|
146
|
+
events: String(step.events),
|
|
147
|
+
fromPlan: (0, store_listing_1.formatRate)(step.conversionFromPlan),
|
|
148
|
+
fromPrevious: (0, store_listing_1.formatRate)(step.conversionFromPrevious),
|
|
149
|
+
})), [
|
|
150
|
+
{ key: 'step', header: 'STEP', maxWidth: 32 },
|
|
151
|
+
{ key: 'sessions', header: 'SESSIONS' },
|
|
152
|
+
{ key: 'events', header: 'EVENTS' },
|
|
153
|
+
{ key: 'fromPlan', header: 'FROM PLAN' },
|
|
154
|
+
{ key: 'fromPrevious', header: 'FROM PREV' },
|
|
155
|
+
]));
|
|
156
|
+
const h = summary.health;
|
|
157
|
+
lines.push(...(0, store_listing_1.labelledLines)([
|
|
158
|
+
['Buyer sessions', String(summary.sessionCount)],
|
|
159
|
+
[
|
|
160
|
+
'Installs',
|
|
161
|
+
`${h.installCompletions} of ${h.installStarts} started (${(0, store_listing_1.formatRate)(h.installCompletionRate)})`,
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
'Activations',
|
|
165
|
+
`${h.activationCompletions} (${(0, store_listing_1.formatRate)(h.activationCompletionRate)} of installs)`,
|
|
166
|
+
],
|
|
167
|
+
['Failed sessions', String(h.failedSessions)],
|
|
168
|
+
]));
|
|
169
|
+
if (summary.truncated) {
|
|
170
|
+
lines.push(' More events than one readout reads; figures cover the first part of the window.');
|
|
171
|
+
}
|
|
172
|
+
const cells = (0, store_listing_1.suppressedCellsLine)(summary.suppressedCells, summary.minimumCohort, 'buyers');
|
|
173
|
+
if (cells)
|
|
174
|
+
lines.push(` ${cells}`);
|
|
175
|
+
}
|
|
176
|
+
if (typeof testEvents === 'number' && testEvents > 0) {
|
|
177
|
+
lines.push(` Not counted: ${testEvents} event(s) from your own test installs.`);
|
|
178
|
+
}
|
|
179
|
+
return lines;
|
|
180
|
+
}
|
|
181
|
+
function adoptionLines(summary) {
|
|
182
|
+
const lines = [`Release adoption — ${(0, store_listing_1.adoptionWindowLine)(summary)}`];
|
|
183
|
+
if (summary.suppressed) {
|
|
184
|
+
lines.push(` ${(0, store_listing_1.withheldLine)(summary.minimumCohort, 'buyers')}`);
|
|
185
|
+
return lines;
|
|
186
|
+
}
|
|
187
|
+
if (summary.versions.length === 0) {
|
|
188
|
+
lines.push(' No version row reaches the floor.');
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
lines.push(...table(summary.versions.map((v) => ({
|
|
192
|
+
version: v.releaseId
|
|
193
|
+
? `${v.versionLabel ? `v${v.versionLabel}` : '(no label)'}${v.latest ? ' (latest)' : ''}`
|
|
194
|
+
: 'no recorded release',
|
|
195
|
+
release: v.releaseNumber === null ? '-' : String(v.releaseNumber),
|
|
196
|
+
installs: String(v.installs),
|
|
197
|
+
})), [
|
|
198
|
+
{ key: 'version', header: 'VERSION' },
|
|
199
|
+
{ key: 'release', header: 'RELEASE #' },
|
|
200
|
+
{ key: 'installs', header: 'COPIES' },
|
|
201
|
+
]));
|
|
202
|
+
}
|
|
203
|
+
if (summary.conflictFields.length > 0) {
|
|
204
|
+
lines.push(' Fields where buyers’ edits conflict with an update:');
|
|
205
|
+
lines.push(...table(summary.conflictFields.map((f) => ({ field: f.field, installs: String(f.installs) })), [
|
|
206
|
+
{ key: 'field', header: 'FIELD' },
|
|
207
|
+
{ key: 'installs', header: 'COPIES' },
|
|
208
|
+
]));
|
|
209
|
+
}
|
|
210
|
+
const cells = (0, store_listing_1.suppressedCellsLine)(summary.suppressedCells, summary.minimumCohort, 'buyers');
|
|
211
|
+
if (cells)
|
|
212
|
+
lines.push(` ${cells}`);
|
|
213
|
+
return lines;
|
|
214
|
+
}
|
|
215
|
+
function outcomesLines(outcomes) {
|
|
216
|
+
const lines = [`Release outcomes — ${(0, store_listing_1.outcomesWindowLine)(outcomes)}`];
|
|
217
|
+
if (outcomes.suppressed) {
|
|
218
|
+
lines.push(` ${(0, store_listing_1.withheldLine)(outcomes.minimumCohort, 'buyer cohorts')}`);
|
|
219
|
+
return lines;
|
|
220
|
+
}
|
|
221
|
+
lines.push(` ${outcomes.cohortCount} buyer cohort(s).`);
|
|
222
|
+
if (outcomes.releases.length === 0) {
|
|
223
|
+
lines.push(' No release row reaches the floor.');
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
lines.push(...table(outcomes.releases.map((r) => ({
|
|
227
|
+
version: r.versionLabel ? `v${r.versionLabel}` : r.releaseId,
|
|
228
|
+
runs: String(r.runs.total),
|
|
229
|
+
success: (0, store_listing_1.formatRate)(r.runs.successRate),
|
|
230
|
+
closes: String(r.taskCloses.closed),
|
|
231
|
+
clean: (0, store_listing_1.formatRate)(r.taskCloses.cleanRate),
|
|
232
|
+
reviews: `${r.buyerTestimony.reviewsAccepted} accepted / ${r.buyerTestimony.reviewsChangesRequested} changes`,
|
|
233
|
+
})), [
|
|
234
|
+
{ key: 'version', header: 'VERSION' },
|
|
235
|
+
{ key: 'runs', header: 'RUNS' },
|
|
236
|
+
{ key: 'success', header: 'SUCCEEDED' },
|
|
237
|
+
{ key: 'closes', header: 'TASKS CLOSED' },
|
|
238
|
+
{ key: 'clean', header: 'CLEAN' },
|
|
239
|
+
{ key: 'reviews', header: 'BUYER REVIEWS' },
|
|
240
|
+
]));
|
|
241
|
+
}
|
|
242
|
+
// What each column rests on: runs and closes are recorded by the platform,
|
|
243
|
+
// reviews are what buyers said.
|
|
244
|
+
lines.push(' Runs and task closes are platform-recorded; reviews are buyer testimony.');
|
|
245
|
+
const cells = (0, store_listing_1.suppressedCellsLine)(outcomes.suppressedCells, outcomes.minimumCohort, 'buyer cohorts');
|
|
246
|
+
if (cells)
|
|
247
|
+
lines.push(` ${cells}`);
|
|
248
|
+
const ex = outcomes.excluded;
|
|
249
|
+
lines.push(...(0, store_listing_1.labelledLines)([
|
|
250
|
+
['Left out: modified copies', (0, store_listing_1.exclusionValue)(ex.modifiedCopyRuns)],
|
|
251
|
+
['Left out: self-assessed closes', (0, store_listing_1.exclusionValue)(ex.selfAssessedCloses)],
|
|
252
|
+
[
|
|
253
|
+
'Left out: agent reviews/assessments',
|
|
254
|
+
`${(0, store_listing_1.exclusionValue)(ex.agentReviews)} / ${(0, store_listing_1.exclusionValue)(ex.agentAssessments)}`,
|
|
255
|
+
],
|
|
256
|
+
]));
|
|
257
|
+
return lines;
|
|
258
|
+
}
|
|
@@ -129,7 +129,7 @@ class TasksActionsAttach extends base_command_1.BaseCommand {
|
|
|
129
129
|
this.exit(1);
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
|
-
const singleTaskId = taskId;
|
|
132
|
+
const singleTaskId = await this.resolveEntityRef('task', taskId);
|
|
133
133
|
let current;
|
|
134
134
|
try {
|
|
135
135
|
current = await data_provider_1.dataService.getTask(singleTaskId, { enrich: false });
|
|
@@ -89,9 +89,10 @@ class TasksActionsDetach extends base_command_1.BaseCommand {
|
|
|
89
89
|
this.exit(1);
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
|
+
const taskRef = await this.resolveEntityRef('task', taskId);
|
|
92
93
|
let current;
|
|
93
94
|
try {
|
|
94
|
-
current = await data_provider_1.dataService.getTask(
|
|
95
|
+
current = await data_provider_1.dataService.getTask(taskRef, { enrich: false });
|
|
95
96
|
}
|
|
96
97
|
catch (err) {
|
|
97
98
|
this.handleApiError(err);
|
|
@@ -109,7 +110,7 @@ class TasksActionsDetach extends base_command_1.BaseCommand {
|
|
|
109
110
|
let updated;
|
|
110
111
|
try {
|
|
111
112
|
updated = await data_provider_1.dataService.updateTask({
|
|
112
|
-
taskId:
|
|
113
|
+
taskId: taskRef,
|
|
113
114
|
data: { attachedActionRefs: remaining },
|
|
114
115
|
});
|
|
115
116
|
}
|
|
@@ -120,7 +121,7 @@ class TasksActionsDetach extends base_command_1.BaseCommand {
|
|
|
120
121
|
this.log(JSON.stringify(updated, null, 2));
|
|
121
122
|
return;
|
|
122
123
|
}
|
|
123
|
-
this.log(`Detached ${existing.length - remaining.length} action(s) from task ${
|
|
124
|
+
this.log(`Detached ${existing.length - remaining.length} action(s) from task ${taskRef}.`);
|
|
124
125
|
this.log(remaining.length
|
|
125
126
|
? `Still attached: ${remaining.map(refKey).join(', ')}`
|
|
126
127
|
: 'No actions attached.');
|
|
@@ -88,9 +88,10 @@ class TasksActivity extends base_command_1.BaseCommand {
|
|
|
88
88
|
async run() {
|
|
89
89
|
this.requireAuth();
|
|
90
90
|
const { args, flags } = await this.parse(TasksActivity);
|
|
91
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
91
92
|
let response;
|
|
92
93
|
try {
|
|
93
|
-
response = await data_provider_1.dataService.listTaskActivityEvents(
|
|
94
|
+
response = await data_provider_1.dataService.listTaskActivityEvents(taskRef, { limit: flags.limit });
|
|
94
95
|
}
|
|
95
96
|
catch (err) {
|
|
96
97
|
this.handleApiError(err);
|
|
@@ -105,7 +106,7 @@ class TasksActivity extends base_command_1.BaseCommand {
|
|
|
105
106
|
// "No activity." was a claim about the TASK. It is only ever a claim about
|
|
106
107
|
// this VIEW: a Task predating the canonical model has its history in the
|
|
107
108
|
// legacy activity log, which this endpoint does not read.
|
|
108
|
-
this.log(await (0, task_legacy_1.emptyCanonicalView)(
|
|
109
|
+
this.log(await (0, task_legacy_1.emptyCanonicalView)(taskRef, 'Activity'));
|
|
109
110
|
return;
|
|
110
111
|
}
|
|
111
112
|
(0, format_1.renderTable)(items.map(activityRow), [
|
|
@@ -20,9 +20,10 @@ class TasksAncestors extends base_command_1.BaseCommand {
|
|
|
20
20
|
async run() {
|
|
21
21
|
this.requireAuth();
|
|
22
22
|
const { args, flags } = await this.parse(TasksAncestors);
|
|
23
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
23
24
|
let response;
|
|
24
25
|
try {
|
|
25
|
-
response = await data_provider_1.dataService.getTaskAncestors(
|
|
26
|
+
response = await data_provider_1.dataService.getTaskAncestors(taskRef);
|
|
26
27
|
}
|
|
27
28
|
catch (err) {
|
|
28
29
|
this.handleApiError(err);
|
|
@@ -32,6 +32,7 @@ class TasksApprovalsCreate extends base_command_1.BaseCommand {
|
|
|
32
32
|
async run() {
|
|
33
33
|
this.requireAuth();
|
|
34
34
|
const { args, flags } = await this.parse(TasksApprovalsCreate);
|
|
35
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
35
36
|
const data = { type: flags.type };
|
|
36
37
|
if (flags['approver-agent'])
|
|
37
38
|
data.approverAgentId = flags['approver-agent'];
|
|
@@ -40,7 +41,7 @@ class TasksApprovalsCreate extends base_command_1.BaseCommand {
|
|
|
40
41
|
let result;
|
|
41
42
|
try {
|
|
42
43
|
result = await data_provider_1.dataService.createTaskApproval({
|
|
43
|
-
taskId:
|
|
44
|
+
taskId: taskRef,
|
|
44
45
|
data: data,
|
|
45
46
|
});
|
|
46
47
|
}
|
|
@@ -20,9 +20,10 @@ class TasksApprovalsDelete extends base_command_1.BaseCommand {
|
|
|
20
20
|
async run() {
|
|
21
21
|
this.requireAuth();
|
|
22
22
|
const { args, flags } = await this.parse(TasksApprovalsDelete);
|
|
23
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
23
24
|
let confirmed;
|
|
24
25
|
try {
|
|
25
|
-
confirmed = await (0, prompt_1.confirmDestructive)(`Delete approval ${args.approvalId} from task ${
|
|
26
|
+
confirmed = await (0, prompt_1.confirmDestructive)(`Delete approval ${args.approvalId} from task ${taskRef}? This cannot be undone.`, flags.yes);
|
|
26
27
|
}
|
|
27
28
|
catch (err) {
|
|
28
29
|
const e = err;
|
|
@@ -33,7 +34,7 @@ class TasksApprovalsDelete extends base_command_1.BaseCommand {
|
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
36
|
try {
|
|
36
|
-
await data_provider_1.dataService.deleteTaskApproval({ taskId:
|
|
37
|
+
await data_provider_1.dataService.deleteTaskApproval({ taskId: taskRef, approvalId: args.approvalId });
|
|
37
38
|
}
|
|
38
39
|
catch (err) {
|
|
39
40
|
this.handleApiError(err);
|
|
@@ -165,9 +165,10 @@ class TasksApprovalsList extends base_command_1.BaseCommand {
|
|
|
165
165
|
async run() {
|
|
166
166
|
this.requireAuth();
|
|
167
167
|
const { args, flags } = await this.parse(TasksApprovalsList);
|
|
168
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
168
169
|
let response;
|
|
169
170
|
try {
|
|
170
|
-
response = await data_provider_1.dataService.listTaskApprovals(
|
|
171
|
+
response = await data_provider_1.dataService.listTaskApprovals(taskRef);
|
|
171
172
|
}
|
|
172
173
|
catch (err) {
|
|
173
174
|
this.handleApiError(err);
|
|
@@ -183,7 +184,7 @@ class TasksApprovalsList extends base_command_1.BaseCommand {
|
|
|
183
184
|
let blockedRun = null;
|
|
184
185
|
let runsRead = false;
|
|
185
186
|
try {
|
|
186
|
-
const runs = (await data_provider_1.dataService.getTaskRuns(
|
|
187
|
+
const runs = (await data_provider_1.dataService.getTaskRuns(taskRef));
|
|
187
188
|
blockedRun = permissionBlockedRun(runs?.data ?? []);
|
|
188
189
|
runsRead = true;
|
|
189
190
|
}
|
|
@@ -202,13 +203,13 @@ class TasksApprovalsList extends base_command_1.BaseCommand {
|
|
|
202
203
|
const out = runsRead
|
|
203
204
|
? {
|
|
204
205
|
...payload,
|
|
205
|
-
blockedRun: blockedRun ? blockedRunSummary(blockedRun, this.config.bin,
|
|
206
|
+
blockedRun: blockedRun ? blockedRunSummary(blockedRun, this.config.bin, taskRef) : null,
|
|
206
207
|
}
|
|
207
208
|
: payload;
|
|
208
209
|
this.log(JSON.stringify(out, null, 2));
|
|
209
210
|
return;
|
|
210
211
|
}
|
|
211
|
-
const blockLines = blockedRun ? permissionBlockLines(blockedRun, this.config.bin,
|
|
212
|
+
const blockLines = blockedRun ? permissionBlockLines(blockedRun, this.config.bin, taskRef) : [];
|
|
212
213
|
if (items.length === 0) {
|
|
213
214
|
this.log('No approval requests.');
|
|
214
215
|
if (blockLines.length > 0) {
|
|
@@ -26,13 +26,14 @@ class TasksApprovalsResolve extends base_command_1.BaseCommand {
|
|
|
26
26
|
async run() {
|
|
27
27
|
this.requireAuth();
|
|
28
28
|
const { args, flags } = await this.parse(TasksApprovalsResolve);
|
|
29
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
29
30
|
const data = { status: flags.status };
|
|
30
31
|
if (flags.reason)
|
|
31
32
|
data.reason = flags.reason;
|
|
32
33
|
let result;
|
|
33
34
|
try {
|
|
34
35
|
result = await data_provider_1.dataService.resolveTaskApproval({
|
|
35
|
-
taskId:
|
|
36
|
+
taskId: taskRef,
|
|
36
37
|
approvalId: args.approvalId,
|
|
37
38
|
data: data,
|
|
38
39
|
});
|
|
@@ -21,11 +21,12 @@ class TasksArchive extends base_command_1.BaseCommand {
|
|
|
21
21
|
async run() {
|
|
22
22
|
this.requireAuth();
|
|
23
23
|
const { args, flags } = await this.parse(TasksArchive);
|
|
24
|
+
const taskId = await this.resolveEntityRef('task', args.id);
|
|
24
25
|
let result;
|
|
25
26
|
try {
|
|
26
27
|
result = flags.unarchive
|
|
27
|
-
? await data_provider_1.dataService.unarchiveTask(
|
|
28
|
-
: await data_provider_1.dataService.archiveTask(
|
|
28
|
+
? await data_provider_1.dataService.unarchiveTask(taskId)
|
|
29
|
+
: await data_provider_1.dataService.archiveTask(taskId);
|
|
29
30
|
}
|
|
30
31
|
catch (err) {
|
|
31
32
|
this.handleApiError(err);
|
|
@@ -109,6 +109,7 @@ class TasksAssign extends base_command_1.BaseCommand {
|
|
|
109
109
|
details: { suggestion: failure.suggestion, context: failure.details },
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
|
+
const taskRef = await this.resolveEntityRef('task', taskIdentity.id);
|
|
112
113
|
const personQueries = [...(args.person ? [args.person] : []), ...(flags.person ?? [])];
|
|
113
114
|
const agentQueries = flags.agent ?? [];
|
|
114
115
|
if (!flags.list && !flags.suggest && personQueries.length === 0 && agentQueries.length === 0) {
|
|
@@ -129,7 +130,7 @@ class TasksAssign extends base_command_1.BaseCommand {
|
|
|
129
130
|
}
|
|
130
131
|
let task;
|
|
131
132
|
try {
|
|
132
|
-
task = await data_provider_1.dataService.getTask(
|
|
133
|
+
task = await data_provider_1.dataService.getTask(taskRef, { enrich: false });
|
|
133
134
|
}
|
|
134
135
|
catch (err) {
|
|
135
136
|
this.handleApiError(err);
|
|
@@ -185,7 +186,7 @@ class TasksAssign extends base_command_1.BaseCommand {
|
|
|
185
186
|
let updated;
|
|
186
187
|
try {
|
|
187
188
|
updated = await data_provider_1.dataService.updateTask({
|
|
188
|
-
taskId:
|
|
189
|
+
taskId: taskRef,
|
|
189
190
|
data: payload,
|
|
190
191
|
});
|
|
191
192
|
}
|
|
@@ -204,7 +205,7 @@ class TasksAssign extends base_command_1.BaseCommand {
|
|
|
204
205
|
return;
|
|
205
206
|
}
|
|
206
207
|
const t = updated;
|
|
207
|
-
const ref = t.identifier ?? t.id ??
|
|
208
|
+
const ref = t.identifier ?? t.id ?? taskRef;
|
|
208
209
|
let verb = 'Assigned';
|
|
209
210
|
if (flags.remove)
|
|
210
211
|
verb = 'Unassigned';
|
|
@@ -20,9 +20,10 @@ class TasksAttachmentsDelete extends base_command_1.BaseCommand {
|
|
|
20
20
|
async run() {
|
|
21
21
|
this.requireAuth();
|
|
22
22
|
const { args, flags } = await this.parse(TasksAttachmentsDelete);
|
|
23
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
23
24
|
let confirmed;
|
|
24
25
|
try {
|
|
25
|
-
confirmed = await (0, prompt_1.confirmDestructive)(`Delete attachment ${args.attachmentId} from task ${
|
|
26
|
+
confirmed = await (0, prompt_1.confirmDestructive)(`Delete attachment ${args.attachmentId} from task ${taskRef}? This cannot be undone.`, flags.yes);
|
|
26
27
|
}
|
|
27
28
|
catch (err) {
|
|
28
29
|
const e = err;
|
|
@@ -33,7 +34,7 @@ class TasksAttachmentsDelete extends base_command_1.BaseCommand {
|
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
36
|
try {
|
|
36
|
-
await data_provider_1.dataService.deleteTaskAttachment({ taskId:
|
|
37
|
+
await data_provider_1.dataService.deleteTaskAttachment({ taskId: taskRef, attachmentId: args.attachmentId });
|
|
37
38
|
}
|
|
38
39
|
catch (err) {
|
|
39
40
|
this.handleApiError(err);
|
|
@@ -8,6 +8,7 @@ export default class TasksAttachmentsDownload extends BaseCommand {
|
|
|
8
8
|
};
|
|
9
9
|
static flags: {
|
|
10
10
|
out: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
12
|
};
|
|
12
13
|
run(): Promise<void>;
|
|
13
14
|
}
|
|
@@ -52,13 +52,22 @@ class TasksAttachmentsDownload extends base_command_1.BaseCommand {
|
|
|
52
52
|
description: 'Output path (use - for stdout)',
|
|
53
53
|
required: true,
|
|
54
54
|
}),
|
|
55
|
+
json: core_1.Flags.boolean({
|
|
56
|
+
description: 'Print {path, bytes} as JSON after writing a file (not valid with --out -)',
|
|
57
|
+
}),
|
|
55
58
|
};
|
|
56
59
|
async run() {
|
|
57
60
|
this.requireAuth();
|
|
58
61
|
const { args, flags } = await this.parse(TasksAttachmentsDownload);
|
|
62
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
63
|
+
if (flags.json && flags.out === '-') {
|
|
64
|
+
this.error('--json cannot be combined with --out - (stdout carries the file bytes).', {
|
|
65
|
+
exit: 2,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
59
68
|
let buffer;
|
|
60
69
|
try {
|
|
61
|
-
buffer = await data_provider_1.dataService.downloadTaskAttachment(
|
|
70
|
+
buffer = await data_provider_1.dataService.downloadTaskAttachment(taskRef, args.attachmentId);
|
|
62
71
|
}
|
|
63
72
|
catch (err) {
|
|
64
73
|
this.handleApiError(err);
|
|
@@ -71,6 +80,16 @@ class TasksAttachmentsDownload extends base_command_1.BaseCommand {
|
|
|
71
80
|
}
|
|
72
81
|
else {
|
|
73
82
|
fs.writeFileSync(flags.out, bytes);
|
|
83
|
+
if (flags.json) {
|
|
84
|
+
this.log(JSON.stringify({
|
|
85
|
+
object: 'task_attachment_download',
|
|
86
|
+
taskId: taskRef,
|
|
87
|
+
attachmentId: args.attachmentId,
|
|
88
|
+
path: flags.out,
|
|
89
|
+
bytes: bytes.length,
|
|
90
|
+
}));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
74
93
|
this.log(`Wrote ${bytes.length} bytes to ${flags.out}`);
|
|
75
94
|
}
|
|
76
95
|
}
|
|
@@ -51,9 +51,10 @@ class TasksAttachmentsList extends base_command_1.BaseCommand {
|
|
|
51
51
|
async run() {
|
|
52
52
|
this.requireAuth();
|
|
53
53
|
const { args, flags } = await this.parse(TasksAttachmentsList);
|
|
54
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
54
55
|
let response;
|
|
55
56
|
try {
|
|
56
|
-
response = await data_provider_1.dataService.listTaskAttachments(
|
|
57
|
+
response = await data_provider_1.dataService.listTaskAttachments(taskRef);
|
|
57
58
|
}
|
|
58
59
|
catch (err) {
|
|
59
60
|
this.handleApiError(err);
|
|
@@ -35,10 +35,11 @@ class TasksAttachmentsSetRole extends base_command_1.BaseCommand {
|
|
|
35
35
|
async run() {
|
|
36
36
|
this.requireAuth();
|
|
37
37
|
const { args, flags } = await this.parse(TasksAttachmentsSetRole);
|
|
38
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
38
39
|
let attachment;
|
|
39
40
|
try {
|
|
40
41
|
attachment = await data_provider_1.dataService.setTaskAttachmentRole({
|
|
41
|
-
taskId:
|
|
42
|
+
taskId: taskRef,
|
|
42
43
|
attachmentId: args.attachmentId,
|
|
43
44
|
role: flags.role,
|
|
44
45
|
});
|
|
@@ -24,13 +24,14 @@ class TasksAttachmentsUpload extends base_command_1.BaseCommand {
|
|
|
24
24
|
async run() {
|
|
25
25
|
this.requireAuth();
|
|
26
26
|
const { args, flags } = await this.parse(TasksAttachmentsUpload);
|
|
27
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
27
28
|
// The pipeline — buffered vs direct, session vs generic — lives in
|
|
28
29
|
// task-asset-upload.ts so `--attach` on updates/result/complete/comments
|
|
29
30
|
// makes the same routing decisions byte for byte (OSK-9863).
|
|
30
31
|
let asset;
|
|
31
32
|
try {
|
|
32
33
|
asset = await (0, task_asset_upload_1.uploadTaskAssetFile)({
|
|
33
|
-
taskId:
|
|
34
|
+
taskId: taskRef,
|
|
34
35
|
filePath: flags.file,
|
|
35
36
|
role: flags.role,
|
|
36
37
|
});
|
|
@@ -5,6 +5,7 @@ export default class TasksBulkUpdate extends BaseCommand {
|
|
|
5
5
|
static flags: {
|
|
6
6
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
7
7
|
'from-json': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
+
'dry-run': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
9
|
'continue-on-error': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
10
|
};
|
|
10
11
|
run(): Promise<void>;
|