@bussolabs/closeyourit-cli 0.23.1 → 0.24.1

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.
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class CoverageShow extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ branch: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<unknown>;
10
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_1 = require("../../base");
4
+ const core_1 = require("@oclif/core");
5
+ // CYSK-26 — l'estratto di copertura pubblicato dalla CI, riletto senza rigirare la suite: è il dato
6
+ // su cui lo scanner del codice non usato decide se la misura è credibile prima di fidarsene.
7
+ class CoverageShow extends base_1.BaseCommand {
8
+ static description = 'Show the coverage extract the CI published for a project (last snapshot per branch, never the history)';
9
+ static examples = [
10
+ '<%= config.bin %> coverage show --project closeyourit-rails',
11
+ '<%= config.bin %> coverage show -p CYRA --branch main',
12
+ '<%= config.bin %> coverage show -p CYRA --json',
13
+ ];
14
+ static flags = {
15
+ ...base_1.projectFlag,
16
+ branch: core_1.Flags.string({ description: 'Only the extract of this branch' }),
17
+ };
18
+ async run() {
19
+ const { flags } = await this.parse(CoverageShow);
20
+ const projectId = await this.resolveProjectId(flags.project);
21
+ const query = flags.branch ? `?branch=${encodeURIComponent(flags.branch)}` : '';
22
+ const res = await this.api.get(`/cli/v1/projects/${projectId}/coverage${query}`);
23
+ if (!this.jsonEnabled()) {
24
+ const reports = res.data ?? [];
25
+ if (reports.length === 0) {
26
+ this.log('No coverage extract published yet: the CI pushes it from the default branch.');
27
+ }
28
+ else {
29
+ for (const report of reports) {
30
+ this.log(`${report.branch ?? '?'} line ${report.line_covered_percent ?? '-'}% branch ${report.branch_covered_percent ?? '-'}% ` +
31
+ `files ${report.files_count ?? '-'} never_loaded ${report.never_loaded_count ?? '-'} ` +
32
+ `sha ${report.sha ?? '-'} captured ${report.captured_at ?? '-'}`);
33
+ }
34
+ }
35
+ }
36
+ return res;
37
+ }
38
+ }
39
+ exports.default = CoverageShow;
@@ -0,0 +1,21 @@
1
+ import { BaseCommand } from '../../base';
2
+ /**
3
+ * Lo stato del ciclo di chiarimenti di un ticket, chiesto al sistema (CYRA-628).
4
+ *
5
+ * È il canale che sostituisce il ri-parsing della discussione: la skill di triage e l'automator
6
+ * leggevano un marcatore HTML nel testo dei commenti e provavano a indovinare se una domanda fosse
7
+ * pendente e a che giro. Una riga scritta dal sistema stesso bastava a farlo ripartire.
8
+ *
9
+ * Sola lettura: le domande le scrive il server quando il triage le consegna, non un chiamante esterno.
10
+ */
11
+ export default class TicketsClarifications extends BaseCommand {
12
+ static args: {
13
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
14
+ };
15
+ static description: string;
16
+ static examples: string[];
17
+ static flags: {
18
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
19
+ };
20
+ run(): Promise<unknown>;
21
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_1 = require("../../base");
5
+ const ticket_clarifications_1 = require("../../lib/ticket-clarifications");
6
+ /**
7
+ * Lo stato del ciclo di chiarimenti di un ticket, chiesto al sistema (CYRA-628).
8
+ *
9
+ * È il canale che sostituisce il ri-parsing della discussione: la skill di triage e l'automator
10
+ * leggevano un marcatore HTML nel testo dei commenti e provavano a indovinare se una domanda fosse
11
+ * pendente e a che giro. Una riga scritta dal sistema stesso bastava a farlo ripartire.
12
+ *
13
+ * Sola lettura: le domande le scrive il server quando il triage le consegna, non un chiamante esterno.
14
+ */
15
+ class TicketsClarifications extends base_1.BaseCommand {
16
+ static args = {
17
+ id: core_1.Args.string({ description: 'Ticket id or code (e.g. DRFL-3)', required: true }),
18
+ };
19
+ static description = 'Show the clarification cycle state of a ticket (rounds, reply, escalation)';
20
+ static examples = [
21
+ '<%= config.bin %> tickets clarifications <ticket-id> --project acme-api',
22
+ '<%= config.bin %> tickets clarifications DRFL-3 -p acme-api --json',
23
+ ];
24
+ static flags = { ...base_1.projectFlag };
25
+ async run() {
26
+ const { args, flags } = await this.parse(TicketsClarifications);
27
+ const projectId = await this.resolveProjectId(flags.project);
28
+ const path = `/cli/v1/projects/${encodeURIComponent(projectId)}/tickets/${encodeURIComponent(args.id)}/clarifications`;
29
+ const res = await this.api.get(path);
30
+ if (!this.jsonEnabled()) {
31
+ this.log((0, ticket_clarifications_1.renderClarificationState)(res.data ?? {}));
32
+ }
33
+ return res;
34
+ }
35
+ }
36
+ exports.default = TicketsClarifications;
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class UsageList extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ kind: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ page: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
10
+ };
11
+ run(): Promise<unknown>;
12
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_1 = require("../../base");
4
+ const core_1 = require("@oclif/core");
5
+ // CYSK-29 — i simboli VISTI in esecuzione (l'insieme positivo). Il verdetto «inutilizzato» lo
6
+ // calcola lo scanner con l'inventario statico del repo, mai questo comando.
7
+ class UsageList extends base_1.BaseCommand {
8
+ static description = 'List the usage symbols the product reported as actually executed (routes as Controller#action, jobs, custom keys)';
9
+ static examples = [
10
+ '<%= config.bin %> usage list --project CYRA',
11
+ '<%= config.bin %> usage list -p CYRA --kind route --environment production',
12
+ '<%= config.bin %> usage list -p CYRA --json',
13
+ ];
14
+ static flags = {
15
+ ...base_1.projectFlag,
16
+ kind: core_1.Flags.string({ description: 'Only this kind (route, job, custom)' }),
17
+ environment: core_1.Flags.string({ description: 'Only this environment' }),
18
+ page: core_1.Flags.integer({ description: 'Page number', default: 1 }),
19
+ };
20
+ async run() {
21
+ const { flags } = await this.parse(UsageList);
22
+ const projectId = await this.resolveProjectId(flags.project);
23
+ const query = new URLSearchParams({ page: String(flags.page) });
24
+ if (flags.kind)
25
+ query.set('kind', flags.kind);
26
+ if (flags.environment)
27
+ query.set('environment', flags.environment);
28
+ const res = await this.api.get(`/cli/v1/projects/${projectId}/usage?${query.toString()}`);
29
+ if (!this.jsonEnabled()) {
30
+ const rows = res.data ?? [];
31
+ if (rows.length === 0) {
32
+ this.log('No usage reported yet: the SDK flushes every ~5 minutes once deployed.');
33
+ }
34
+ else {
35
+ for (const row of rows) {
36
+ this.log(`${row.kind ?? '?'} ${row.symbol ?? '?'} last_seen ${row.last_seen_at ?? '-'} hits ~${row.hits_count ?? '-'} (${row.environment ?? '-'})`);
37
+ }
38
+ }
39
+ }
40
+ return res;
41
+ }
42
+ }
43
+ exports.default = UsageList;
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class UsageReporters extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ kind: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<unknown>;
10
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_1 = require("../../base");
4
+ const core_1 = require("@oclif/core");
5
+ // CYSK-29 — chi sta mandando usage e da quando: la risposta a «rotta mai chiamata o SDK mai
6
+ // deployato?». Lo scanner la legge PRIMA di giudicare qualunque kind; `truncated_last_window`
7
+ // squalifica il kind.
8
+ class UsageReporters extends base_1.BaseCommand {
9
+ static description = 'List the usage reporters: which SDK is sending usage of each kind, and since when';
10
+ static examples = [
11
+ '<%= config.bin %> usage reporters --project CYRA',
12
+ '<%= config.bin %> usage reporters -p CYRA --kind route',
13
+ ];
14
+ static flags = {
15
+ ...base_1.projectFlag,
16
+ kind: core_1.Flags.string({ description: 'Only this kind (route, job, custom)' }),
17
+ };
18
+ async run() {
19
+ const { flags } = await this.parse(UsageReporters);
20
+ const projectId = await this.resolveProjectId(flags.project);
21
+ const query = flags.kind ? `?kind=${encodeURIComponent(flags.kind)}` : '';
22
+ const res = await this.api.get(`/cli/v1/projects/${projectId}/usage/reporters${query}`);
23
+ if (!this.jsonEnabled()) {
24
+ const rows = res.data ?? [];
25
+ if (rows.length === 0) {
26
+ this.log('No usage reporter yet: without one, "never seen" only means "SDK not deployed".');
27
+ }
28
+ else {
29
+ for (const row of rows) {
30
+ this.log(`${row.kind ?? '?'} ${row.sdk_name ?? '?'}@${row.sdk_version ?? '-'} since ${row.first_reported_at ?? '-'} last ${row.last_reported_at ?? '-'} truncated ${row.truncated_last_window ? 'YES' : 'no'} (${row.environment ?? '-'})`);
31
+ }
32
+ }
33
+ }
34
+ return res;
35
+ }
36
+ }
37
+ exports.default = UsageReporters;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Lo stato del ciclo di chiarimenti, come lo racconta il SERVER (CYRA-628).
3
+ *
4
+ * Fino a qui quello stato viveva nel testo della discussione: un marcatore HTML che tre repository
5
+ * ri-parsavano per conto loro. Bastava che il sistema stesso scrivesse una riga qualsiasi — «resoconto
6
+ * aggiornato alla versione 2» — perché chi legge la scambiasse per una risposta e facesse ripartire un
7
+ * ticket a cui non aveva risposto nessuno. Intanto l'archivio continuava a dire «in attesa»: due parti
8
+ * dello stesso prodotto raccontavano cose diverse sullo stesso ticket, e decideva quella che sapeva meno.
9
+ *
10
+ * Il LIMITE di giri non compare qui e non compare nella risposta: il server espone i fatti — quanti
11
+ * giri, se è arrivata una risposta — e quando chiamare una persona resta policy di chi legge.
12
+ */
13
+ export declare function renderClarificationState(stato: Record<string, unknown>): string;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderClarificationState = renderClarificationState;
4
+ const output_1 = require("./output");
5
+ /**
6
+ * Lo stato del ciclo di chiarimenti, come lo racconta il SERVER (CYRA-628).
7
+ *
8
+ * Fino a qui quello stato viveva nel testo della discussione: un marcatore HTML che tre repository
9
+ * ri-parsavano per conto loro. Bastava che il sistema stesso scrivesse una riga qualsiasi — «resoconto
10
+ * aggiornato alla versione 2» — perché chi legge la scambiasse per una risposta e facesse ripartire un
11
+ * ticket a cui non aveva risposto nessuno. Intanto l'archivio continuava a dire «in attesa»: due parti
12
+ * dello stesso prodotto raccontavano cose diverse sullo stesso ticket, e decideva quella che sapeva meno.
13
+ *
14
+ * Il LIMITE di giri non compare qui e non compare nella risposta: il server espone i fatti — quanti
15
+ * giri, se è arrivata una risposta — e quando chiamare una persona resta policy di chi legge.
16
+ */
17
+ function renderClarificationState(stato) {
18
+ const rounds = Array.isArray(stato.rounds) ? stato.rounds : [];
19
+ const testa = `── ${(0, output_1.sanitize)(stato.state ?? '?')} · giri: ${(0, output_1.sanitize)(stato.cycles ?? 0)} · risposta: ${stato.has_reply ? 'sì' : 'no'}`;
20
+ if (rounds.length === 0)
21
+ return `${testa}\nNessuna domanda in corso.`;
22
+ const corpo = rounds.map((round) => {
23
+ const quando = round.answered_at ? `risposto ${(0, output_1.sanitize)(round.answered_at)}` : 'senza risposta';
24
+ return [
25
+ `\n· giro ${(0, output_1.sanitize)(round.cycle ?? '?')} — ${quando}`,
26
+ (0, output_1.sanitizeMultiline)(round.questions ?? ''),
27
+ round.response ? (0, output_1.sanitizeMultiline)(round.response) : '',
28
+ ].filter(Boolean).join('\n');
29
+ });
30
+ return [testa, ...corpo].join('\n');
31
+ }