@skrr-ai/cli 0.1.107 → 0.1.109
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/README.md +10 -0
- package/dist/base-command.d.ts +59 -0
- package/dist/base-command.js +118 -7
- package/dist/commands/agents/update.d.ts +14 -0
- package/dist/commands/agents/update.js +40 -1
- package/dist/commands/commitments/accounting.js +7 -2
- package/dist/commands/commitments/cost.d.ts +11 -0
- package/dist/commands/commitments/cost.js +26 -3
- package/dist/commands/commitments/create.js +2 -1
- package/dist/commands/commitments/operating-review.d.ts +15 -0
- package/dist/commands/commitments/operating-review.js +103 -50
- package/dist/commands/commitments/update.js +12 -5
- package/dist/commands/doctor.js +9 -0
- package/dist/commands/goals/list.js +6 -1
- package/dist/commands/grants/rotate.js +4 -0
- package/dist/commands/login.js +42 -14
- package/dist/commands/machines/list.js +28 -6
- package/dist/commands/projects/show.js +1 -1
- package/dist/commands/revoke-daemon.js +2 -1
- package/dist/commands/spaces/workflows/archive.d.ts +1 -0
- package/dist/commands/spaces/workflows/archive.js +1 -0
- package/dist/commands/spaces/workflows/artifact.d.ts +1 -0
- package/dist/commands/spaces/workflows/artifact.js +1 -0
- package/dist/commands/spaces/workflows/cancel-node.d.ts +1 -0
- package/dist/commands/spaces/workflows/cancel-node.js +1 -0
- package/dist/commands/spaces/workflows/cancel.d.ts +1 -0
- package/dist/commands/spaces/workflows/cancel.js +6 -2
- package/dist/commands/spaces/workflows/create.d.ts +1 -0
- package/dist/commands/spaces/workflows/create.js +7 -1
- package/dist/commands/spaces/workflows/events.d.ts +1 -0
- package/dist/commands/spaces/workflows/events.js +1 -0
- package/dist/commands/spaces/workflows/fixtures/create.d.ts +1 -0
- package/dist/commands/spaces/workflows/fixtures/create.js +1 -0
- package/dist/commands/spaces/workflows/fixtures/list.d.ts +1 -0
- package/dist/commands/spaces/workflows/fixtures/list.js +1 -0
- package/dist/commands/spaces/workflows/lifecycle-diagnostics.d.ts +1 -0
- package/dist/commands/spaces/workflows/lifecycle-diagnostics.js +1 -0
- package/dist/commands/spaces/workflows/list.d.ts +1 -0
- package/dist/commands/spaces/workflows/list.js +1 -0
- package/dist/commands/spaces/workflows/node-types.d.ts +2 -0
- package/dist/commands/spaces/workflows/node-types.js +24 -6
- package/dist/commands/spaces/workflows/pause.d.ts +1 -0
- package/dist/commands/spaces/workflows/pause.js +1 -0
- package/dist/commands/spaces/workflows/plan/show.d.ts +1 -0
- package/dist/commands/spaces/workflows/plan/show.js +1 -0
- package/dist/commands/spaces/workflows/plan/update.d.ts +1 -0
- package/dist/commands/spaces/workflows/plan/update.js +1 -0
- package/dist/commands/spaces/workflows/proposals/apply.d.ts +1 -0
- package/dist/commands/spaces/workflows/proposals/apply.js +1 -0
- package/dist/commands/spaces/workflows/proposals/confirm.d.ts +1 -0
- package/dist/commands/spaces/workflows/proposals/confirm.js +1 -0
- package/dist/commands/spaces/workflows/proposals/create.d.ts +1 -0
- package/dist/commands/spaces/workflows/proposals/create.js +1 -0
- package/dist/commands/spaces/workflows/proposals/dismiss.d.ts +1 -0
- package/dist/commands/spaces/workflows/proposals/dismiss.js +1 -0
- package/dist/commands/spaces/workflows/proposals/list.d.ts +1 -0
- package/dist/commands/spaces/workflows/proposals/list.js +1 -0
- package/dist/commands/spaces/workflows/publish.d.ts +1 -0
- package/dist/commands/spaces/workflows/publish.js +9 -0
- package/dist/commands/spaces/workflows/reconcile.d.ts +1 -0
- package/dist/commands/spaces/workflows/reconcile.js +1 -0
- package/dist/commands/spaces/workflows/resume.d.ts +1 -0
- package/dist/commands/spaces/workflows/resume.js +1 -0
- package/dist/commands/spaces/workflows/retry.d.ts +1 -0
- package/dist/commands/spaces/workflows/retry.js +1 -0
- package/dist/commands/spaces/workflows/run.d.ts +1 -0
- package/dist/commands/spaces/workflows/run.js +14 -7
- package/dist/commands/spaces/workflows/runs.d.ts +1 -0
- package/dist/commands/spaces/workflows/runs.js +1 -0
- package/dist/commands/spaces/workflows/show.d.ts +25 -0
- package/dist/commands/spaces/workflows/show.js +42 -4
- package/dist/commands/spaces/workflows/signal.d.ts +12 -0
- package/dist/commands/spaces/workflows/signal.js +40 -2
- package/dist/commands/spaces/workflows/start.d.ts +1 -0
- package/dist/commands/spaces/workflows/start.js +1 -0
- package/dist/commands/spaces/workflows/task-execution/create.d.ts +1 -0
- package/dist/commands/spaces/workflows/task-execution/create.js +1 -0
- package/dist/commands/spaces/workflows/test.d.ts +1 -0
- package/dist/commands/spaces/workflows/test.js +1 -0
- package/dist/commands/spaces/workflows/triggers/create.d.ts +1 -0
- package/dist/commands/spaces/workflows/triggers/create.js +1 -0
- package/dist/commands/spaces/workflows/triggers/fire.d.ts +1 -0
- package/dist/commands/spaces/workflows/triggers/fire.js +1 -0
- package/dist/commands/spaces/workflows/triggers/list.d.ts +1 -0
- package/dist/commands/spaces/workflows/triggers/list.js +1 -0
- package/dist/commands/spaces/workflows/triggers/update.d.ts +1 -0
- package/dist/commands/spaces/workflows/triggers/update.js +1 -0
- package/dist/commands/spaces/workflows/update.d.ts +1 -0
- package/dist/commands/spaces/workflows/update.js +4 -0
- package/dist/commands/spaces/workflows/validate.d.ts +1 -0
- package/dist/commands/spaces/workflows/validate.js +15 -0
- package/dist/commands/tasks/activity.js +6 -2
- package/dist/commands/tasks/bulk-update.d.ts +1 -0
- package/dist/commands/tasks/bulk-update.js +7 -0
- package/dist/commands/tasks/complete.js +2 -1
- package/dist/commands/tasks/create-tree.d.ts +69 -0
- package/dist/commands/tasks/create-tree.js +413 -47
- package/dist/commands/tasks/list.d.ts +2 -0
- package/dist/commands/tasks/list.js +19 -1
- package/dist/commands/tasks/rearm-recurrence.d.ts +22 -0
- package/dist/commands/tasks/rearm-recurrence.js +68 -0
- package/dist/commands/tasks/show.d.ts +1 -0
- package/dist/commands/tasks/show.js +17 -3
- package/dist/commands/tasks/timeline.js +4 -0
- package/dist/commands/tasks/update.d.ts +1 -0
- package/dist/commands/tasks/update.js +6 -1
- package/dist/commands/triggers/create.js +8 -2
- package/dist/commands/triggers/parse-intent.d.ts +7 -0
- package/dist/commands/triggers/parse-intent.js +31 -9
- package/dist/commands/workspaces/grants.js +23 -3
- package/dist/commands/workspaces/members.d.ts +20 -0
- package/dist/commands/workspaces/members.js +64 -0
- package/dist/commands/workspaces/stewardship.js +14 -2
- package/dist/help.js +12 -0
- package/dist/hooks/command-not-found.js +27 -1
- package/dist/lib/command-miss.d.ts +52 -2
- package/dist/lib/command-miss.js +187 -18
- package/dist/lib/commitment-loop-status.d.ts +8 -0
- package/dist/lib/commitment-loop-status.js +45 -0
- package/dist/lib/commitment-product.js +13 -1
- package/dist/lib/commitments.d.ts +16 -2
- package/dist/lib/commitments.js +48 -8
- package/dist/lib/daemon-command-hint.d.ts +15 -0
- package/dist/lib/daemon-command-hint.js +21 -0
- package/dist/lib/daemon-setup.js +10 -1
- package/dist/lib/daemonBrokerRefusal.js +3 -2
- package/dist/lib/daemonHandoff.js +2 -1
- package/dist/lib/deployed-build.d.ts +43 -0
- package/dist/lib/deployed-build.js +66 -0
- package/dist/lib/grants.d.ts +27 -1
- package/dist/lib/grants.js +39 -21
- package/dist/lib/json-mode.d.ts +11 -0
- package/dist/lib/json-mode.js +19 -0
- package/dist/lib/json-output.d.ts +25 -0
- package/dist/lib/json-output.js +30 -0
- package/dist/lib/list-output.d.ts +9 -0
- package/dist/lib/list-output.js +20 -1
- package/dist/lib/local-daemon-readiness.d.ts +90 -0
- package/dist/lib/local-daemon-readiness.js +143 -0
- package/dist/lib/machines.d.ts +117 -0
- package/dist/lib/machines.js +139 -0
- package/dist/lib/managed-instruction-local.d.ts +2 -0
- package/dist/lib/managed-instruction-local.js +2 -0
- package/dist/lib/profile-machine-identity-guard.d.ts +18 -0
- package/dist/lib/profile-machine-identity-guard.js +29 -0
- package/dist/lib/request-field-flags.d.ts +20 -0
- package/dist/lib/request-field-flags.js +34 -0
- package/dist/lib/stewardship-output.d.ts +1 -1
- package/dist/lib/stewardship-output.js +26 -30
- package/dist/lib/task-batch.d.ts +61 -4
- package/dist/lib/task-batch.js +316 -80
- package/dist/lib/task-economics.d.ts +5 -0
- package/dist/lib/task-economics.js +15 -0
- package/dist/lib/task-recurrence-outcome.d.ts +6 -6
- package/dist/lib/task-recurrence-outcome.js +27 -3
- package/dist/lib/tasks.d.ts +39 -0
- package/dist/lib/tasks.js +132 -0
- package/dist/lib/triggers.d.ts +31 -1
- package/dist/lib/triggers.js +55 -1
- package/dist/lib/workflow-issues.d.ts +14 -0
- package/dist/lib/workflow-issues.js +32 -0
- package/dist/lib/workflow-run-view.d.ts +55 -0
- package/dist/lib/workflow-run-view.js +105 -0
- package/dist/lib/workspaces.d.ts +31 -4
- package/dist/lib/workspaces.js +43 -0
- package/dist/lib/write-target.d.ts +29 -0
- package/dist/lib/write-target.js +72 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/workspaceIsolationProbeWire.d.ts +51 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/workspaceIsolationProbeWire.js +50 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/workspaceIsolationProbeWire.d.ts +51 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/workspaceIsolationProbeWire.js +46 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +7896 -7524
- package/oclif.manifest.json +376 -52
- package/package.json +19 -1
|
@@ -105,6 +105,8 @@ export default class TasksList extends BaseCommand {
|
|
|
105
105
|
subscribed: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
106
106
|
'include-snoozed': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
107
107
|
'external-key': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
108
|
+
'external-key-prefix': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
109
|
+
'description-format': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
108
110
|
tag: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
109
111
|
'label-id': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
110
112
|
q: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
@@ -48,6 +48,7 @@ const FILTER_FLAGS = new Set([
|
|
|
48
48
|
'subscribed',
|
|
49
49
|
'include-snoozed',
|
|
50
50
|
'external-key',
|
|
51
|
+
'external-key-prefix',
|
|
51
52
|
'blocked-by',
|
|
52
53
|
'blocks',
|
|
53
54
|
'due-before',
|
|
@@ -286,6 +287,13 @@ function buildListParams(flags, assigneeUserId) {
|
|
|
286
287
|
...(flag('external-key')
|
|
287
288
|
? { externalKey: flag('external-key') }
|
|
288
289
|
: {}),
|
|
290
|
+
...(flag('external-key-prefix')
|
|
291
|
+
? { externalKeyPrefix: flag('external-key-prefix') }
|
|
292
|
+
: {}),
|
|
293
|
+
// A presentation of each row, not a filter: it is deliberately not in FILTER_FLAGS.
|
|
294
|
+
...(flag('description-format') === 'markdown'
|
|
295
|
+
? { descriptionFormat: 'markdown' }
|
|
296
|
+
: {}),
|
|
289
297
|
...(flag('blocked-by') ? { blockedBy: flag('blocked-by') } : {}),
|
|
290
298
|
...(flag('blocks') ? { blocks: flag('blocks') } : {}),
|
|
291
299
|
...(flag('due-before') ? { dueBefore: flag('due-before') } : {}),
|
|
@@ -469,6 +477,13 @@ class TasksList extends base_command_1.BaseCommand {
|
|
|
469
477
|
description: 'Include tasks you have personally snoozed (hidden by default)',
|
|
470
478
|
}),
|
|
471
479
|
'external-key': core_1.Flags.string({ description: 'Filter by external key' }),
|
|
480
|
+
'external-key-prefix': core_1.Flags.string({
|
|
481
|
+
description: 'Filter to tasks whose external key starts with this literal prefix, e.g. every task of one tree written under --external-key-prefix. Combine with --space; see also `tasks create-tree --verify`.',
|
|
482
|
+
}),
|
|
483
|
+
'description-format': core_1.Flags.string({
|
|
484
|
+
description: 'JSON/text: how to read each description. html (default) is what is stored; markdown returns it as it was written, so a description you wrote compares equal to the one you read back.',
|
|
485
|
+
options: ['html', 'markdown'],
|
|
486
|
+
}),
|
|
472
487
|
tag: core_1.Flags.string({
|
|
473
488
|
description: 'Filter to tasks carrying EVERY listed tag (repeatable, AND-intersection, ' +
|
|
474
489
|
'case-insensitive)',
|
|
@@ -711,7 +726,8 @@ class TasksList extends base_command_1.BaseCommand {
|
|
|
711
726
|
if (flags.rank)
|
|
712
727
|
this.log('\nRanked only within this fetched page; estimates are claims, not measured savings.\n' +
|
|
713
728
|
'SCORE = annualized USD savings / max(effort hours, 0.5) x risk factor (low 1, medium 0.6, high 0.25); ' +
|
|
714
|
-
'— means savings, effort or risk is missing, so the row is not scored
|
|
729
|
+
'— means savings, effort or risk is missing (or outside the plausible range), so the row is not scored ' +
|
|
730
|
+
'and sorts after every scored row: larger stated savings first, then rows with no estimate.');
|
|
715
731
|
if (r?.next_cursor) {
|
|
716
732
|
this.log('');
|
|
717
733
|
this.log(`Next page: --cursor ${r.next_cursor}`);
|
|
@@ -719,6 +735,8 @@ class TasksList extends base_command_1.BaseCommand {
|
|
|
719
735
|
const note = (0, list_output_1.limitNote)(flags.limit, items.length, Boolean(r?.has_more));
|
|
720
736
|
for (const line of (0, list_output_1.warningLines)(note.warning ? [note.warning] : []))
|
|
721
737
|
this.log(line);
|
|
738
|
+
for (const line of (0, list_output_1.textModeProjectionNotes)(flags))
|
|
739
|
+
this.log(line);
|
|
722
740
|
}
|
|
723
741
|
}
|
|
724
742
|
exports.default = TasksList;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* Continue a recurring series whose next occurrence was never armed (OSK-15338).
|
|
4
|
+
*
|
|
5
|
+
* The failure (`recurrence.armFailure`) is recorded on the FINISHED occurrence, and `tasks schedule`
|
|
6
|
+
* refuses a finished Task, so this is the command every surface names for the way back. It arms the
|
|
7
|
+
* occurrence the series is owed and clears the failure; `--cron` / `--timezone` correct the series
|
|
8
|
+
* first, which is the only cure for an `invalid_pattern` failure.
|
|
9
|
+
*/
|
|
10
|
+
export default class TasksRearmRecurrence extends BaseCommand {
|
|
11
|
+
static description: string;
|
|
12
|
+
static examples: string[];
|
|
13
|
+
static args: {
|
|
14
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
15
|
+
};
|
|
16
|
+
static flags: {
|
|
17
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
cron: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
+
timezone: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
+
};
|
|
21
|
+
run(): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../base-command");
|
|
6
|
+
const web_url_1 = require("../../lib/web-url");
|
|
7
|
+
/**
|
|
8
|
+
* Continue a recurring series whose next occurrence was never armed (OSK-15338).
|
|
9
|
+
*
|
|
10
|
+
* The failure (`recurrence.armFailure`) is recorded on the FINISHED occurrence, and `tasks schedule`
|
|
11
|
+
* refuses a finished Task, so this is the command every surface names for the way back. It arms the
|
|
12
|
+
* occurrence the series is owed and clears the failure; `--cron` / `--timezone` correct the series
|
|
13
|
+
* first, which is the only cure for an `invalid_pattern` failure.
|
|
14
|
+
*/
|
|
15
|
+
class TasksRearmRecurrence extends base_command_1.BaseCommand {
|
|
16
|
+
static description = 'Re-arm a recurring series from the finished occurrence whose next occurrence was never scheduled';
|
|
17
|
+
static examples = [
|
|
18
|
+
'<%= config.bin %> tasks rearm-recurrence OSK-42',
|
|
19
|
+
'<%= config.bin %> tasks rearm-recurrence OSK-42 --cron "0 9 * * 1-5" --timezone America/New_York',
|
|
20
|
+
];
|
|
21
|
+
static args = {
|
|
22
|
+
id: core_1.Args.string({
|
|
23
|
+
description: 'The finished occurrence (Task ID or identifier) that carries the arm failure',
|
|
24
|
+
required: true,
|
|
25
|
+
ignoreStdin: true,
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
static flags = {
|
|
29
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
30
|
+
cron: core_1.Flags.string({
|
|
31
|
+
description: 'Correct the series pattern first: five cron fields "minute hour day-of-month month day-of-week", e.g. "0 9 * * 1-5"',
|
|
32
|
+
}),
|
|
33
|
+
timezone: core_1.Flags.string({
|
|
34
|
+
description: 'Correct the series timezone first (IANA zone, e.g. America/New_York)',
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
async run() {
|
|
38
|
+
this.requireAuth();
|
|
39
|
+
const { args, flags } = await this.parse(TasksRearmRecurrence);
|
|
40
|
+
const taskRef = await this.resolveEntityRef('task', args.id);
|
|
41
|
+
let result;
|
|
42
|
+
try {
|
|
43
|
+
result = await data_provider_1.dataService.rearmTaskRecurrence({
|
|
44
|
+
taskId: taskRef,
|
|
45
|
+
pattern: flags.cron,
|
|
46
|
+
timezone: flags.timezone,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
this.handleApiError(err);
|
|
51
|
+
}
|
|
52
|
+
if (flags.json) {
|
|
53
|
+
this.log(JSON.stringify({
|
|
54
|
+
...result,
|
|
55
|
+
task: (0, web_url_1.withTaskUrl)(this.cliConfig.baseURL, result.task),
|
|
56
|
+
}, null, 2));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const finished = result.task;
|
|
60
|
+
const from = finished.identifier || finished.id || taskRef;
|
|
61
|
+
const next = result.successor.identifier || result.successor.id;
|
|
62
|
+
const when = result.successor.scheduledFor ? ` for ${result.successor.scheduledFor}` : '';
|
|
63
|
+
this.log(result.alreadyArmed
|
|
64
|
+
? `The series from ${from} was already armed: next occurrence ${next}${when}. The failure marker is cleared.`
|
|
65
|
+
: `Re-armed the series from ${from}: next occurrence ${next} is scheduled${when}.`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.default = TasksRearmRecurrence;
|
|
@@ -112,6 +112,7 @@ export default class TasksShow extends BaseCommand {
|
|
|
112
112
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
113
113
|
task: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
114
114
|
'no-enrich': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
115
|
+
'description-format': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
115
116
|
};
|
|
116
117
|
run(): Promise<void>;
|
|
117
118
|
/**
|
|
@@ -21,6 +21,7 @@ const label_ref_1 = require("../../lib/label-ref");
|
|
|
21
21
|
const principal_display_1 = require("../../lib/principal-display");
|
|
22
22
|
const task_economics_line_1 = require("../../lib/task-economics-line");
|
|
23
23
|
const format_1 = require("../../lib/format");
|
|
24
|
+
const task_recurrence_outcome_1 = require("../../lib/task-recurrence-outcome");
|
|
24
25
|
/**
|
|
25
26
|
* Where to look next — as COMMANDS, not as facts about the task.
|
|
26
27
|
*
|
|
@@ -159,9 +160,13 @@ function recurrenceArmFailureLines(t, bin = 'skrr') {
|
|
|
159
160
|
const code = recurrence?.armFailure?.code;
|
|
160
161
|
if (typeof code !== 'string' || !code)
|
|
161
162
|
return [];
|
|
163
|
+
const ref = (typeof t.identifier === 'string' && t.identifier) ||
|
|
164
|
+
(typeof t.id === 'string' && t.id) ||
|
|
165
|
+
'<task-id>';
|
|
162
166
|
return [
|
|
163
167
|
`Recurrence: ${(0, data_provider_1.describeRecurrenceArmFailure)(code)} (${code})`,
|
|
164
|
-
|
|
168
|
+
// Not `tasks schedule`: that refuses the finished occurrence carrying this failure (OSK-15338).
|
|
169
|
+
` ${(0, task_recurrence_outcome_1.recurrenceRearmHint)(code, ref, bin)}`,
|
|
165
170
|
];
|
|
166
171
|
}
|
|
167
172
|
/**
|
|
@@ -246,6 +251,10 @@ class TasksShow extends base_command_1.BaseCommand {
|
|
|
246
251
|
'no-enrich': core_1.Flags.boolean({
|
|
247
252
|
description: 'Skip server-side enrichment (assignee names, parent titles)',
|
|
248
253
|
}),
|
|
254
|
+
'description-format': core_1.Flags.string({
|
|
255
|
+
description: 'How to read the description. html (default) is what is stored; markdown returns it as it was written.',
|
|
256
|
+
options: ['html', 'markdown'],
|
|
257
|
+
}),
|
|
249
258
|
};
|
|
250
259
|
async run() {
|
|
251
260
|
this.requireAuth();
|
|
@@ -304,7 +313,12 @@ class TasksShow extends base_command_1.BaseCommand {
|
|
|
304
313
|
task = bound;
|
|
305
314
|
}
|
|
306
315
|
else {
|
|
307
|
-
task = await data_provider_1.dataService.getTask(taskId, {
|
|
316
|
+
task = await data_provider_1.dataService.getTask(taskId, {
|
|
317
|
+
enrich: !flags['no-enrich'],
|
|
318
|
+
...(flags['description-format'] === 'markdown'
|
|
319
|
+
? { descriptionFormat: 'markdown' }
|
|
320
|
+
: {}),
|
|
321
|
+
});
|
|
308
322
|
}
|
|
309
323
|
}
|
|
310
324
|
catch (err) {
|
|
@@ -331,7 +345,7 @@ class TasksShow extends base_command_1.BaseCommand {
|
|
|
331
345
|
completionRead = false;
|
|
332
346
|
}
|
|
333
347
|
if (flags.json) {
|
|
334
|
-
this.
|
|
348
|
+
this.printJsonResult({ ...t, url, completion });
|
|
335
349
|
return;
|
|
336
350
|
}
|
|
337
351
|
for (const line of completionLines(completion, { read: completionRead }))
|
|
@@ -5,6 +5,7 @@ const core_1 = require("@oclif/core");
|
|
|
5
5
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
6
6
|
const base_command_1 = require("../../base-command");
|
|
7
7
|
const format_1 = require("../../lib/format");
|
|
8
|
+
const task_economics_1 = require("../../lib/task-economics");
|
|
8
9
|
const task_legacy_1 = require("../../lib/task-legacy");
|
|
9
10
|
/**
|
|
10
11
|
* `<action> (<k=v ...>)`, or just the preview when there is nothing to add.
|
|
@@ -13,6 +14,9 @@ const task_legacy_1 = require("../../lib/task-legacy");
|
|
|
13
14
|
* renders `details` with, so the two surfaces describe one entry the same way.
|
|
14
15
|
*/
|
|
15
16
|
function withDetails(item) {
|
|
17
|
+
// An estimate change reads as from-what-to-what, the same line `tasks activity` prints.
|
|
18
|
+
if (typeof item.type === 'string' && item.type.startsWith(data_provider_1.TASK_ECONOMICS_ACTIVITY_TYPE_PREFIX))
|
|
19
|
+
return (0, task_economics_1.describeEconomicsChange)(item.data);
|
|
16
20
|
const preview = String(item.preview ?? '-');
|
|
17
21
|
const details = (0, format_1.formatCell)(item.data ?? item.details, '');
|
|
18
22
|
return details ? `${preview} (${details})` : preview;
|
|
@@ -23,6 +23,7 @@ export default class TasksUpdate extends BaseCommand {
|
|
|
23
23
|
risk: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
24
|
confidence: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
25
25
|
rationale: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
26
|
+
'retract-estimate': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
26
27
|
estimate: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
27
28
|
/**
|
|
28
29
|
* Declared, hidden, and refused — on purpose. (S4 dogfood finding)
|
|
@@ -84,6 +84,10 @@ class TasksUpdate extends base_command_1.BaseCommand {
|
|
|
84
84
|
rationale: core_1.Flags.string({
|
|
85
85
|
description: 'Why the estimate is what it is, up to 500 characters (part of the estimate). An earlier rationale stays on the claim, under its new basis, until you replace it.',
|
|
86
86
|
}),
|
|
87
|
+
'retract-estimate': core_1.Flags.boolean({
|
|
88
|
+
description: "Remove the Task's economic estimate (savings, effort, risk, confidence and rationale). Recorded in `tasks activity` as task.economics.retracted under your name; an Agent cannot retract an estimate a person confirmed (409).",
|
|
89
|
+
exclusive: ['savings', 'per', 'effort', 'risk', 'confidence', 'rationale'],
|
|
90
|
+
}),
|
|
87
91
|
estimate: core_1.Flags.integer({
|
|
88
92
|
description: 'New estimate value from the Space estimate scale. Requires a scale on the Space (or an ' +
|
|
89
93
|
'ancestor it inherits from); with none set, the server drops the value. Set the scale ' +
|
|
@@ -410,7 +414,8 @@ class TasksUpdate extends base_command_1.BaseCommand {
|
|
|
410
414
|
startDate: flags['start-date'],
|
|
411
415
|
dueDate: flags['due-date'],
|
|
412
416
|
estimate: flags.estimate,
|
|
413
|
-
|
|
417
|
+
// `null` is the retraction the server records as its own Activity event (OSK-15370).
|
|
418
|
+
economics: flags['retract-estimate'] ? null : (0, task_economics_1.economicsFromFlags)(flags, body.economics),
|
|
414
419
|
// Never sent: `taskUpdateMutationGuard` refuses any payload carrying
|
|
415
420
|
// `status` before the request is built. It is merged in only so the guard
|
|
416
421
|
// sees it and answers with the sentence that names `tasks move`.
|
|
@@ -7,7 +7,7 @@ const builtinActions_1 = require("../../lib/builtinActions");
|
|
|
7
7
|
const triggers_1 = require("../../lib/triggers");
|
|
8
8
|
const web_url_1 = require("../../lib/web-url");
|
|
9
9
|
class TriggersCreate extends base_command_1.BaseCommand {
|
|
10
|
-
static description = 'Create a universal trigger';
|
|
10
|
+
static description = 'Create a universal trigger. A schedule trigger skips an occurrence that is overdue by more than its catch-up window (--stale-catchup-ms)';
|
|
11
11
|
static examples = [
|
|
12
12
|
'<%= config.bin %> triggers create --scope agent --ref agentId=<agent-id> --kind schedule --mode send_message --cron "0 9 * * *" --prompt "Prepare the daily brief"',
|
|
13
13
|
'<%= config.bin %> triggers create --scope agent --ref agentId=<agent-id> --kind once --mode send_message --at 2026-06-01T15:30:00Z --prompt "Send the launch recap"',
|
|
@@ -65,7 +65,7 @@ class TriggersCreate extends base_command_1.BaseCommand {
|
|
|
65
65
|
}),
|
|
66
66
|
'effect-options': core_1.Flags.string({ description: 'Effect policy options JSON object' }),
|
|
67
67
|
'workflow-event-key': core_1.Flags.string({
|
|
68
|
-
description: 'Exact event key the parked workflow step waits on (required for mode=workflow_signal). Resolves steps in the scope Space; the trigger owner must hold Space edit access at every fire',
|
|
68
|
+
description: 'Exact event key the parked workflow step waits on (required for mode=workflow_signal). Resolves steps in the scope Space; the trigger owner must hold Space edit access at every fire. A person resolves one wait by hand with `skrr workflows signal`',
|
|
69
69
|
}),
|
|
70
70
|
'workflow-outcome': core_1.Flags.string({
|
|
71
71
|
description: 'How the resolved step settles (default success)',
|
|
@@ -290,6 +290,8 @@ class TriggersCreate extends base_command_1.BaseCommand {
|
|
|
290
290
|
dryRun: flags['dry-run'],
|
|
291
291
|
});
|
|
292
292
|
(0, triggers_1.mergeObjectField)(payload, 'execution', execution);
|
|
293
|
+
const mergedExecution = payload.execution;
|
|
294
|
+
(0, triggers_1.assertModeRequiredFlags)(mergedExecution?.mode, flags, mergedExecution);
|
|
293
295
|
(0, triggers_1.mergeTriggerKindConfig)(payload, flags.kind ?? payload.kind, {
|
|
294
296
|
schedule,
|
|
295
297
|
once,
|
|
@@ -304,6 +306,10 @@ class TriggersCreate extends base_command_1.BaseCommand {
|
|
|
304
306
|
this.error(err.message, { exit: 1 });
|
|
305
307
|
}
|
|
306
308
|
this.validatePayload(payload);
|
|
309
|
+
// A body assembled from flags: the server's field paths are read back as those flags. A
|
|
310
|
+
// body the person wrote (--from-json) keeps the paths, which are then what they typed.
|
|
311
|
+
if (!flags['from-json'])
|
|
312
|
+
this.requestFieldFlags = triggers_1.TRIGGER_CREATE_FIELD_FLAGS;
|
|
307
313
|
let trigger;
|
|
308
314
|
try {
|
|
309
315
|
trigger = await triggers_1.triggerApi.create(payload);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseCommand } from '../../base-command';
|
|
2
|
+
import { type TriggerParseIntentResponse } from '../../lib/triggers';
|
|
2
3
|
export default class TriggersParseIntent extends BaseCommand {
|
|
3
4
|
static description: string;
|
|
4
5
|
static examples: string[];
|
|
@@ -14,3 +15,9 @@ export default class TriggersParseIntent extends BaseCommand {
|
|
|
14
15
|
};
|
|
15
16
|
run(): Promise<void>;
|
|
16
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* The human rendering of a parse. Every unsupported condition is printed on its own line, never
|
|
20
|
+
* folded into the proposal (OSK-15402: "skip market holidays" was dropped while the summary claimed
|
|
21
|
+
* "every NYSE trading day"), and a clarifying question names the supported way to answer it.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseIntentLines(result: TriggerParseIntentResponse, bin?: string): string[];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseIntentLines = parseIntentLines;
|
|
3
4
|
const core_1 = require("@oclif/core");
|
|
4
5
|
const base_command_1 = require("../../base-command");
|
|
5
6
|
const prompt_1 = require("../../lib/prompt");
|
|
@@ -21,11 +22,11 @@ class TriggersParseIntent extends base_command_1.BaseCommand {
|
|
|
21
22
|
multiple: true,
|
|
22
23
|
}),
|
|
23
24
|
message: core_1.Flags.string({
|
|
24
|
-
description: 'User message to parse (repeatable;
|
|
25
|
+
description: 'User message to parse (repeatable; appended as user turns, after --history-json when both are given)',
|
|
25
26
|
multiple: true,
|
|
26
27
|
}),
|
|
27
28
|
'history-json': core_1.Flags.string({
|
|
28
|
-
description: '
|
|
29
|
+
description: 'Parser history JSON array of {role:"user"|"assistant",content:string} objects. To answer a clarifying question, pass the `history` a previous --json run returned and add your reply with --message',
|
|
29
30
|
}),
|
|
30
31
|
timezone: core_1.Flags.string({ description: 'IANA timezone used for relative times' }),
|
|
31
32
|
now: core_1.Flags.string({ description: 'Override current ISO timestamp used for relative times' }),
|
|
@@ -51,7 +52,10 @@ class TriggersParseIntent extends base_command_1.BaseCommand {
|
|
|
51
52
|
if (history)
|
|
52
53
|
body.history = history;
|
|
53
54
|
if (flags.message && flags.message.length > 0) {
|
|
54
|
-
|
|
55
|
+
// Appended, never replacing: a reply to a clarifying question only means something after
|
|
56
|
+
// the question it answers (OSK-15402). It used to discard --history-json entirely.
|
|
57
|
+
const prior = Array.isArray(body.history) ? body.history : [];
|
|
58
|
+
body.history = [...prior, ...flags.message.map((content) => ({ role: 'user', content }))];
|
|
55
59
|
}
|
|
56
60
|
if (flags.timezone)
|
|
57
61
|
body.timezone = flags.timezone;
|
|
@@ -83,12 +87,30 @@ class TriggersParseIntent extends base_command_1.BaseCommand {
|
|
|
83
87
|
this.log(JSON.stringify(result, null, 2));
|
|
84
88
|
return;
|
|
85
89
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (result.proposedTrigger) {
|
|
89
|
-
this.log('');
|
|
90
|
-
this.log(JSON.stringify(result.proposedTrigger, null, 2));
|
|
91
|
-
}
|
|
90
|
+
for (const line of parseIntentLines(result, this.config.bin))
|
|
91
|
+
this.log(line);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
exports.default = TriggersParseIntent;
|
|
95
|
+
/**
|
|
96
|
+
* The human rendering of a parse. Every unsupported condition is printed on its own line, never
|
|
97
|
+
* folded into the proposal (OSK-15402: "skip market holidays" was dropped while the summary claimed
|
|
98
|
+
* "every NYSE trading day"), and a clarifying question names the supported way to answer it.
|
|
99
|
+
*/
|
|
100
|
+
function parseIntentLines(result, bin = 'skrr') {
|
|
101
|
+
const lines = [result.message ?? '(no parser message)'];
|
|
102
|
+
lines.push(`Needs clarification: ${result.needsClarification ? 'yes' : 'no'}`);
|
|
103
|
+
const unsupported = Array.isArray(result.unsupported) ? result.unsupported : [];
|
|
104
|
+
if (unsupported.length > 0) {
|
|
105
|
+
lines.push('', 'Not applied by this trigger:');
|
|
106
|
+
for (const item of unsupported)
|
|
107
|
+
lines.push(` - "${item.text}" (${item.kind}): ${item.reason}`);
|
|
108
|
+
}
|
|
109
|
+
if (result.proposedTrigger) {
|
|
110
|
+
lines.push('', JSON.stringify(result.proposedTrigger, null, 2));
|
|
111
|
+
}
|
|
112
|
+
else if (result.needsClarification) {
|
|
113
|
+
lines.push('', 'To answer, run it again with your reply after the earlier messages, e.g.', ` ${bin} triggers parse-intent --scope <kind> --ref <key=value> --message "<first message>" --message "<your answer>"`, 'or pass the returned `history` (see --json) with --history-json and add --message "<your answer>".');
|
|
114
|
+
}
|
|
115
|
+
return lines;
|
|
116
|
+
}
|
|
@@ -18,10 +18,11 @@ class WorkspacesGrants extends base_command_1.BaseCommand {
|
|
|
18
18
|
const { args, flags } = await this.parse(WorkspacesGrants);
|
|
19
19
|
try {
|
|
20
20
|
const report = await (0, workspaces_1.listWorkspaceGrants)(args.workspaceId);
|
|
21
|
-
if (flags.json)
|
|
21
|
+
if (flags.json) {
|
|
22
22
|
this.log(JSON.stringify(report, null, 2));
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
(0, stewardship_output_1.printWorkspaceGrants)(report, (line) => this.log(line), await memberNames(args.workspaceId));
|
|
25
26
|
}
|
|
26
27
|
catch (error) {
|
|
27
28
|
this.handleApiError(error);
|
|
@@ -29,3 +30,22 @@ class WorkspacesGrants extends base_command_1.BaseCommand {
|
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
exports.default = WorkspacesGrants;
|
|
33
|
+
/**
|
|
34
|
+
* Owner ids to names, for the table's OWNER column (OSK-15357). Best effort: the
|
|
35
|
+
* report is already authoritative, and a members read that fails only leaves
|
|
36
|
+
* the column showing ids, as it did before.
|
|
37
|
+
*/
|
|
38
|
+
async function memberNames(workspaceId) {
|
|
39
|
+
try {
|
|
40
|
+
const members = await (0, workspaces_1.listWorkspaceMembers)(workspaceId);
|
|
41
|
+
return new Map(members
|
|
42
|
+
.map((member) => [
|
|
43
|
+
String(member.userId),
|
|
44
|
+
member.user?.name || member.user?.username || member.user?.email || '',
|
|
45
|
+
])
|
|
46
|
+
.filter(([, name]) => name));
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return new Map();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr workspaces members` — who is in a workspace, with the user id the
|
|
4
|
+
* other workspace commands take (OSK-15356).
|
|
5
|
+
*
|
|
6
|
+
* `workspaces stewardship` needs a member's user id, and nothing in this
|
|
7
|
+
* command family printed one but `skrr whoami` (your own). An owner handing
|
|
8
|
+
* over a departing member's work had no way to find theirs.
|
|
9
|
+
*/
|
|
10
|
+
export default class WorkspacesMembers extends BaseCommand {
|
|
11
|
+
static description: string;
|
|
12
|
+
static examples: string[];
|
|
13
|
+
static args: {
|
|
14
|
+
workspaceId: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
15
|
+
};
|
|
16
|
+
static flags: {
|
|
17
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../base-command");
|
|
5
|
+
const format_1 = require("../../lib/format");
|
|
6
|
+
const workspaces_1 = require("../../lib/workspaces");
|
|
7
|
+
/**
|
|
8
|
+
* `skrr workspaces members` — who is in a workspace, with the user id the
|
|
9
|
+
* other workspace commands take (OSK-15356).
|
|
10
|
+
*
|
|
11
|
+
* `workspaces stewardship` needs a member's user id, and nothing in this
|
|
12
|
+
* command family printed one but `skrr whoami` (your own). An owner handing
|
|
13
|
+
* over a departing member's work had no way to find theirs.
|
|
14
|
+
*/
|
|
15
|
+
class WorkspacesMembers extends base_command_1.BaseCommand {
|
|
16
|
+
static description = 'List the current members of a workspace with their user ids and roles';
|
|
17
|
+
static examples = [
|
|
18
|
+
'<%= config.bin %> workspaces members <workspace-id>',
|
|
19
|
+
'<%= config.bin %> workspaces members <workspace-id> --json',
|
|
20
|
+
];
|
|
21
|
+
static args = {
|
|
22
|
+
workspaceId: core_1.Args.string({ required: true, ignoreStdin: true, description: 'Workspace ID' }),
|
|
23
|
+
};
|
|
24
|
+
static flags = {
|
|
25
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
26
|
+
};
|
|
27
|
+
async run() {
|
|
28
|
+
this.requireAuth();
|
|
29
|
+
const { args, flags } = await this.parse(WorkspacesMembers);
|
|
30
|
+
let members;
|
|
31
|
+
try {
|
|
32
|
+
members = await (0, workspaces_1.listWorkspaceMembers)(args.workspaceId);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
this.handleApiError(error);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (flags.json) {
|
|
39
|
+
this.log(JSON.stringify(members, null, 2));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (members.length === 0) {
|
|
43
|
+
this.log('No current members.');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
(0, format_1.renderTable)(members.map((member) => ({
|
|
47
|
+
userId: String(member.userId),
|
|
48
|
+
name: member.user?.name || member.user?.username || '—',
|
|
49
|
+
email: member.user?.email || '—',
|
|
50
|
+
role: member.role || '—',
|
|
51
|
+
joined: member.joinedAt || '—',
|
|
52
|
+
})), [
|
|
53
|
+
{ key: 'userId', header: 'USER ID', verbatim: true },
|
|
54
|
+
{ key: 'name', header: 'NAME', maxWidth: 28 },
|
|
55
|
+
{ key: 'email', header: 'EMAIL', maxWidth: 36 },
|
|
56
|
+
{ key: 'role', header: 'ROLE' },
|
|
57
|
+
{ key: 'joined', header: 'JOINED' },
|
|
58
|
+
], (line) => this.log(line));
|
|
59
|
+
this.log('');
|
|
60
|
+
this.log('Current members only: someone who has left is not listed. ' +
|
|
61
|
+
`\`skrr workspaces stewardship ${args.workspaceId} <user-id|email>\` reads one member's handover.`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.default = WorkspacesMembers;
|
|
@@ -8,13 +8,15 @@ class WorkspacesStewardship extends base_command_1.BaseCommand {
|
|
|
8
8
|
static description = 'Read a member’s workspace stewardship metadata (person owner/admin only)';
|
|
9
9
|
static examples = [
|
|
10
10
|
'<%= config.bin %> workspaces stewardship <workspace-id> <user-id> --json',
|
|
11
|
+
'<%= config.bin %> workspaces stewardship <workspace-id> person@example.com',
|
|
11
12
|
];
|
|
12
13
|
static args = {
|
|
13
14
|
workspaceId: core_1.Args.string({ required: true, ignoreStdin: true, description: 'Workspace ID' }),
|
|
14
15
|
userId: core_1.Args.string({
|
|
15
16
|
required: true,
|
|
16
17
|
ignoreStdin: true,
|
|
17
|
-
description:
|
|
18
|
+
description: "Member user ID (24 hexadecimal characters) or a current member's email. " +
|
|
19
|
+
'`skrr workspaces members <workspace-id>` lists them; `skrr whoami` prints your own',
|
|
18
20
|
}),
|
|
19
21
|
};
|
|
20
22
|
static flags = {
|
|
@@ -23,8 +25,18 @@ class WorkspacesStewardship extends base_command_1.BaseCommand {
|
|
|
23
25
|
async run() {
|
|
24
26
|
this.requireAuth();
|
|
25
27
|
const { args, flags } = await this.parse(WorkspacesStewardship);
|
|
28
|
+
let userId;
|
|
26
29
|
try {
|
|
27
|
-
|
|
30
|
+
userId = await (0, workspaces_1.resolveMemberUserId)(args.workspaceId, args.userId);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (error instanceof workspaces_1.MemberReferenceError)
|
|
34
|
+
this.error(error.message, { exit: 1 });
|
|
35
|
+
this.handleApiError(error);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const report = await (0, workspaces_1.getWorkspaceStewardship)(args.workspaceId, userId);
|
|
28
40
|
if (flags.json)
|
|
29
41
|
this.log(JSON.stringify(report, null, 2));
|
|
30
42
|
else
|
package/dist/help.js
CHANGED
|
@@ -61,6 +61,18 @@ class SkrrHelp extends core_1.Help {
|
|
|
61
61
|
// so it must fall through — only an id that is neither a command nor a
|
|
62
62
|
// topic is a miss.
|
|
63
63
|
if (id && !this.config.findCommand(id) && !this.config.findTopic(id)) {
|
|
64
|
+
// `skrr tasks get --help` is asked about the command `skrr tasks get` runs
|
|
65
|
+
// as: the same synonym the hook resolves when it is run (OSK-16434).
|
|
66
|
+
const flagStart = argv.findIndex((token) => token.startsWith('-'));
|
|
67
|
+
const words = flagStart === -1 ? argv : argv.slice(0, flagStart);
|
|
68
|
+
const synonym = (0, command_miss_1.resolveVerbSynonym)(lookup, words);
|
|
69
|
+
if (synonym) {
|
|
70
|
+
return super.showHelp([
|
|
71
|
+
...synonym.id.split(':'),
|
|
72
|
+
...synonym.rest,
|
|
73
|
+
...(flagStart === -1 ? [] : argv.slice(flagStart)),
|
|
74
|
+
]);
|
|
75
|
+
}
|
|
64
76
|
throw new Error((0, command_miss_1.describeCommandMiss)(lookup, id));
|
|
65
77
|
}
|
|
66
78
|
return super.showHelp(argv);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
3
4
|
const command_manifest_1 = require("../lib/command-manifest");
|
|
4
5
|
const usage_discovery_1 = require("../lib/usage-discovery");
|
|
5
6
|
const command_miss_1 = require("../lib/command-miss");
|
|
7
|
+
const json_mode_1 = require("../lib/json-mode");
|
|
6
8
|
/**
|
|
7
9
|
* Turn "command not found" back into the truth when the command DOES exist.
|
|
8
10
|
*
|
|
@@ -65,6 +67,30 @@ const hook = async function (opts) {
|
|
|
65
67
|
throw err;
|
|
66
68
|
}
|
|
67
69
|
}
|
|
70
|
+
const lookup = (0, command_miss_1.lookupFromConfig)(this.config);
|
|
71
|
+
const rawArgv = process.argv.slice(2);
|
|
72
|
+
const words = (0, command_miss_1.typedCommandWords)(id, rawArgv);
|
|
73
|
+
// A read verb spelled the other way (`tasks get`, `machines ls`) means the
|
|
74
|
+
// command that exists. Run it rather than refuse: refusing sent a reader to a
|
|
75
|
+
// suggestion list that did not contain the command they meant (OSK-16434).
|
|
76
|
+
// Only `list`/`ls` and `show`/`get`, only when the typed spelling is not a
|
|
77
|
+
// command of that topic, and only when the other one is.
|
|
78
|
+
const synonym = (0, command_miss_1.resolveVerbSynonym)(lookup, words);
|
|
79
|
+
if (synonym) {
|
|
80
|
+
// Said to a person, never to a pipe: a script gets its output undisturbed.
|
|
81
|
+
if (process.stderr.isTTY && !(0, json_mode_1.wantsJsonFromArgv)(rawArgv)) {
|
|
82
|
+
process.stderr.write(`\`${synonym.typed}\` is \`${synonym.resolved}\`.\n`);
|
|
83
|
+
}
|
|
84
|
+
return this.config.runCommand(synonym.id, [...synonym.rest, ...(opts.argv ?? [])]);
|
|
85
|
+
}
|
|
86
|
+
// `--json` asked for a document. A miss is a refusal like any other, and every
|
|
87
|
+
// other refusal prints `{ok:false, error}`; this one printed prose, so the
|
|
88
|
+
// pipe into `jq` failed on the prose and hid the refusal (OSK-16434). Exit
|
|
89
|
+
// status 1, as before.
|
|
90
|
+
if ((0, json_mode_1.wantsJsonFromArgv)([...rawArgv, ...(opts.argv ?? [])])) {
|
|
91
|
+
process.stdout.write(`${JSON.stringify((0, command_miss_1.commandMissEnvelope)(lookup, id, words), null, 2)}\n`);
|
|
92
|
+
core_1.Errors.exit(1);
|
|
93
|
+
}
|
|
68
94
|
// The message itself lives in `lib/command-miss`, shared with the help
|
|
69
95
|
// class — `skrr daemon reload` reaches this hook and `skrr daemon reload
|
|
70
96
|
// --help` does not, so the two surfaces have to read from one description or
|
|
@@ -76,7 +102,7 @@ const hook = async function (opts) {
|
|
|
76
102
|
// — a typo would silently look like success, which is far worse than the
|
|
77
103
|
// message this hook was written to improve. (I shipped exactly that for one
|
|
78
104
|
// build; `skrr shortcuts lst` said nothing and exited 0.)
|
|
79
|
-
throw new Error((0, command_miss_1.describeCommandMiss)(
|
|
105
|
+
throw new Error((0, command_miss_1.describeCommandMiss)(lookup, id));
|
|
80
106
|
};
|
|
81
107
|
exports.default = hook;
|
|
82
108
|
class VirtualUsageFlagError extends Error {
|