@skrr-ai/cli 0.1.36 → 0.1.38
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 +17 -4
- package/bin/dev-fallback.js +167 -4
- package/dist/base-command.js +46 -2
- package/dist/commands/agents/actions/create.d.ts +5 -0
- package/dist/commands/agents/actions/create.js +42 -5
- package/dist/commands/agents/actions/delete.d.ts +1 -0
- package/dist/commands/agents/actions/delete.js +7 -0
- package/dist/commands/agents/actions/update.d.ts +5 -0
- package/dist/commands/agents/actions/update.js +27 -1
- package/dist/commands/agents/api-actions/add.d.ts +41 -0
- package/dist/commands/agents/api-actions/add.js +205 -0
- package/dist/commands/agents/api-actions/index.d.ts +39 -0
- package/dist/commands/agents/api-actions/index.js +103 -0
- package/dist/commands/agents/api-actions/remove.d.ts +14 -0
- package/dist/commands/agents/api-actions/remove.js +36 -0
- package/dist/commands/agents/avatar/default/apply.d.ts +25 -0
- package/dist/commands/agents/avatar/default/apply.js +56 -0
- package/dist/commands/agents/avatar/default/index.d.ts +29 -0
- package/dist/commands/agents/avatar/default/index.js +61 -0
- package/dist/commands/agents/avatar/default/set.d.ts +24 -0
- package/dist/commands/agents/avatar/default/set.js +120 -0
- package/dist/commands/agents/avatar/library/delete.d.ts +20 -0
- package/dist/commands/agents/avatar/library/delete.js +47 -0
- package/dist/commands/agents/avatar/library/index.d.ts +16 -0
- package/dist/commands/agents/avatar/library/index.js +56 -0
- package/dist/commands/agents/avatar/presets.d.ts +19 -0
- package/dist/commands/agents/avatar/presets.js +56 -0
- package/dist/commands/agents/avatar/upload.js +7 -1
- package/dist/commands/agents/categories/create.d.ts +14 -0
- package/dist/commands/agents/categories/create.js +46 -0
- package/dist/commands/agents/categories/delete.d.ts +13 -0
- package/dist/commands/agents/categories/delete.js +41 -0
- package/dist/commands/agents/categories/index.d.ts +36 -0
- package/dist/commands/agents/categories/index.js +135 -0
- package/dist/commands/agents/categories/update.d.ts +22 -0
- package/dist/commands/agents/categories/update.js +59 -0
- package/dist/commands/agents/chat.d.ts +21 -0
- package/dist/commands/agents/chat.js +94 -7
- package/dist/commands/agents/create.d.ts +10 -0
- package/dist/commands/agents/create.js +64 -3
- package/dist/commands/agents/ensure-default.d.ts +27 -0
- package/dist/commands/agents/ensure-default.js +65 -0
- package/dist/commands/agents/list.d.ts +15 -0
- package/dist/commands/agents/list.js +31 -1
- package/dist/commands/agents/mute.d.ts +16 -0
- package/dist/commands/agents/mute.js +38 -0
- package/dist/commands/agents/pin.d.ts +16 -0
- package/dist/commands/agents/pin.js +38 -0
- package/dist/commands/agents/scene-background/upload.d.ts +30 -0
- package/dist/commands/agents/scene-background/upload.js +97 -0
- package/dist/commands/agents/show.js +13 -0
- package/dist/commands/agents/tools/auth.d.ts +19 -0
- package/dist/commands/agents/tools/auth.js +41 -0
- package/dist/commands/agents/tools/calls.d.ts +36 -0
- package/dist/commands/agents/tools/calls.js +117 -0
- package/dist/commands/agents/tools/index.d.ts +20 -0
- package/dist/commands/agents/tools/index.js +77 -0
- package/dist/commands/agents/unmute.d.ts +16 -0
- package/dist/commands/agents/unmute.js +38 -0
- package/dist/commands/agents/unpin.d.ts +16 -0
- package/dist/commands/agents/unpin.js +38 -0
- package/dist/commands/agents/update.d.ts +12 -0
- package/dist/commands/agents/update.js +74 -3
- package/dist/commands/code/{oversky-agent.d.ts → skrr-agent.d.ts} +3 -3
- package/dist/commands/code/{oversky-agent.js → skrr-agent.js} +11 -8
- package/dist/commands/convos/messages.d.ts +13 -0
- package/dist/commands/convos/messages.js +40 -16
- package/dist/commands/daemon/index.js +8 -1
- package/dist/commands/daemon/logs.d.ts +26 -0
- package/dist/commands/daemon/logs.js +56 -0
- package/dist/commands/daemon/uninstall.js +1 -1
- package/dist/commands/followups/act.d.ts +22 -0
- package/dist/commands/followups/act.js +103 -0
- package/dist/commands/followups/cancel.d.ts +20 -0
- package/dist/commands/followups/cancel.js +50 -0
- package/dist/commands/followups/checkin.d.ts +27 -0
- package/dist/commands/followups/checkin.js +107 -0
- package/dist/commands/followups/list.d.ts +24 -0
- package/dist/commands/followups/list.js +90 -0
- package/dist/commands/followups/observability.d.ts +23 -0
- package/dist/commands/followups/observability.js +114 -0
- package/dist/commands/followups/remind.d.ts +26 -0
- package/dist/commands/followups/remind.js +106 -0
- package/dist/commands/followups/reschedule.d.ts +15 -0
- package/dist/commands/followups/reschedule.js +48 -0
- package/dist/commands/followups/resolve.d.ts +23 -0
- package/dist/commands/followups/resolve.js +54 -0
- package/dist/commands/followups/show.d.ts +12 -0
- package/dist/commands/followups/show.js +46 -0
- package/dist/commands/followups/watch.d.ts +51 -0
- package/dist/commands/followups/watch.js +211 -0
- package/dist/commands/goals/labels/add.js +19 -2
- package/dist/commands/goals/labels/remove.js +22 -2
- package/dist/commands/harnesses/forget.js +28 -0
- package/dist/commands/harnesses/install.d.ts +41 -0
- package/dist/commands/harnesses/install.js +165 -0
- package/dist/commands/harnesses/installers.d.ts +45 -0
- package/dist/commands/harnesses/installers.js +155 -0
- package/dist/commands/harnesses/list.d.ts +82 -1
- package/dist/commands/harnesses/list.js +104 -12
- package/dist/commands/harnesses/models.js +10 -1
- package/dist/commands/harnesses/show.d.ts +15 -0
- package/dist/commands/harnesses/show.js +44 -3
- package/dist/commands/harnesses/update.js +1 -1
- package/dist/commands/harnesses/usage.d.ts +25 -0
- package/dist/commands/harnesses/usage.js +24 -2
- package/dist/commands/instructions/status.js +13 -1
- package/dist/commands/labels/list.d.ts +24 -1
- package/dist/commands/labels/list.js +62 -19
- package/dist/commands/machines/dedicated/catalog.js +4 -15
- package/dist/commands/machines/dedicated/create.d.ts +8 -0
- package/dist/commands/machines/dedicated/create.js +58 -1
- package/dist/commands/machines/dedicated/destroy.js +18 -4
- package/dist/commands/machines/dedicated/list.js +9 -6
- package/dist/commands/machines/hosted/list.js +12 -0
- package/dist/commands/machines/list.js +11 -0
- package/dist/commands/machines/show.d.ts +1 -0
- package/dist/commands/machines/show.js +40 -11
- package/dist/commands/memory/governance/index.d.ts +21 -0
- package/dist/commands/memory/governance/index.js +64 -0
- package/dist/commands/memory/governance/set.d.ts +24 -0
- package/dist/commands/memory/governance/set.js +95 -0
- package/dist/commands/memory/provenance.d.ts +18 -0
- package/dist/commands/memory/provenance.js +66 -0
- package/dist/commands/profiles/list.d.ts +23 -0
- package/dist/commands/profiles/list.js +96 -0
- package/dist/commands/search/skills.d.ts +11 -1
- package/dist/commands/search/skills.js +26 -8
- package/dist/commands/skills/details.d.ts +2 -0
- package/dist/commands/skills/details.js +24 -1
- package/dist/commands/skills/import-as-actions.d.ts +32 -0
- package/dist/commands/skills/import-as-actions.js +175 -0
- package/dist/commands/skills/install.d.ts +2 -0
- package/dist/commands/skills/install.js +24 -1
- package/dist/commands/skills/invocable.js +6 -2
- package/dist/commands/skills/local.d.ts +40 -0
- package/dist/commands/skills/local.js +160 -0
- package/dist/commands/skills/search.d.ts +11 -1
- package/dist/commands/skills/search.js +29 -8
- package/dist/commands/spaces/actions/add.js +23 -5
- package/dist/commands/spaces/actions/available.js +3 -0
- package/dist/commands/spaces/actions/list.d.ts +5 -0
- package/dist/commands/spaces/actions/list.js +49 -3
- package/dist/commands/spaces/actions/run.d.ts +28 -0
- package/dist/commands/spaces/actions/run.js +146 -0
- package/dist/commands/spaces/actions/update.js +27 -5
- package/dist/commands/spaces/create.d.ts +3 -0
- package/dist/commands/spaces/create.js +32 -2
- package/dist/commands/spaces/label-summaries.d.ts +27 -0
- package/dist/commands/spaces/label-summaries.js +64 -0
- package/dist/commands/spaces/labels/add.js +19 -2
- package/dist/commands/spaces/labels/remove.js +22 -2
- package/dist/commands/spaces/show.js +2 -0
- package/dist/commands/spaces/task-rollups.d.ts +5 -0
- package/dist/commands/spaces/task-rollups.js +15 -4
- package/dist/commands/spaces/update.d.ts +5 -0
- package/dist/commands/spaces/update.js +41 -4
- package/dist/commands/spaces/workflows/lifecycle-diagnostics.d.ts +11 -0
- package/dist/commands/spaces/workflows/lifecycle-diagnostics.js +105 -0
- package/dist/commands/tasks/actions/attach.js +32 -7
- package/dist/commands/tasks/complete.d.ts +1 -0
- package/dist/commands/tasks/complete.js +21 -1
- package/dist/commands/tasks/create.d.ts +3 -0
- package/dist/commands/tasks/create.js +34 -2
- package/dist/commands/tasks/events/append.js +29 -6
- package/dist/commands/tasks/expectations/assess.d.ts +12 -0
- package/dist/commands/tasks/expectations/assess.js +123 -14
- package/dist/commands/tasks/expectations.js +95 -17
- package/dist/commands/tasks/follow-up.js +2 -2
- package/dist/commands/tasks/labels/attach.js +20 -3
- package/dist/commands/tasks/labels/detach.js +21 -3
- package/dist/commands/tasks/lifecycle/attach.d.ts +14 -0
- package/dist/commands/tasks/lifecycle/attach.js +47 -0
- package/dist/commands/tasks/lifecycle/definitions.d.ts +11 -0
- package/dist/commands/tasks/lifecycle/definitions.js +59 -0
- package/dist/commands/tasks/lifecycle/detach.d.ts +19 -0
- package/dist/commands/tasks/lifecycle/detach.js +72 -0
- package/dist/commands/tasks/lifecycle/history.d.ts +13 -0
- package/dist/commands/tasks/lifecycle/history.js +38 -0
- package/dist/commands/tasks/lifecycle/migrate.d.ts +14 -0
- package/dist/commands/tasks/lifecycle/migrate.js +68 -0
- package/dist/commands/tasks/lifecycle/reconcile.d.ts +11 -0
- package/dist/commands/tasks/lifecycle/reconcile.js +27 -0
- package/dist/commands/tasks/lifecycle/reopen.d.ts +15 -0
- package/dist/commands/tasks/lifecycle/reopen.js +71 -0
- package/dist/commands/tasks/lifecycle/show.d.ts +11 -0
- package/dist/commands/tasks/lifecycle/show.js +27 -0
- package/dist/commands/tasks/lifecycle/start.d.ts +12 -0
- package/dist/commands/tasks/lifecycle/start.js +30 -0
- package/dist/commands/tasks/lifecycle/transition.d.ts +15 -0
- package/dist/commands/tasks/lifecycle/transition.js +109 -0
- package/dist/commands/tasks/list.js +16 -9
- package/dist/commands/tasks/move.d.ts +1 -0
- package/dist/commands/tasks/move.js +29 -0
- package/dist/commands/tasks/result/submit.js +11 -1
- package/dist/commands/tasks/review-queue.d.ts +44 -0
- package/dist/commands/tasks/review-queue.js +314 -0
- package/dist/commands/tasks/show.d.ts +11 -0
- package/dist/commands/tasks/show.js +139 -4
- package/dist/commands/tasks/trust.js +7 -2
- package/dist/commands/tasks/update.d.ts +1 -0
- package/dist/commands/tasks/update.js +83 -0
- package/dist/commands/tasks/updates/add.js +1 -1
- package/dist/commands/token/list.d.ts +22 -0
- package/dist/commands/token/list.js +68 -0
- package/dist/commands/token/revoke.d.ts +23 -0
- package/dist/commands/token/revoke.js +53 -0
- package/dist/lib/agent-actions.d.ts +92 -11
- package/dist/lib/agent-actions.js +171 -25
- package/dist/lib/agent-config.d.ts +11 -0
- package/dist/lib/agent-config.js +85 -3
- package/dist/lib/agent-pin-mute.d.ts +29 -0
- package/dist/lib/agent-pin-mute.js +30 -0
- package/dist/lib/agent-visual-refs.d.ts +33 -0
- package/dist/lib/agent-visual-refs.js +267 -0
- package/dist/lib/agentic-stream.d.ts +6 -0
- package/dist/lib/agentic-stream.js +34 -3
- package/dist/lib/assignee-resolver.d.ts +1 -1
- package/dist/lib/assignee-resolver.js +8 -0
- package/dist/lib/bulk-task-targets.d.ts +12 -0
- package/dist/lib/bulk-task-targets.js +34 -1
- package/dist/lib/cli-installers.d.ts +130 -0
- package/dist/lib/cli-installers.js +145 -0
- package/dist/lib/command-miss.js +55 -7
- package/dist/lib/dedicated-lease-command.d.ts +13 -0
- package/dist/lib/dedicated-lease-command.js +22 -1
- package/dist/lib/dedicated-machines.d.ts +95 -1
- package/dist/lib/dedicated-machines.js +236 -2
- package/dist/lib/failed-lookup.d.ts +3 -0
- package/dist/lib/failed-lookup.js +40 -0
- package/dist/lib/first-party-harness-agent.js +16 -2
- package/dist/lib/first-party-harness-doctor.d.ts +15 -0
- package/dist/lib/first-party-harness-doctor.js +126 -27
- package/dist/lib/followups.d.ts +115 -0
- package/dist/lib/followups.js +127 -0
- package/dist/lib/harnesses.d.ts +8 -0
- package/dist/lib/instruction-input.d.ts +19 -1
- package/dist/lib/instruction-input.js +52 -1
- package/dist/lib/label-ref.d.ts +95 -0
- package/dist/lib/label-ref.js +163 -0
- package/dist/lib/label-scope.d.ts +17 -2
- package/dist/lib/label-scope.js +27 -7
- package/dist/lib/local-skills.d.ts +98 -0
- package/dist/lib/local-skills.js +195 -0
- package/dist/lib/machines.d.ts +10 -10
- package/dist/lib/machines.js +23 -1
- package/dist/lib/search-query.d.ts +19 -0
- package/dist/lib/search-query.js +35 -0
- package/dist/lib/space-custom-actions.d.ts +72 -0
- package/dist/lib/space-custom-actions.js +117 -0
- package/dist/lib/space-resolver.d.ts +1 -21
- package/dist/lib/space-resolver.js +19 -10
- package/dist/lib/task-closure.d.ts +33 -0
- package/dist/lib/task-closure.js +104 -0
- package/dist/lib/task-lifecycle-output.d.ts +14 -0
- package/dist/lib/task-lifecycle-output.js +209 -0
- package/dist/lib/task-ref-resolver.d.ts +1 -17
- package/dist/lib/task-ref-resolver.js +18 -8
- package/dist/lib/tasks.d.ts +3 -0
- package/dist/lib/tasks.js +40 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +4 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +5559 -4897
- package/oclif.manifest.json +33890 -28690
- package/package.json +24 -6
|
@@ -0,0 +1,50 @@
|
|
|
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 followups_1 = require("../../lib/followups");
|
|
6
|
+
/**
|
|
7
|
+
* `skrr followups cancel <id>` — "never mind". It records exactly what
|
|
8
|
+
* `resolve --outcome abandoned` records (terminal `abandoned`, the reason as
|
|
9
|
+
* the note); it exists so calling one off does not require knowing the
|
|
10
|
+
* terminal vocabulary. Neither help text used to say so, and a user had to
|
|
11
|
+
* read the service to choose between them (OSK-9679).
|
|
12
|
+
*/
|
|
13
|
+
class FollowupsCancel extends base_command_1.BaseCommand {
|
|
14
|
+
static description = 'Call off a follow-up you no longer want (same record as resolve --outcome abandoned)';
|
|
15
|
+
static examples = [
|
|
16
|
+
'<%= config.bin %> followups cancel fu_abc',
|
|
17
|
+
'<%= config.bin %> followups cancel fu_abc --reason "handled it by hand"',
|
|
18
|
+
'# If what you were waiting for happened, record that instead:',
|
|
19
|
+
'<%= config.bin %> followups resolve fu_abc --outcome resolved',
|
|
20
|
+
];
|
|
21
|
+
static args = {
|
|
22
|
+
id: followups_1.followUpIdArg,
|
|
23
|
+
};
|
|
24
|
+
static flags = {
|
|
25
|
+
reason: core_1.Flags.string({
|
|
26
|
+
description: 'Why it is being called off — stored as the note (default: "cancelled")',
|
|
27
|
+
}),
|
|
28
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
29
|
+
};
|
|
30
|
+
async run() {
|
|
31
|
+
this.requireAuth();
|
|
32
|
+
const { args, flags } = await this.parse(FollowupsCancel);
|
|
33
|
+
let result;
|
|
34
|
+
try {
|
|
35
|
+
result = (await followups_1.followupsApi.cancel(args.id, {
|
|
36
|
+
...(flags.reason ? { reason: flags.reason } : {}),
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
this.handleApiError(err);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (flags.json) {
|
|
44
|
+
this.log(JSON.stringify(result, null, 2));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
this.log(`Follow-up ${args.id} cancelled.`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.default = FollowupsCancel;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr followups checkin` — a `checkin` follow-up: the agent decides to come
|
|
4
|
+
* back later. `--in` arms the `once` form (the agent's pick); `--frequency`
|
|
5
|
+
* arms `recurring` (a cadence the user picked).
|
|
6
|
+
*
|
|
7
|
+
* This is permission AND restraint: a check-in may stay silent on wake when
|
|
8
|
+
* there is nothing worth saying — silence is the designed outcome, not a
|
|
9
|
+
* failure.
|
|
10
|
+
*/
|
|
11
|
+
export default class FollowupsCheckin extends BaseCommand {
|
|
12
|
+
static description: string;
|
|
13
|
+
static examples: string[];
|
|
14
|
+
static flags: {
|
|
15
|
+
subject: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
|
+
why: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
17
|
+
in: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
|
+
frequency: 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
|
+
agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
+
endpoint: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
|
+
'endpoint-target': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
|
+
pin: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
};
|
|
26
|
+
run(): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
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 followups_1 = require("../../lib/followups");
|
|
6
|
+
const agent_resolver_1 = require("../../lib/agent-resolver");
|
|
7
|
+
/**
|
|
8
|
+
* `skrr followups checkin` — a `checkin` follow-up: the agent decides to come
|
|
9
|
+
* back later. `--in` arms the `once` form (the agent's pick); `--frequency`
|
|
10
|
+
* arms `recurring` (a cadence the user picked).
|
|
11
|
+
*
|
|
12
|
+
* This is permission AND restraint: a check-in may stay silent on wake when
|
|
13
|
+
* there is nothing worth saying — silence is the designed outcome, not a
|
|
14
|
+
* failure.
|
|
15
|
+
*/
|
|
16
|
+
class FollowupsCheckin extends base_command_1.BaseCommand {
|
|
17
|
+
static description = 'Come back to this later — the check-in follow-up';
|
|
18
|
+
static examples = [
|
|
19
|
+
'<%= config.bin %> followups checkin --subject conversation:conv_9 --why "waiting on their answer about the move" --in 90m',
|
|
20
|
+
'<%= config.bin %> followups checkin --subject task:OSK-42 --why "weekly touch-base" --frequency "0 9 * * MON" --timezone America/New_York',
|
|
21
|
+
];
|
|
22
|
+
static flags = {
|
|
23
|
+
subject: core_1.Flags.string({ description: 'Subject ref: type:externalKey', required: true }),
|
|
24
|
+
why: core_1.Flags.string({ description: 'Why this wake exists, in one line', required: true }),
|
|
25
|
+
in: core_1.Flags.string({
|
|
26
|
+
description: 'Duration from now (90m, 2h) — the once form',
|
|
27
|
+
exclusive: ['frequency'],
|
|
28
|
+
}),
|
|
29
|
+
frequency: core_1.Flags.string({
|
|
30
|
+
description: 'Cron cadence — the recurring form (user-picked)',
|
|
31
|
+
exclusive: ['in'],
|
|
32
|
+
}),
|
|
33
|
+
timezone: core_1.Flags.string({
|
|
34
|
+
description: 'IANA timezone for --frequency',
|
|
35
|
+
dependsOn: ['frequency'],
|
|
36
|
+
}),
|
|
37
|
+
agent: core_1.Flags.string({ description: 'Agent ID (default: bound session agent)' }),
|
|
38
|
+
endpoint: core_1.Flags.string({ description: 'Delivery endpoint id (EndpointRegistry)' }),
|
|
39
|
+
'endpoint-target': core_1.Flags.string({ description: 'Channel target for channel endpoints' }),
|
|
40
|
+
pin: core_1.Flags.string({ description: 'Conversation id the check-in was authored in' }),
|
|
41
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
42
|
+
};
|
|
43
|
+
async run() {
|
|
44
|
+
this.requireAuth();
|
|
45
|
+
const { flags } = await this.parse(FollowupsCheckin);
|
|
46
|
+
if (!flags.in && !flags.frequency) {
|
|
47
|
+
this.failWithCliError({
|
|
48
|
+
message: 'Either --in <duration> or --frequency <cron> is required.',
|
|
49
|
+
code: 'FOLLOWUP_KIND_FIELD_MISSING',
|
|
50
|
+
exit: 2,
|
|
51
|
+
retryable: false,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
let agent;
|
|
55
|
+
try {
|
|
56
|
+
agent = (0, followups_1.resolveFollowUpAgent)(flags.agent);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
const failure = (0, agent_resolver_1.agentResolutionFailure)(err);
|
|
60
|
+
this.failWithCliError({
|
|
61
|
+
message: failure.message,
|
|
62
|
+
code: failure.code,
|
|
63
|
+
exit: 2,
|
|
64
|
+
retryable: false,
|
|
65
|
+
details: { suggestion: failure.suggestion, context: failure.details },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
let response;
|
|
69
|
+
try {
|
|
70
|
+
response = await followups_1.followupsApi.create({
|
|
71
|
+
kind: 'checkin',
|
|
72
|
+
producer: agent.boundToSession ? 'agent_in_turn' : 'user_explicit',
|
|
73
|
+
agentId: agent.id,
|
|
74
|
+
subject: (0, followups_1.parseSubjectRef)(flags.subject),
|
|
75
|
+
why: flags.why,
|
|
76
|
+
...(flags.in ? { form: 'once', in: flags.in } : {}),
|
|
77
|
+
...(flags.frequency
|
|
78
|
+
? { form: 'recurring', frequency: flags.frequency, timezone: flags.timezone }
|
|
79
|
+
: {}),
|
|
80
|
+
...(flags.endpoint ? { endpointId: flags.endpoint } : {}),
|
|
81
|
+
...(flags['endpoint-target'] ? { endpointTarget: flags['endpoint-target'] } : {}),
|
|
82
|
+
...(flags.pin ? { pinnedConversationId: flags.pin } : {}),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
this.handleApiError(err);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (flags.json) {
|
|
90
|
+
this.log(JSON.stringify(response, null, 2));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const row = response.followup;
|
|
94
|
+
if (response.reused) {
|
|
95
|
+
this.log(`Already armed: ${row?.id} — one pending check-in per conversation, and this is it.`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (response.dropped) {
|
|
99
|
+
// silent_drop is the check-in budget's contract: the answer to "one
|
|
100
|
+
// greeting too many" is quiet, not an error the caller can retry.
|
|
101
|
+
this.log('Dropped by the daily check-in budget — staying quiet is the correct outcome.');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.log(`Check-in armed: ${row?.id} at ${row?.nextRunAt ?? flags.in ?? flags.frequency}.`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.default = FollowupsCheckin;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr followups list` — what is still owed, one row per follow-up across
|
|
4
|
+
* all four kinds.
|
|
5
|
+
*
|
|
6
|
+
* Default scope is ONE agent (the session's, or `--agent`) — "what do I still
|
|
7
|
+
* owe" is the question an agent asks. `--all-agents` is the human's view and
|
|
8
|
+
* is opt-in, so an agent cannot accidentally read another agent's
|
|
9
|
+
* obligations and start reasoning about them.
|
|
10
|
+
*/
|
|
11
|
+
export default class FollowupsList extends BaseCommand {
|
|
12
|
+
static description: string;
|
|
13
|
+
static examples: string[];
|
|
14
|
+
static flags: {
|
|
15
|
+
agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
|
+
'all-agents': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
17
|
+
kind: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
|
+
subject: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
+
state: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
+
limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
22
|
+
};
|
|
23
|
+
run(): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
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 followups_1 = require("../../lib/followups");
|
|
6
|
+
const agent_resolver_1 = require("../../lib/agent-resolver");
|
|
7
|
+
/**
|
|
8
|
+
* `skrr followups list` — what is still owed, one row per follow-up across
|
|
9
|
+
* all four kinds.
|
|
10
|
+
*
|
|
11
|
+
* Default scope is ONE agent (the session's, or `--agent`) — "what do I still
|
|
12
|
+
* owe" is the question an agent asks. `--all-agents` is the human's view and
|
|
13
|
+
* is opt-in, so an agent cannot accidentally read another agent's
|
|
14
|
+
* obligations and start reasoning about them.
|
|
15
|
+
*/
|
|
16
|
+
class FollowupsList extends base_command_1.BaseCommand {
|
|
17
|
+
static description = 'List follow-ups — armed, proposed, paused, or settled';
|
|
18
|
+
static examples = [
|
|
19
|
+
'<%= config.bin %> followups list',
|
|
20
|
+
'<%= config.bin %> followups list --agent agent_1 --kind watch --state armed',
|
|
21
|
+
'<%= config.bin %> followups list --all-agents --kind checkin',
|
|
22
|
+
'<%= config.bin %> followups list --subject task:OSK-42 --json',
|
|
23
|
+
];
|
|
24
|
+
static flags = {
|
|
25
|
+
agent: core_1.Flags.string({
|
|
26
|
+
description: 'Agent ID (default: bound session agent)',
|
|
27
|
+
exclusive: ['all-agents'],
|
|
28
|
+
}),
|
|
29
|
+
'all-agents': core_1.Flags.boolean({
|
|
30
|
+
description: 'List across every agent — the human view',
|
|
31
|
+
exclusive: ['agent'],
|
|
32
|
+
default: false,
|
|
33
|
+
}),
|
|
34
|
+
kind: core_1.Flags.string({ description: 'Filter by kind', options: [...followups_1.FOLLOWUP_KINDS] }),
|
|
35
|
+
subject: core_1.Flags.string({ description: 'Filter by subject ref: type:externalKey' }),
|
|
36
|
+
state: core_1.Flags.string({ description: 'Filter by state', options: [...followups_1.FOLLOWUP_STATES] }),
|
|
37
|
+
limit: core_1.Flags.integer({ description: 'Max results (1..500)', min: 1, max: 500 }),
|
|
38
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
39
|
+
};
|
|
40
|
+
async run() {
|
|
41
|
+
this.requireAuth();
|
|
42
|
+
const { flags } = await this.parse(FollowupsList);
|
|
43
|
+
let agentId;
|
|
44
|
+
if (!flags['all-agents']) {
|
|
45
|
+
try {
|
|
46
|
+
agentId = (0, followups_1.resolveFollowUpAgent)(flags.agent).id;
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
const failure = (0, agent_resolver_1.agentResolutionFailure)(err);
|
|
50
|
+
this.failWithCliError({
|
|
51
|
+
message: failure.message,
|
|
52
|
+
code: failure.code,
|
|
53
|
+
exit: 2,
|
|
54
|
+
retryable: false,
|
|
55
|
+
details: { suggestion: failure.suggestion, context: failure.details },
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
let response;
|
|
60
|
+
try {
|
|
61
|
+
response = await followups_1.followupsApi.list({
|
|
62
|
+
...(agentId ? { agentId } : {}),
|
|
63
|
+
...(flags['all-agents'] ? { allAgents: true } : {}),
|
|
64
|
+
...(flags.kind ? { kind: flags.kind } : {}),
|
|
65
|
+
...(flags.subject ? { subject: flags.subject } : {}),
|
|
66
|
+
...(flags.state ? { state: flags.state } : {}),
|
|
67
|
+
...(flags.limit ? { limit: flags.limit } : {}),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
this.handleApiError(err);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (flags.json) {
|
|
75
|
+
this.log(JSON.stringify(response, null, 2));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const rows = response.followups ?? [];
|
|
79
|
+
if (rows.length === 0) {
|
|
80
|
+
this.log('No follow-ups.');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
for (const row of rows) {
|
|
84
|
+
this.log((0, followups_1.followupSummaryLine)(row));
|
|
85
|
+
if (row.why)
|
|
86
|
+
this.log(` why: ${row.why}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.default = FollowupsList;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr followups observability` — how follow-ups are doing, per (agent, kind).
|
|
4
|
+
*
|
|
5
|
+
* `list` answers "what is still owed", one row per follow-up. This answers the
|
|
6
|
+
* question a page of rows cannot: how many were created, how they ended, how
|
|
7
|
+
* often they escalated, today's budget, and how often a check-in chose to stay
|
|
8
|
+
* quiet. The API served this rollup from the day the service shipped and no
|
|
9
|
+
* command reached it (OSK-9678).
|
|
10
|
+
*
|
|
11
|
+
* Scope follows `list`: one agent by default (the session's, or `--agent`),
|
|
12
|
+
* every agent only with `--all-agents`.
|
|
13
|
+
*/
|
|
14
|
+
export default class FollowupsObservability extends BaseCommand {
|
|
15
|
+
static description: string;
|
|
16
|
+
static examples: string[];
|
|
17
|
+
static flags: {
|
|
18
|
+
agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
+
'all-agents': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
20
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
};
|
|
22
|
+
run(): Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
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 followups_1 = require("../../lib/followups");
|
|
7
|
+
const agent_resolver_1 = require("../../lib/agent-resolver");
|
|
8
|
+
const rate = (value) => value === null ? '—' : `${Math.round(value * 100)}%`;
|
|
9
|
+
/** `resolved 3 · abandoned 1` — the outcomes that happened, not five zeros. */
|
|
10
|
+
const outcomes = (terminal) => Object.entries(terminal)
|
|
11
|
+
.filter(([, count]) => count > 0)
|
|
12
|
+
.map(([outcome, count]) => `${outcome} ${count}`)
|
|
13
|
+
.join(' · ') || '—';
|
|
14
|
+
/**
|
|
15
|
+
* `skrr followups observability` — how follow-ups are doing, per (agent, kind).
|
|
16
|
+
*
|
|
17
|
+
* `list` answers "what is still owed", one row per follow-up. This answers the
|
|
18
|
+
* question a page of rows cannot: how many were created, how they ended, how
|
|
19
|
+
* often they escalated, today's budget, and how often a check-in chose to stay
|
|
20
|
+
* quiet. The API served this rollup from the day the service shipped and no
|
|
21
|
+
* command reached it (OSK-9678).
|
|
22
|
+
*
|
|
23
|
+
* Scope follows `list`: one agent by default (the session's, or `--agent`),
|
|
24
|
+
* every agent only with `--all-agents`.
|
|
25
|
+
*/
|
|
26
|
+
class FollowupsObservability extends base_command_1.BaseCommand {
|
|
27
|
+
static description = 'Per-agent, per-kind rollup — created, outcomes, escalation, budget, check-in silence';
|
|
28
|
+
static examples = [
|
|
29
|
+
'<%= config.bin %> followups observability',
|
|
30
|
+
'<%= config.bin %> followups observability --agent agent_1',
|
|
31
|
+
'<%= config.bin %> followups observability --all-agents --json',
|
|
32
|
+
];
|
|
33
|
+
static flags = {
|
|
34
|
+
agent: core_1.Flags.string({
|
|
35
|
+
description: 'Agent ID (default: bound session agent)',
|
|
36
|
+
exclusive: ['all-agents'],
|
|
37
|
+
}),
|
|
38
|
+
'all-agents': core_1.Flags.boolean({
|
|
39
|
+
description: 'Roll up every agent — the human view',
|
|
40
|
+
exclusive: ['agent'],
|
|
41
|
+
default: false,
|
|
42
|
+
}),
|
|
43
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
44
|
+
};
|
|
45
|
+
async run() {
|
|
46
|
+
this.requireAuth();
|
|
47
|
+
const { flags } = await this.parse(FollowupsObservability);
|
|
48
|
+
let agentId;
|
|
49
|
+
if (!flags['all-agents']) {
|
|
50
|
+
try {
|
|
51
|
+
agentId = (0, followups_1.resolveFollowUpAgent)(flags.agent).id;
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
const failure = (0, agent_resolver_1.agentResolutionFailure)(err);
|
|
55
|
+
this.failWithCliError({
|
|
56
|
+
message: failure.message,
|
|
57
|
+
code: failure.code,
|
|
58
|
+
exit: 2,
|
|
59
|
+
retryable: false,
|
|
60
|
+
details: { suggestion: failure.suggestion, context: failure.details },
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
let report;
|
|
65
|
+
try {
|
|
66
|
+
report = await followups_1.followupsApi.observability(agentId ? { agentId } : {});
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
this.handleApiError(err);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (flags.json) {
|
|
73
|
+
this.log(JSON.stringify(report, null, 2));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const agents = (report.agents ?? []).filter((agent) => agent.kinds.length > 0);
|
|
77
|
+
if (agents.length === 0) {
|
|
78
|
+
this.log('No follow-ups.');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// One heading per agent rather than an AGENT column: an agent id repeated
|
|
82
|
+
// on every row pushed the table past any normal terminal width.
|
|
83
|
+
agents.forEach((agent, index) => {
|
|
84
|
+
if (index > 0)
|
|
85
|
+
this.log('');
|
|
86
|
+
this.log(agent.agentId === 'user' ? 'user (reminders with no agent)' : agent.agentId);
|
|
87
|
+
(0, format_1.renderTable)(agent.kinds.map((kind) => ({
|
|
88
|
+
kind: kind.kind,
|
|
89
|
+
created: String(kind.created),
|
|
90
|
+
open: String(kind.armed),
|
|
91
|
+
proposed: String(kind.proposed),
|
|
92
|
+
settled: String(kind.settled),
|
|
93
|
+
outcomes: outcomes(kind.terminal),
|
|
94
|
+
escalated: rate(kind.escalationRate),
|
|
95
|
+
fires: String(kind.fires),
|
|
96
|
+
budget: kind.budget ? `${kind.budget.used}/${kind.budget.limit ?? '∞'}` : '—',
|
|
97
|
+
silence: rate(kind.silenceRate),
|
|
98
|
+
})), [
|
|
99
|
+
{ key: 'kind', header: 'KIND' },
|
|
100
|
+
{ key: 'created', header: 'CREATED' },
|
|
101
|
+
{ key: 'open', header: 'OPEN' },
|
|
102
|
+
{ key: 'proposed', header: 'PROPOSED' },
|
|
103
|
+
{ key: 'settled', header: 'SETTLED' },
|
|
104
|
+
{ key: 'outcomes', header: 'OUTCOMES' },
|
|
105
|
+
{ key: 'escalated', header: 'ESCALATED' },
|
|
106
|
+
{ key: 'fires', header: 'FIRES' },
|
|
107
|
+
{ key: 'budget', header: 'TODAY/LIMIT' },
|
|
108
|
+
{ key: 'silence', header: 'SILENT' },
|
|
109
|
+
], (line) => this.log(line));
|
|
110
|
+
});
|
|
111
|
+
this.log(`\nAs of ${report.generatedAt ?? 'now'}. TODAY/LIMIT is the daily budget (reminders are not metered); SILENT is how often a check-in chose to stay quiet.`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.default = FollowupsObservability;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr followups remind` — a `reminder` follow-up.
|
|
4
|
+
*
|
|
5
|
+
* A passive reminder (the default) delivers the user's own words back at T
|
|
6
|
+
* and needs no agent. `--active` wakes the agent to word it, which is why it
|
|
7
|
+
* needs an agent context the passive form does not.
|
|
8
|
+
*/
|
|
9
|
+
export default class FollowupsRemind extends BaseCommand {
|
|
10
|
+
static description: string;
|
|
11
|
+
static examples: string[];
|
|
12
|
+
static flags: {
|
|
13
|
+
subject: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
|
+
content: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
|
+
at: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
16
|
+
in: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
17
|
+
why: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
|
+
active: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
agent: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
+
endpoint: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
+
'endpoint-target': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
|
+
pin: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
};
|
|
25
|
+
run(): Promise<void>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
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 followups_1 = require("../../lib/followups");
|
|
6
|
+
const agent_resolver_1 = require("../../lib/agent-resolver");
|
|
7
|
+
/**
|
|
8
|
+
* `skrr followups remind` — a `reminder` follow-up.
|
|
9
|
+
*
|
|
10
|
+
* A passive reminder (the default) delivers the user's own words back at T
|
|
11
|
+
* and needs no agent. `--active` wakes the agent to word it, which is why it
|
|
12
|
+
* needs an agent context the passive form does not.
|
|
13
|
+
*/
|
|
14
|
+
class FollowupsRemind extends base_command_1.BaseCommand {
|
|
15
|
+
static description = 'Remind the owner at a time — the reminder follow-up';
|
|
16
|
+
static examples = [
|
|
17
|
+
'<%= config.bin %> followups remind --subject task:OSK-42 --content "pick the deploy up" --in 2h',
|
|
18
|
+
'<%= config.bin %> followups remind --subject conversation:conv_9 --content "ask how the move went" --at 2026-09-20T09:00:00Z',
|
|
19
|
+
'<%= config.bin %> followups remind --subject task:OSK-42 --content "ping me" --at 2026-09-20T09:00:00Z --active --agent agent_1',
|
|
20
|
+
];
|
|
21
|
+
static flags = {
|
|
22
|
+
subject: core_1.Flags.string({ description: 'Subject ref: type:externalKey', required: true }),
|
|
23
|
+
content: core_1.Flags.string({ description: "The reminder's own words", required: true }),
|
|
24
|
+
at: core_1.Flags.string({ description: 'ISO-8601 instant to remind at', exclusive: ['in'] }),
|
|
25
|
+
in: core_1.Flags.string({
|
|
26
|
+
description: 'Duration from now (90m, 2h, 3d)',
|
|
27
|
+
exclusive: ['at'],
|
|
28
|
+
}),
|
|
29
|
+
why: core_1.Flags.string({ description: 'Why this wake exists (defaults to the content)' }),
|
|
30
|
+
active: core_1.Flags.boolean({
|
|
31
|
+
description: 'Wake the agent to word the reminder (needs an agent context)',
|
|
32
|
+
default: false,
|
|
33
|
+
}),
|
|
34
|
+
agent: core_1.Flags.string({ description: 'Agent ID (default: bound session agent)' }),
|
|
35
|
+
endpoint: core_1.Flags.string({ description: 'Delivery endpoint id (EndpointRegistry)' }),
|
|
36
|
+
'endpoint-target': core_1.Flags.string({ description: 'Channel target for channel endpoints' }),
|
|
37
|
+
pin: core_1.Flags.string({ description: 'Conversation id the reminder was authored in' }),
|
|
38
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
39
|
+
};
|
|
40
|
+
async run() {
|
|
41
|
+
this.requireAuth();
|
|
42
|
+
const { flags } = await this.parse(FollowupsRemind);
|
|
43
|
+
const at = flags.at ?? flags.in;
|
|
44
|
+
if (!at) {
|
|
45
|
+
this.failWithCliError({
|
|
46
|
+
message: 'Either --at <iso> or --in <duration> is required.',
|
|
47
|
+
code: 'FOLLOWUP_KIND_FIELD_MISSING',
|
|
48
|
+
exit: 2,
|
|
49
|
+
retryable: false,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// A passive reminder runs no agent, so it may legitimately have none — the
|
|
53
|
+
// ONLY kind/form where the resolver is allowed to fall through empty.
|
|
54
|
+
let agent;
|
|
55
|
+
try {
|
|
56
|
+
agent = (0, followups_1.resolveFollowUpAgent)(flags.agent);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
if (flags.active) {
|
|
60
|
+
const failure = (0, agent_resolver_1.agentResolutionFailure)(err);
|
|
61
|
+
this.failWithCliError({
|
|
62
|
+
message: failure.message,
|
|
63
|
+
code: failure.code,
|
|
64
|
+
exit: 2,
|
|
65
|
+
retryable: false,
|
|
66
|
+
details: { suggestion: failure.suggestion, context: failure.details },
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
let response;
|
|
71
|
+
try {
|
|
72
|
+
response = await followups_1.followupsApi.create({
|
|
73
|
+
kind: 'reminder',
|
|
74
|
+
form: flags.active ? 'active' : 'passive',
|
|
75
|
+
producer: agent?.boundToSession ? 'agent_in_turn' : 'user_explicit',
|
|
76
|
+
...(agent ? { agentId: agent.id } : {}),
|
|
77
|
+
subject: (0, followups_1.parseSubjectRef)(flags.subject),
|
|
78
|
+
why: flags.why ?? flags.content,
|
|
79
|
+
content: flags.content,
|
|
80
|
+
at,
|
|
81
|
+
...(flags.endpoint ? { endpointId: flags.endpoint } : {}),
|
|
82
|
+
...(flags['endpoint-target'] ? { endpointTarget: flags['endpoint-target'] } : {}),
|
|
83
|
+
...(flags.pin ? { pinnedConversationId: flags.pin } : {}),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
this.handleApiError(err);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (flags.json) {
|
|
91
|
+
this.log(JSON.stringify(response, null, 2));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const row = response.followup;
|
|
95
|
+
if (response.reused) {
|
|
96
|
+
this.log(`Already armed: ${row?.id} — the same reminder exists and was not duplicated.`);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (response.dropped) {
|
|
100
|
+
this.log('Dropped by the daily budget — no reminder was armed.');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
this.log(`Reminder armed: ${row?.id} at ${row?.nextRunAt ?? at}.`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.default = FollowupsRemind;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/** `skrr followups reschedule <id>` — move a pending wake to a new time. */
|
|
3
|
+
export default class FollowupsReschedule extends BaseCommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static args: {
|
|
7
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
8
|
+
};
|
|
9
|
+
static flags: {
|
|
10
|
+
at: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
in: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
};
|
|
14
|
+
run(): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
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 followups_1 = require("../../lib/followups");
|
|
6
|
+
/** `skrr followups reschedule <id>` — move a pending wake to a new time. */
|
|
7
|
+
class FollowupsReschedule extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'Reschedule a pending follow-up';
|
|
9
|
+
static examples = [
|
|
10
|
+
'<%= config.bin %> followups reschedule fu_abc --in 2h',
|
|
11
|
+
'<%= config.bin %> followups reschedule fu_abc --at 2026-09-20T09:00:00Z',
|
|
12
|
+
];
|
|
13
|
+
static args = {
|
|
14
|
+
id: followups_1.followUpIdArg,
|
|
15
|
+
};
|
|
16
|
+
static flags = {
|
|
17
|
+
at: core_1.Flags.string({ description: 'New instant (ISO-8601)', exclusive: ['in'] }),
|
|
18
|
+
in: core_1.Flags.string({ description: 'New offset from now (90m, 2h)', exclusive: ['at'] }),
|
|
19
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
20
|
+
};
|
|
21
|
+
async run() {
|
|
22
|
+
this.requireAuth();
|
|
23
|
+
const { args, flags } = await this.parse(FollowupsReschedule);
|
|
24
|
+
const at = flags.at ?? flags.in;
|
|
25
|
+
if (!at) {
|
|
26
|
+
this.failWithCliError({
|
|
27
|
+
message: 'Either --at <iso> or --in <duration> is required.',
|
|
28
|
+
code: 'FOLLOWUP_KIND_FIELD_MISSING',
|
|
29
|
+
exit: 2,
|
|
30
|
+
retryable: false,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
let result;
|
|
34
|
+
try {
|
|
35
|
+
result = (await followups_1.followupsApi.reschedule(args.id, { at }));
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
this.handleApiError(err);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (flags.json) {
|
|
42
|
+
this.log(JSON.stringify(result, null, 2));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.log(`Follow-up ${args.id} rescheduled to ${at}.`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.default = FollowupsReschedule;
|