@skrr-ai/cli 0.1.22 → 0.1.24
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 +83 -73
- package/bin/dev-fallback.js +221 -0
- package/bin/run.js +96 -0
- package/dist/base-command.d.ts +15 -0
- package/dist/base-command.js +145 -11
- package/dist/commands/agents/attach-harness.d.ts +37 -0
- package/dist/commands/agents/attach-harness.js +102 -3
- package/dist/commands/agents/chat.d.ts +69 -1
- package/dist/commands/agents/chat.js +202 -22
- package/dist/commands/agents/create.d.ts +38 -0
- package/dist/commands/agents/create.js +95 -2
- package/dist/commands/agents/schedule-trace.js +11 -0
- package/dist/commands/agents/show.js +29 -1
- package/dist/commands/api-keys/create.d.ts +24 -0
- package/dist/commands/api-keys/create.js +80 -0
- package/dist/commands/api-keys/list.d.ts +11 -0
- package/dist/commands/api-keys/list.js +42 -0
- package/dist/commands/api-keys/revoke.d.ts +14 -0
- package/dist/commands/api-keys/revoke.js +33 -0
- package/dist/commands/api-keys/rotate.d.ts +19 -0
- package/dist/commands/api-keys/rotate.js +42 -0
- package/dist/commands/balance/index.d.ts +18 -0
- package/dist/commands/balance/index.js +29 -0
- package/dist/commands/balance/show.d.ts +25 -0
- package/dist/commands/balance/show.js +60 -0
- package/dist/commands/balance/statement.d.ts +19 -0
- package/dist/commands/balance/statement.js +52 -0
- package/dist/commands/browser/doctor.d.ts +11 -0
- package/dist/commands/browser/doctor.js +11 -0
- package/dist/commands/code/jobs/approve.d.ts +25 -0
- package/dist/commands/code/jobs/approve.js +52 -0
- package/dist/commands/code/jobs/cancel.d.ts +12 -0
- package/dist/commands/code/jobs/cancel.js +39 -0
- package/dist/commands/code/jobs/index.d.ts +19 -0
- package/dist/commands/code/jobs/index.js +38 -0
- package/dist/commands/code/jobs/list.d.ts +12 -0
- package/dist/commands/code/jobs/list.js +87 -0
- package/dist/commands/code/jobs/run.d.ts +32 -0
- package/dist/commands/code/jobs/run.js +151 -0
- package/dist/commands/code/jobs/show.d.ts +12 -0
- package/dist/commands/code/jobs/show.js +86 -0
- package/dist/commands/commitments/preflight.js +18 -4
- package/dist/commands/commitments/receipt-metrics.d.ts +39 -0
- package/dist/commands/commitments/receipt-metrics.js +78 -0
- package/dist/commands/convos/search.js +5 -5
- package/dist/commands/harnesses/leases/list.d.ts +3 -0
- package/dist/commands/harnesses/leases/list.js +59 -12
- package/dist/commands/harnesses/leases/show.js +36 -0
- package/dist/commands/harnesses/list.d.ts +18 -0
- package/dist/commands/harnesses/list.js +30 -0
- package/dist/commands/harnesses/products.js +49 -3
- package/dist/commands/harnesses/quota.d.ts +16 -0
- package/dist/commands/harnesses/quota.js +26 -1
- package/dist/commands/harnesses/usage.js +17 -0
- package/dist/commands/inbox/index.d.ts +2 -1
- package/dist/commands/inbox/index.js +27 -4
- package/dist/commands/login.js +4 -1
- package/dist/commands/machines/dedicated/create.d.ts +18 -0
- package/dist/commands/machines/dedicated/create.js +90 -0
- package/dist/commands/machines/dedicated/destroy.d.ts +14 -0
- package/dist/commands/machines/dedicated/destroy.js +56 -0
- package/dist/commands/machines/dedicated/grow.d.ts +13 -0
- package/dist/commands/machines/dedicated/grow.js +46 -0
- package/dist/commands/machines/dedicated/health-check.d.ts +12 -0
- package/dist/commands/machines/dedicated/health-check.js +42 -0
- package/dist/commands/machines/dedicated/incident-close.d.ts +12 -0
- package/dist/commands/machines/dedicated/incident-close.js +42 -0
- package/dist/commands/machines/dedicated/index.d.ts +6 -0
- package/dist/commands/machines/dedicated/index.js +39 -0
- package/dist/commands/machines/dedicated/list.d.ts +11 -0
- package/dist/commands/machines/dedicated/list.js +58 -0
- package/dist/commands/machines/dedicated/restart.d.ts +12 -0
- package/dist/commands/machines/dedicated/restart.js +42 -0
- package/dist/commands/machines/dedicated/show.d.ts +12 -0
- package/dist/commands/machines/dedicated/show.js +58 -0
- package/dist/commands/machines/dedicated/snapshot.d.ts +12 -0
- package/dist/commands/machines/dedicated/snapshot.js +42 -0
- package/dist/commands/machines/dedicated/start.d.ts +12 -0
- package/dist/commands/machines/dedicated/start.js +42 -0
- package/dist/commands/machines/dedicated/stop.d.ts +12 -0
- package/dist/commands/machines/dedicated/stop.js +42 -0
- package/dist/commands/machines/hosted/index.js +4 -1
- package/dist/commands/machines/list.d.ts +1 -0
- package/dist/commands/machines/list.js +33 -5
- package/dist/commands/memory/approvals/issue.d.ts +18 -0
- package/dist/commands/memory/approvals/issue.js +63 -0
- package/dist/commands/memory/commit.js +5 -2
- package/dist/commands/memory/context.d.ts +3 -2
- package/dist/commands/memory/context.js +9 -11
- package/dist/commands/memory/delete.d.ts +1 -1
- package/dist/commands/memory/list.d.ts +1 -1
- package/dist/commands/memory/list.js +1 -1
- package/dist/commands/memory/mounts/resolve.d.ts +10 -0
- package/dist/commands/memory/mounts/resolve.js +27 -0
- package/dist/commands/memory/proposals/commit.d.ts +18 -0
- package/dist/commands/memory/proposals/commit.js +32 -0
- package/dist/commands/memory/proposals/create.d.ts +18 -0
- package/dist/commands/memory/proposals/create.js +56 -0
- package/dist/commands/memory/proposals/list.d.ts +13 -0
- package/dist/commands/memory/proposals/list.js +31 -0
- package/dist/commands/memory/proposals/promote.d.ts +22 -0
- package/dist/commands/memory/proposals/promote.js +33 -0
- package/dist/commands/memory/proposals/reject.d.ts +16 -0
- package/dist/commands/memory/proposals/reject.js +28 -0
- package/dist/commands/memory/rebuild-index.d.ts +20 -0
- package/dist/commands/memory/rebuild-index.js +25 -0
- package/dist/commands/memory/save.d.ts +1 -1
- package/dist/commands/memory/save.js +1 -1
- package/dist/commands/memory/search.d.ts +6 -3
- package/dist/commands/memory/search.js +27 -3
- package/dist/commands/memory/show.d.ts +1 -1
- package/dist/commands/memory/stores/archive.d.ts +14 -0
- package/dist/commands/memory/stores/archive.js +31 -0
- package/dist/commands/memory/stores/create.d.ts +12 -0
- package/dist/commands/memory/stores/create.js +30 -0
- package/dist/commands/memory/stores/delete.d.ts +15 -0
- package/dist/commands/memory/stores/delete.js +38 -0
- package/dist/commands/memory/stores/list.d.ts +10 -0
- package/dist/commands/memory/stores/list.js +29 -0
- package/dist/commands/memory/stores/show.d.ts +12 -0
- package/dist/commands/memory/stores/show.js +14 -0
- package/dist/commands/memory/stores/update.d.ts +15 -0
- package/dist/commands/memory/stores/update.js +39 -0
- package/dist/commands/memory/sync/delete.d.ts +13 -0
- package/dist/commands/memory/sync/delete.js +35 -0
- package/dist/commands/memory/sync/pull.d.ts +19 -0
- package/dist/commands/memory/sync/pull.js +52 -0
- package/dist/commands/memory/sync/push.d.ts +18 -0
- package/dist/commands/memory/sync/push.js +115 -0
- package/dist/commands/memory/sync/resolve.d.ts +23 -0
- package/dist/commands/memory/sync/resolve.js +27 -0
- package/dist/commands/memory/sync/status.d.ts +9 -0
- package/dist/commands/memory/sync/status.js +22 -0
- package/dist/commands/memory/topics/archive.d.ts +20 -0
- package/dist/commands/memory/topics/archive.js +29 -0
- package/dist/commands/memory/topics/create.d.ts +23 -0
- package/dist/commands/memory/topics/create.js +46 -0
- package/dist/commands/memory/topics/delete.d.ts +22 -0
- package/dist/commands/memory/topics/delete.js +30 -0
- package/dist/commands/memory/topics/forget.d.ts +22 -0
- package/dist/commands/memory/topics/forget.js +29 -0
- package/dist/commands/memory/topics/list.d.ts +13 -0
- package/dist/commands/memory/topics/list.js +22 -0
- package/dist/commands/memory/topics/move.d.ts +22 -0
- package/dist/commands/memory/topics/move.js +26 -0
- package/dist/commands/memory/topics/show.d.ts +17 -0
- package/dist/commands/memory/topics/show.js +21 -0
- package/dist/commands/memory/topics/update.d.ts +23 -0
- package/dist/commands/memory/topics/update.js +27 -0
- package/dist/commands/memory/tree.d.ts +5 -2
- package/dist/commands/memory/tree.js +20 -2
- package/dist/commands/memory/update.d.ts +1 -1
- package/dist/commands/memory/versions/list.d.ts +16 -0
- package/dist/commands/memory/versions/list.js +22 -0
- package/dist/commands/memory/versions/redact.d.ts +21 -0
- package/dist/commands/memory/versions/redact.js +22 -0
- package/dist/commands/memory/versions/restore.d.ts +20 -0
- package/dist/commands/memory/versions/restore.js +16 -0
- package/dist/commands/memory/versions/show.d.ts +15 -0
- package/dist/commands/memory/versions/show.js +17 -0
- package/dist/commands/messages/list.js +25 -8
- package/dist/commands/messages/show.js +10 -0
- package/dist/commands/spaces/update.js +16 -12
- package/dist/commands/spaces/work-sync/reconcile.d.ts +38 -0
- package/dist/commands/spaces/work-sync/reconcile.js +90 -0
- package/dist/commands/spaces/work-sync/telemetry.d.ts +29 -0
- package/dist/commands/spaces/work-sync/telemetry.js +96 -0
- package/dist/commands/store/install.js +5 -1
- package/dist/commands/store/releases.js +1 -1
- package/dist/commands/store/update.js +5 -1
- package/dist/commands/subscriptions/cancel.js +5 -1
- package/dist/commands/subscriptions/health.js +5 -1
- package/dist/commands/subscriptions/status.js +5 -1
- package/dist/commands/subscriptions/subscribe.js +5 -1
- package/dist/commands/tasks/activity.d.ts +2 -3
- package/dist/commands/tasks/activity.js +20 -6
- package/dist/commands/tasks/complete.d.ts +22 -150
- package/dist/commands/tasks/complete.js +174 -599
- package/dist/commands/tasks/create.d.ts +6 -0
- package/dist/commands/tasks/create.js +114 -4
- package/dist/commands/tasks/deliverable/add.d.ts +8 -0
- package/dist/commands/tasks/deliverable/add.js +62 -11
- package/dist/commands/tasks/deliverable/confirm.d.ts +5 -5
- package/dist/commands/tasks/deliverable/confirm.js +9 -18
- package/dist/commands/tasks/deliverable/list.d.ts +12 -0
- package/dist/commands/tasks/deliverable/list.js +58 -0
- package/dist/commands/tasks/events/append.d.ts +2 -0
- package/dist/commands/tasks/events/append.js +41 -6
- package/dist/commands/tasks/events/list.d.ts +1 -0
- package/dist/commands/tasks/events/list.js +1 -0
- package/dist/commands/tasks/events/tail.d.ts +1 -0
- package/dist/commands/tasks/events/tail.js +1 -0
- package/dist/commands/tasks/expectations/assess.d.ts +21 -0
- package/dist/commands/tasks/expectations/assess.js +103 -0
- package/dist/commands/tasks/expectations.js +121 -25
- package/dist/commands/tasks/judge.d.ts +1 -0
- package/dist/commands/tasks/judge.js +2 -1
- package/dist/commands/tasks/output.d.ts +1 -11
- package/dist/commands/tasks/output.js +80 -141
- package/dist/commands/tasks/report.d.ts +3 -3
- package/dist/commands/tasks/report.js +66 -41
- package/dist/commands/tasks/resource/add.d.ts +23 -0
- package/dist/commands/tasks/resource/add.js +76 -0
- package/dist/commands/tasks/resource/list.d.ts +13 -0
- package/dist/commands/tasks/resource/list.js +41 -0
- package/dist/commands/tasks/result/show.d.ts +13 -0
- package/dist/commands/tasks/result/show.js +64 -0
- package/dist/commands/tasks/result/submit.d.ts +26 -0
- package/dist/commands/tasks/result/submit.js +134 -0
- package/dist/commands/tasks/resume/save.d.ts +16 -0
- package/dist/commands/tasks/resume/save.js +69 -0
- package/dist/commands/tasks/resume/show.d.ts +13 -0
- package/dist/commands/tasks/resume/show.js +35 -0
- package/dist/commands/tasks/review.d.ts +17 -0
- package/dist/commands/tasks/review.js +54 -0
- package/dist/commands/tasks/runs.js +5 -0
- package/dist/commands/tasks/self-schedule.js +7 -4
- package/dist/commands/tasks/show.js +19 -0
- package/dist/commands/tasks/timeline.d.ts +2 -2
- package/dist/commands/tasks/timeline.js +19 -24
- package/dist/commands/tasks/updates/add.d.ts +22 -0
- package/dist/commands/tasks/updates/add.js +122 -0
- package/dist/commands/tasks/updates/list.d.ts +15 -0
- package/dist/commands/tasks/updates/list.js +57 -0
- package/dist/commands/tasks/waive.d.ts +1 -0
- package/dist/commands/tasks/waive.js +2 -1
- package/dist/lib/agentic-stream.d.ts +257 -0
- package/dist/lib/agentic-stream.js +490 -33
- package/dist/lib/balance.d.ts +8 -0
- package/dist/lib/commitment-product.d.ts +10 -1
- package/dist/lib/commitment-product.js +66 -2
- package/dist/lib/commitments.d.ts +2 -1
- package/dist/lib/commitments.js +1 -0
- package/dist/lib/conversation-search.d.ts +3 -0
- package/dist/lib/conversation-search.js +75 -0
- package/dist/lib/dedicated-machines.d.ts +66 -0
- package/dist/lib/dedicated-machines.js +161 -0
- package/dist/lib/execution-target.d.ts +21 -0
- package/dist/lib/execution-target.js +22 -6
- package/dist/lib/harnesses.d.ts +87 -6
- package/dist/lib/harnesses.js +32 -1
- package/dist/lib/hosted-machines.js +9 -0
- package/dist/lib/inbox.d.ts +2 -1
- package/dist/lib/machines.d.ts +17 -0
- package/dist/lib/machines.js +29 -0
- package/dist/lib/managed-agent-keys.d.ts +104 -0
- package/dist/lib/managed-agent-keys.js +50 -0
- package/dist/lib/memory-scope.d.ts +4 -3
- package/dist/lib/memory-scope.js +9 -9
- package/dist/lib/memory-sync.d.ts +114 -0
- package/dist/lib/memory-sync.js +730 -0
- package/dist/lib/message-provenance.d.ts +42 -0
- package/dist/lib/message-provenance.js +89 -0
- package/dist/lib/scoped-memory-command.d.ts +68 -0
- package/dist/lib/scoped-memory-command.js +183 -0
- package/dist/lib/session-task-endpoints.d.ts +1 -1
- package/dist/lib/session-task-endpoints.js +7 -0
- package/dist/lib/sky-code-broker.d.ts +47 -0
- package/dist/lib/sky-code-broker.js +50 -0
- package/dist/lib/sky-code-doctor.js +10 -1
- package/dist/lib/task-artifact-flags.d.ts +2 -0
- package/dist/lib/task-artifact-flags.js +7 -0
- package/dist/lib/task-execution.d.ts +4 -5
- package/dist/lib/task-execution.js +4 -5
- package/dist/lib/task-extras.d.ts +1 -5
- package/dist/lib/task-extras.js +1 -5
- package/dist/lib/task-legacy.d.ts +24 -0
- package/dist/lib/task-legacy.js +48 -0
- package/dist/lib/task-transcript.d.ts +5 -7
- package/dist/lib/task-transcript.js +8 -16
- package/dist/lib/tasks.d.ts +39 -21
- package/dist/lib/tasks.js +64 -21
- package/dist/lib/triggers.d.ts +39 -1
- package/dist/lib/triggers.js +70 -2
- package/dist/lib/usage-discovery.d.ts +17 -1
- package/dist/lib/usage-discovery.js +17 -1
- package/dist/lib/work-sync.d.ts +70 -0
- package/dist/lib/work-sync.js +29 -0
- package/dist/node_modules/@skrr-ai/data-provider/index.js +3760 -3621
- package/oclif.manifest.json +14653 -7813
- package/package.json +26 -5
package/dist/lib/task-extras.js
CHANGED
|
@@ -42,11 +42,7 @@ exports.taskLookupApi = {
|
|
|
42
42
|
*/
|
|
43
43
|
followUp: (id, body) => data_provider_1.request.post(`${base(id)}/follow-up`, body),
|
|
44
44
|
cancelFollowUp: (id) => data_provider_1.request.post(`${base(id)}/follow-up/cancel`, {}),
|
|
45
|
-
/**
|
|
46
|
-
* Atomic completion: moves the task AND writes the TASK_OUTPUT comment in one
|
|
47
|
-
* request, so a crash between the two cannot leave a done task with no record
|
|
48
|
-
* of what it produced.
|
|
49
|
-
*/
|
|
45
|
+
/** Result-first closeout: submit one immutable Result, then project status. */
|
|
50
46
|
complete: (id, body) => data_provider_1.request.post(`${base(id)}/complete`, body),
|
|
51
47
|
treePosition: (id, body) => data_provider_1.request.patch(`${base(id)}/tree-position`, body),
|
|
52
48
|
createAndStart: (body) => data_provider_1.request.post(`${MOUNT}/create-and-start`, body),
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tell a reader when an empty canonical view means "nothing happened" and when
|
|
3
|
+
* it means "this Task predates the records this view reads".
|
|
4
|
+
*
|
|
5
|
+
* Canonical Task Model v1 shipped with an explicit decision not to migrate
|
|
6
|
+
* legacy data, so a Task created before 2026-09-11 has no TaskUpdate, TaskResult
|
|
7
|
+
* or TaskActivityEvent rows — its history is in `activityLog`, `TaskWorkEvent`
|
|
8
|
+
* and TASK_OUTPUT comments. Every canonical read surface therefore answered
|
|
9
|
+
* "No activity." / "Result: none submitted" / nothing at all for Tasks with
|
|
10
|
+
* years of history, stating absence as fact.
|
|
11
|
+
*
|
|
12
|
+
* The marker is that `specVersion` is ABSENT — a field the caller can only
|
|
13
|
+
* notice by its own missingness, which is why this belongs in one helper rather
|
|
14
|
+
* than in each command.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isLegacyTask(taskId: string): Promise<boolean>;
|
|
17
|
+
/**
|
|
18
|
+
* The sentence to print instead of claiming emptiness. `surface` names what the
|
|
19
|
+
* reader just asked for, so the message says which view is empty rather than
|
|
20
|
+
* implying the Task is.
|
|
21
|
+
*/
|
|
22
|
+
export declare function legacyEmptyStateMessage(surface: string): string;
|
|
23
|
+
/** Render the right empty state for a canonical view that came back empty. */
|
|
24
|
+
export declare function emptyCanonicalView(taskId: string, surface: string): Promise<string>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isLegacyTask = isLegacyTask;
|
|
4
|
+
exports.legacyEmptyStateMessage = legacyEmptyStateMessage;
|
|
5
|
+
exports.emptyCanonicalView = emptyCanonicalView;
|
|
6
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
7
|
+
/**
|
|
8
|
+
* Tell a reader when an empty canonical view means "nothing happened" and when
|
|
9
|
+
* it means "this Task predates the records this view reads".
|
|
10
|
+
*
|
|
11
|
+
* Canonical Task Model v1 shipped with an explicit decision not to migrate
|
|
12
|
+
* legacy data, so a Task created before 2026-09-11 has no TaskUpdate, TaskResult
|
|
13
|
+
* or TaskActivityEvent rows — its history is in `activityLog`, `TaskWorkEvent`
|
|
14
|
+
* and TASK_OUTPUT comments. Every canonical read surface therefore answered
|
|
15
|
+
* "No activity." / "Result: none submitted" / nothing at all for Tasks with
|
|
16
|
+
* years of history, stating absence as fact.
|
|
17
|
+
*
|
|
18
|
+
* The marker is that `specVersion` is ABSENT — a field the caller can only
|
|
19
|
+
* notice by its own missingness, which is why this belongs in one helper rather
|
|
20
|
+
* than in each command.
|
|
21
|
+
*/
|
|
22
|
+
async function isLegacyTask(taskId) {
|
|
23
|
+
try {
|
|
24
|
+
const task = (await data_provider_1.dataService.getTask(taskId));
|
|
25
|
+
return task !== undefined && task !== null && task.specVersion === undefined;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Never turn a diagnostic into a failure: the caller is rendering an empty
|
|
29
|
+
// state, not making a decision.
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The sentence to print instead of claiming emptiness. `surface` names what the
|
|
35
|
+
* reader just asked for, so the message says which view is empty rather than
|
|
36
|
+
* implying the Task is.
|
|
37
|
+
*/
|
|
38
|
+
function legacyEmptyStateMessage(surface) {
|
|
39
|
+
return (`No ${surface} recorded under the canonical Task model.\n` +
|
|
40
|
+
'This Task predates it, so its history was never migrated — read it with ' +
|
|
41
|
+
'`skrr tasks show`, `skrr tasks comments list`, or `skrr tasks transcript`.');
|
|
42
|
+
}
|
|
43
|
+
/** Render the right empty state for a canonical view that came back empty. */
|
|
44
|
+
async function emptyCanonicalView(taskId, surface) {
|
|
45
|
+
return (await isLegacyTask(taskId))
|
|
46
|
+
? legacyEmptyStateMessage(surface)
|
|
47
|
+
: `No ${surface} recorded yet.`;
|
|
48
|
+
}
|
|
@@ -13,7 +13,7 @@ export type ParsedTaskOutput = {
|
|
|
13
13
|
verdict: string;
|
|
14
14
|
};
|
|
15
15
|
/**
|
|
16
|
-
* Parsed `---TASK_OUTPUT---` block plus the
|
|
16
|
+
* Parsed historical `---TASK_OUTPUT---` block plus the Comment it came from.
|
|
17
17
|
*/
|
|
18
18
|
export type TaskOutputComment = {
|
|
19
19
|
commentId: string;
|
|
@@ -36,9 +36,9 @@ export type TaskOutputComment = {
|
|
|
36
36
|
/**
|
|
37
37
|
* Mirror of `api/server/services/taskCompletionFormatting.js:parseTaskOutputBlock`.
|
|
38
38
|
* Kept as a CLI-local copy on purpose — the CLI cannot import from `api/`, and
|
|
39
|
-
* the block format is a wire contract
|
|
40
|
-
*
|
|
41
|
-
*
|
|
39
|
+
* the block format is a historical wire contract, not an implementation
|
|
40
|
+
* detail. Keep the two compatibility readers in lockstep, including the
|
|
41
|
+
* single-line field semantics: the `m` flag makes `$`
|
|
42
42
|
* match at each line end, so a value stops at its own newline. That is correct
|
|
43
43
|
* by construction — `tasks complete` collapses `[\r\n]+` to spaces before
|
|
44
44
|
* writing — but a hand-authored block CAN carry continuation lines, which this
|
|
@@ -63,9 +63,7 @@ export declare function normalizeMessage(message: Record<string, unknown>): Tran
|
|
|
63
63
|
export declare function selectWindow<T>(items: T[], limit: number | null, head?: boolean): T[];
|
|
64
64
|
export declare function fetchTranscript(conversationId: string): Promise<TranscriptMessage[]>;
|
|
65
65
|
/**
|
|
66
|
-
* Newest `---TASK_OUTPUT---`
|
|
67
|
-
* posted one (still running, failed before finalization, or completed by a path
|
|
68
|
-
* that skipped the canonical block).
|
|
66
|
+
* Newest historical `---TASK_OUTPUT---` Comment, or null when none exists.
|
|
69
67
|
*/
|
|
70
68
|
export declare function fetchLatestTaskOutputComment(taskId: string, limit?: number): Promise<TaskOutputComment | null>;
|
|
71
69
|
/** Last message the agent (not the user) produced in the execution conversation. */
|
|
@@ -14,25 +14,19 @@ exports.unverifiedOutcomeNote = unverifiedOutcomeNote;
|
|
|
14
14
|
/**
|
|
15
15
|
* Task → agent-response plumbing for the `skrr` CLI.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* TasksMCP completion path — the structured verdict.
|
|
22
|
-
* 3. The run rows (`tasks runs` / `execution-summary`) — did it even finish.
|
|
23
|
-
*
|
|
24
|
-
* Nothing tied those together, so "what did the agent produce for this task?"
|
|
25
|
-
* meant three commands plus a jq hop. This module is the shared read layer for
|
|
26
|
-
* `tasks transcript` and `tasks output`.
|
|
17
|
+
* Shared transcript normalization plus read-only parsing of historical
|
|
18
|
+
* TASK_OUTPUT Comments. Canonical output now lives in TaskResult, TaskReview,
|
|
19
|
+
* TaskResourceLink, and TaskExecutionRun; no writer may call the compatibility
|
|
20
|
+
* functions below.
|
|
27
21
|
*/
|
|
28
22
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
29
23
|
const TASK_OUTPUT_FIELDS = ['status', 'summary', 'artifacts', 'verdict'];
|
|
30
24
|
/**
|
|
31
25
|
* Mirror of `api/server/services/taskCompletionFormatting.js:parseTaskOutputBlock`.
|
|
32
26
|
* Kept as a CLI-local copy on purpose — the CLI cannot import from `api/`, and
|
|
33
|
-
* the block format is a wire contract
|
|
34
|
-
*
|
|
35
|
-
*
|
|
27
|
+
* the block format is a historical wire contract, not an implementation
|
|
28
|
+
* detail. Keep the two compatibility readers in lockstep, including the
|
|
29
|
+
* single-line field semantics: the `m` flag makes `$`
|
|
36
30
|
* match at each line end, so a value stops at its own newline. That is correct
|
|
37
31
|
* by construction — `tasks complete` collapses `[\r\n]+` to spaces before
|
|
38
32
|
* writing — but a hand-authored block CAN carry continuation lines, which this
|
|
@@ -121,9 +115,7 @@ async function fetchTranscript(conversationId) {
|
|
|
121
115
|
return list.map(normalizeMessage);
|
|
122
116
|
}
|
|
123
117
|
/**
|
|
124
|
-
* Newest `---TASK_OUTPUT---`
|
|
125
|
-
* posted one (still running, failed before finalization, or completed by a path
|
|
126
|
-
* that skipped the canonical block).
|
|
118
|
+
* Newest historical `---TASK_OUTPUT---` Comment, or null when none exists.
|
|
127
119
|
*/
|
|
128
120
|
async function fetchLatestTaskOutputComment(taskId, limit = 50) {
|
|
129
121
|
const response = (await data_provider_1.dataService.listTaskComments(taskId, { limit }));
|
package/dist/lib/tasks.d.ts
CHANGED
|
@@ -59,6 +59,7 @@ export type TaskCreateFlagValues = {
|
|
|
59
59
|
description?: string;
|
|
60
60
|
presetKey?: string;
|
|
61
61
|
}>;
|
|
62
|
+
'review-policy'?: string;
|
|
62
63
|
'start-date'?: string;
|
|
63
64
|
'due-date'?: string;
|
|
64
65
|
estimate?: number;
|
|
@@ -98,6 +99,37 @@ export declare function parseExpectations(specs: string[] | undefined): {
|
|
|
98
99
|
error: string;
|
|
99
100
|
};
|
|
100
101
|
export declare const EXPECT_FLAG_HELP: string;
|
|
102
|
+
/**
|
|
103
|
+
* What `--default-expect` means, as a value rather than a side effect.
|
|
104
|
+
*
|
|
105
|
+
* `clear` REMOVES the Space default, and it has to exist. Every Expectation gates
|
|
106
|
+
* closure and a Space default is inherited by every task created afterwards, so a
|
|
107
|
+
* default set by mistake — or one that outlived its project — gated the whole
|
|
108
|
+
* board with no way back. `tasks update --expect` already had this sentinel; the
|
|
109
|
+
* Space flag, the one the design calls "configured once and then holds", did not.
|
|
110
|
+
* The only exit was to waive the expectation on every task, which writes `dropped`
|
|
111
|
+
* into the ledger about a requirement that was never real. That is a false record,
|
|
112
|
+
* not a workaround.
|
|
113
|
+
*
|
|
114
|
+
* `null` rather than `[]`: the route declares the field `.nullable()` and the API
|
|
115
|
+
* turns null into an `$unset`, so the Space stops carrying a default instead of
|
|
116
|
+
* carrying an empty one. `undefined` means the flag was not passed and the
|
|
117
|
+
* existing default must be left exactly as it is.
|
|
118
|
+
*
|
|
119
|
+
* `clear` must be the SOLE value. Combined with an expectation it is two
|
|
120
|
+
* contradictory instructions, and honouring one of them silently is how a caller
|
|
121
|
+
* ends up with a contract they did not ask for.
|
|
122
|
+
*
|
|
123
|
+
* Extracted so the three outcomes can be tested without a command harness — the
|
|
124
|
+
* bug being fixed was in this decision, not in the HTTP call after it.
|
|
125
|
+
*/
|
|
126
|
+
export declare function resolveDefaultExpectations(values: string[] | undefined): {
|
|
127
|
+
ok: true;
|
|
128
|
+
value: Array<Record<string, unknown>> | null | undefined;
|
|
129
|
+
} | {
|
|
130
|
+
ok: false;
|
|
131
|
+
error: string;
|
|
132
|
+
};
|
|
101
133
|
/**
|
|
102
134
|
* Parse a deliverable coordinate. Also delegated — `:` and `@` and now `/` all
|
|
103
135
|
* mean different things, and a second implementation of that grammar is how the
|
|
@@ -111,7 +143,7 @@ export declare function parseDeliverableCoordinate(spec: string): {
|
|
|
111
143
|
error: string;
|
|
112
144
|
};
|
|
113
145
|
/** Lifecycle values a caller may assert, for flag validation. */
|
|
114
|
-
export declare const DELIVERABLE_LIFECYCLE_VALUES: readonly ["local", "in_review", "
|
|
146
|
+
export declare const DELIVERABLE_LIFECYCLE_VALUES: readonly ["local", "in_review", "available", "unavailable", "superseded"];
|
|
115
147
|
export declare function buildTaskCreatePayload(body: TaskRecord, flags?: TaskCreateFlagValues): TaskRecord;
|
|
116
148
|
/**
|
|
117
149
|
* The Agent this CLI process is running AS, if any.
|
|
@@ -245,27 +277,13 @@ export declare function normalizeBulkUpdateInput(input: unknown): Array<{
|
|
|
245
277
|
patch: TaskRecord;
|
|
246
278
|
}>;
|
|
247
279
|
/**
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
* succeeds and the value is permanently recorded, while `--status` beside it
|
|
252
|
-
* is enumerated and rejects a typo. So `--verdict aproved` closes a task with
|
|
253
|
-
* a verdict nothing matches, quietly.
|
|
254
|
-
*
|
|
255
|
-
* It cannot simply be enumerated, and that is the point worth recording:
|
|
256
|
-
*
|
|
257
|
-
* - A REVIEWER task legitimately passes a JSON object
|
|
258
|
-
* (`{"posture":"request_changes","confidence":0.82,"criteria":[…]}`) —
|
|
259
|
-
* documented in the task-execution prompt and consumed by
|
|
260
|
-
* `normalizeReviewPosture`. `options:` on the flag would refuse it.
|
|
261
|
-
* - That normaliser accepts synonyms, and when it recognises NOTHING it does
|
|
262
|
-
* not fail — it derives the posture from the criteria instead. So a typo
|
|
263
|
-
* silently becomes whatever the criteria imply.
|
|
280
|
+
* Historical workflow-verdict strings recognised while parsing legacy task
|
|
281
|
+
* output. Canonical completion has no `--verdict`; domain conclusions live on
|
|
282
|
+
* TaskResult and acceptance lives on TaskReview.
|
|
264
283
|
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
* by `task-verdict-parity.spec.ts`, the same way TASK_WORK_EVENT_KINDS is.
|
|
284
|
+
* Kept only so old `TASK_OUTPUT`/TaskWorkEvent readers can classify stored
|
|
285
|
+
* values consistently with `normalizeReviewPosture`. New commands must not
|
|
286
|
+
* import this vocabulary for authoring.
|
|
269
287
|
*/
|
|
270
288
|
export declare const RECOGNIZED_TASK_VERDICTS: readonly ["request_changes", "changes_requested", "needs_changes", "needs_revision", "approved", "approve", "pass", "passed", "blocked"];
|
|
271
289
|
/** The server's own normalisation, so the same spellings match here. */
|
package/dist/lib/tasks.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.taskUpdateMutationGuard = taskUpdateMutationGuard;
|
|
|
6
6
|
exports.executionIsolationFromWorktreeFlag = executionIsolationFromWorktreeFlag;
|
|
7
7
|
exports.parseExpectation = parseExpectation;
|
|
8
8
|
exports.parseExpectations = parseExpectations;
|
|
9
|
+
exports.resolveDefaultExpectations = resolveDefaultExpectations;
|
|
9
10
|
exports.parseDeliverableCoordinate = parseDeliverableCoordinate;
|
|
10
11
|
exports.buildTaskCreatePayload = buildTaskCreatePayload;
|
|
11
12
|
exports.boundSessionAgentId = boundSessionAgentId;
|
|
@@ -156,10 +157,54 @@ const kindsForHelp = Array.isArray(data_provider_1.TASK_OUTCOME_KINDS)
|
|
|
156
157
|
const presetsForHelp = Array.isArray(data_provider_1.EXPECTATION_PRESETS)
|
|
157
158
|
? data_provider_1.EXPECTATION_PRESETS.map((preset) => `@${preset.key}`).join(', ')
|
|
158
159
|
: '@merged-to-main, @pdf-delivered';
|
|
159
|
-
exports.EXPECT_FLAG_HELP = 'What this task must produce
|
|
160
|
+
exports.EXPECT_FLAG_HELP = 'What this task must produce. Each one GATES closure: the Task cannot enter a ' +
|
|
161
|
+
'completed state until every Expectation is assessed met or waived ' +
|
|
162
|
+
'(`tasks expectations assess`). Form: <kind>[/<format>][:<target>] or @<preset> — ' +
|
|
160
163
|
`e.g. 'code:origin/main', 'file/pdf:Drive/Reports', '@merged-to-main'. ` +
|
|
161
164
|
`Kinds: ${kindsForHelp}. Presets: ${presetsForHelp}. ` +
|
|
162
165
|
'Anything else is stored as a plain-language expectation a person settles. Repeatable.';
|
|
166
|
+
/**
|
|
167
|
+
* What `--default-expect` means, as a value rather than a side effect.
|
|
168
|
+
*
|
|
169
|
+
* `clear` REMOVES the Space default, and it has to exist. Every Expectation gates
|
|
170
|
+
* closure and a Space default is inherited by every task created afterwards, so a
|
|
171
|
+
* default set by mistake — or one that outlived its project — gated the whole
|
|
172
|
+
* board with no way back. `tasks update --expect` already had this sentinel; the
|
|
173
|
+
* Space flag, the one the design calls "configured once and then holds", did not.
|
|
174
|
+
* The only exit was to waive the expectation on every task, which writes `dropped`
|
|
175
|
+
* into the ledger about a requirement that was never real. That is a false record,
|
|
176
|
+
* not a workaround.
|
|
177
|
+
*
|
|
178
|
+
* `null` rather than `[]`: the route declares the field `.nullable()` and the API
|
|
179
|
+
* turns null into an `$unset`, so the Space stops carrying a default instead of
|
|
180
|
+
* carrying an empty one. `undefined` means the flag was not passed and the
|
|
181
|
+
* existing default must be left exactly as it is.
|
|
182
|
+
*
|
|
183
|
+
* `clear` must be the SOLE value. Combined with an expectation it is two
|
|
184
|
+
* contradictory instructions, and honouring one of them silently is how a caller
|
|
185
|
+
* ends up with a contract they did not ask for.
|
|
186
|
+
*
|
|
187
|
+
* Extracted so the three outcomes can be tested without a command harness — the
|
|
188
|
+
* bug being fixed was in this decision, not in the HTTP call after it.
|
|
189
|
+
*/
|
|
190
|
+
function resolveDefaultExpectations(values) {
|
|
191
|
+
if (values === undefined || values.length === 0)
|
|
192
|
+
return { ok: true, value: undefined };
|
|
193
|
+
const clears = values.filter((value) => value.trim().toLowerCase() === 'clear');
|
|
194
|
+
if (clears.length > 0 && values.length > 1) {
|
|
195
|
+
return {
|
|
196
|
+
ok: false,
|
|
197
|
+
error: '--default-expect clear removes the space default and cannot be combined with an ' +
|
|
198
|
+
'expectation. Run it alone, then set the new default.',
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
if (clears.length > 0)
|
|
202
|
+
return { ok: true, value: null };
|
|
203
|
+
const parsed = parseExpectations(values);
|
|
204
|
+
if (!parsed.ok)
|
|
205
|
+
return { ok: false, error: parsed.error };
|
|
206
|
+
return { ok: true, value: parsed.value };
|
|
207
|
+
}
|
|
163
208
|
/**
|
|
164
209
|
* Parse a deliverable coordinate. Also delegated — `:` and `@` and now `/` all
|
|
165
210
|
* mean different things, and a second implementation of that grammar is how the
|
|
@@ -214,6 +259,7 @@ function buildTaskCreatePayload(body, flags = {}) {
|
|
|
214
259
|
assigneeUserIds: flags['assignee-user'],
|
|
215
260
|
executionMode: flags['execution-mode'],
|
|
216
261
|
expectations: flags.expectations,
|
|
262
|
+
reviewPolicy: flags['review-policy'],
|
|
217
263
|
startDate: flags['start-date'],
|
|
218
264
|
dueDate: flags['due-date'],
|
|
219
265
|
estimate: flags.estimate,
|
|
@@ -538,8 +584,18 @@ async function applyDefaultAgentToPayload(payload, defaultAgent, opts = {}) {
|
|
|
538
584
|
}
|
|
539
585
|
if (hasExplicitTaskAssignee(payload)) {
|
|
540
586
|
return {
|
|
587
|
+
// `applied` is about the DEFAULT, not about the assignment. It reads the
|
|
588
|
+
// other way: a caller who named `--assignee-agent` and got back
|
|
589
|
+
// `{applied: false, source: 'explicit-assignee'}` stopped and went to
|
|
590
|
+
// verify with `tasks show`, where the assignment was perfectly correct —
|
|
591
|
+
// on the one output a scripted caller would check before `tasks start`
|
|
592
|
+
// (OSK-7712). The two subfields together assert the opposite of what they
|
|
593
|
+
// mean. Renaming the field would break every existing reader, so the
|
|
594
|
+
// note — which exists for exactly this, "an explanation for the operator,
|
|
595
|
+
// not an error" — says it instead.
|
|
541
596
|
applied: false,
|
|
542
597
|
source: 'explicit-assignee',
|
|
598
|
+
note: 'You named the assignee, so no default was applied. The assignment is in place.',
|
|
543
599
|
agentIds: stringArray(payload.assigneeAgentIds),
|
|
544
600
|
userIds: stringArray(payload.assigneeUserIds),
|
|
545
601
|
};
|
|
@@ -548,6 +604,7 @@ async function applyDefaultAgentToPayload(payload, defaultAgent, opts = {}) {
|
|
|
548
604
|
return {
|
|
549
605
|
applied: false,
|
|
550
606
|
source: 'existing-assignee',
|
|
607
|
+
note: 'The task already had an assignee, so no default was applied. It is unchanged.',
|
|
551
608
|
agentIds: stringArray(opts.existingTask?.assigneeAgentIds),
|
|
552
609
|
userIds: stringArray(opts.existingTask?.assigneeUserIds),
|
|
553
610
|
};
|
|
@@ -809,27 +866,13 @@ function formatApiError(err) {
|
|
|
809
866
|
return String(err);
|
|
810
867
|
}
|
|
811
868
|
/**
|
|
812
|
-
*
|
|
813
|
-
*
|
|
814
|
-
*
|
|
815
|
-
* succeeds and the value is permanently recorded, while `--status` beside it
|
|
816
|
-
* is enumerated and rejects a typo. So `--verdict aproved` closes a task with
|
|
817
|
-
* a verdict nothing matches, quietly.
|
|
818
|
-
*
|
|
819
|
-
* It cannot simply be enumerated, and that is the point worth recording:
|
|
820
|
-
*
|
|
821
|
-
* - A REVIEWER task legitimately passes a JSON object
|
|
822
|
-
* (`{"posture":"request_changes","confidence":0.82,"criteria":[…]}`) —
|
|
823
|
-
* documented in the task-execution prompt and consumed by
|
|
824
|
-
* `normalizeReviewPosture`. `options:` on the flag would refuse it.
|
|
825
|
-
* - That normaliser accepts synonyms, and when it recognises NOTHING it does
|
|
826
|
-
* not fail — it derives the posture from the criteria instead. So a typo
|
|
827
|
-
* silently becomes whatever the criteria imply.
|
|
869
|
+
* Historical workflow-verdict strings recognised while parsing legacy task
|
|
870
|
+
* output. Canonical completion has no `--verdict`; domain conclusions live on
|
|
871
|
+
* TaskResult and acceptance lives on TaskReview.
|
|
828
872
|
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
*
|
|
832
|
-
* by `task-verdict-parity.spec.ts`, the same way TASK_WORK_EVENT_KINDS is.
|
|
873
|
+
* Kept only so old `TASK_OUTPUT`/TaskWorkEvent readers can classify stored
|
|
874
|
+
* values consistently with `normalizeReviewPosture`. New commands must not
|
|
875
|
+
* import this vocabulary for authoring.
|
|
833
876
|
*/
|
|
834
877
|
exports.RECOGNIZED_TASK_VERDICTS = [
|
|
835
878
|
'request_changes',
|
package/dist/lib/triggers.d.ts
CHANGED
|
@@ -93,8 +93,27 @@ export interface TriggerDefinition {
|
|
|
93
93
|
selfScheduled?: Record<string, unknown>;
|
|
94
94
|
form?: Record<string, unknown>;
|
|
95
95
|
chatMessage?: Record<string, unknown>;
|
|
96
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Fire outcomes. Typed rather than `Record<string, unknown>` for the fields
|
|
98
|
+
* the summary prints, so a reader cannot be shown a count the compiler never
|
|
99
|
+
* checked — `fireCount` is SUCCESSES and `failureCount` is failures, and
|
|
100
|
+
* conflating them is the confusion this shape exists to prevent (OSK-7842).
|
|
101
|
+
*/
|
|
102
|
+
audit?: {
|
|
103
|
+
fireCount?: number;
|
|
104
|
+
failureCount?: number;
|
|
105
|
+
lastResult?: string;
|
|
106
|
+
lastError?: string;
|
|
107
|
+
lastFiredAt?: string;
|
|
108
|
+
[key: string]: unknown;
|
|
109
|
+
};
|
|
97
110
|
webhook?: Record<string, unknown>;
|
|
111
|
+
/** Whether the SCHEDULER has actually heard of this trigger. See `armedLabel`. */
|
|
112
|
+
scheduleSync?: {
|
|
113
|
+
status?: string;
|
|
114
|
+
lastError?: string;
|
|
115
|
+
lastErrorAt?: string;
|
|
116
|
+
};
|
|
98
117
|
/**
|
|
99
118
|
* Server-DERIVED: maintained by a managed producer, so the mutation routes
|
|
100
119
|
* refuse to edit or remove it. Optional because a server predating the field
|
|
@@ -303,6 +322,25 @@ export declare class AgentTriggerScopeError extends Error {
|
|
|
303
322
|
export declare function fetchAgentScopedTrigger(agentId: string, triggerId: string): Promise<TriggerDefinition>;
|
|
304
323
|
export declare function scopeLabel(trigger: TriggerDefinition): string;
|
|
305
324
|
export declare function nextRunLabel(trigger: TriggerDefinition): string;
|
|
325
|
+
/**
|
|
326
|
+
* Whether a trigger will actually fire — not merely whether someone left it on.
|
|
327
|
+
*
|
|
328
|
+
* `enabled` means "not manually disabled", and two states diverge from it
|
|
329
|
+
* permanently:
|
|
330
|
+
*
|
|
331
|
+
* `!sync` — `enabled: true` with `scheduleSync.status` not `ok`. The row is
|
|
332
|
+
* on to every read surface and the scheduler has never heard of it. Twenty
|
|
333
|
+
* triggers were left in exactly this state in ninety minutes of production,
|
|
334
|
+
* and nothing on the agent, trigger or schedule surfaces reported it — so
|
|
335
|
+
* an operator looking at an enabled trigger had no reason to doubt it
|
|
336
|
+
* (OSK-7727).
|
|
337
|
+
* `spent` — a `once` trigger that has fired. It has no next occurrence, so
|
|
338
|
+
* `enabled` and "will fire again" diverge forever after the single fire; an
|
|
339
|
+
* agent that has been used for a while accumulates a growing list of
|
|
340
|
+
* `enabled: true` rows whose obvious reading is "these are armed"
|
|
341
|
+
* (OSK-7711).
|
|
342
|
+
*/
|
|
343
|
+
export declare function armedLabel(trigger: TriggerDefinition): string;
|
|
306
344
|
export declare function renderTriggerList(triggers: TriggerDefinition[], log: (line: string) => void): void;
|
|
307
345
|
/**
|
|
308
346
|
* The `duplicate_subscription` warning a create response may carry, as the
|
package/dist/lib/triggers.js
CHANGED
|
@@ -28,6 +28,7 @@ exports.agentRefEntity = agentRefEntity;
|
|
|
28
28
|
exports.fetchAgentScopedTrigger = fetchAgentScopedTrigger;
|
|
29
29
|
exports.scopeLabel = scopeLabel;
|
|
30
30
|
exports.nextRunLabel = nextRunLabel;
|
|
31
|
+
exports.armedLabel = armedLabel;
|
|
31
32
|
exports.renderTriggerList = renderTriggerList;
|
|
32
33
|
exports.formatDuplicateSubscriptionWarning = formatDuplicateSubscriptionWarning;
|
|
33
34
|
exports.armedStateLabel = armedStateLabel;
|
|
@@ -711,6 +712,35 @@ function nextRunLabel(trigger) {
|
|
|
711
712
|
'';
|
|
712
713
|
return next ? String(next) : '-';
|
|
713
714
|
}
|
|
715
|
+
/**
|
|
716
|
+
* Whether a trigger will actually fire — not merely whether someone left it on.
|
|
717
|
+
*
|
|
718
|
+
* `enabled` means "not manually disabled", and two states diverge from it
|
|
719
|
+
* permanently:
|
|
720
|
+
*
|
|
721
|
+
* `!sync` — `enabled: true` with `scheduleSync.status` not `ok`. The row is
|
|
722
|
+
* on to every read surface and the scheduler has never heard of it. Twenty
|
|
723
|
+
* triggers were left in exactly this state in ninety minutes of production,
|
|
724
|
+
* and nothing on the agent, trigger or schedule surfaces reported it — so
|
|
725
|
+
* an operator looking at an enabled trigger had no reason to doubt it
|
|
726
|
+
* (OSK-7727).
|
|
727
|
+
* `spent` — a `once` trigger that has fired. It has no next occurrence, so
|
|
728
|
+
* `enabled` and "will fire again" diverge forever after the single fire; an
|
|
729
|
+
* agent that has been used for a while accumulates a growing list of
|
|
730
|
+
* `enabled: true` rows whose obvious reading is "these are armed"
|
|
731
|
+
* (OSK-7711).
|
|
732
|
+
*/
|
|
733
|
+
function armedLabel(trigger) {
|
|
734
|
+
if (trigger.enabled === false)
|
|
735
|
+
return 'no';
|
|
736
|
+
const sync = trigger.scheduleSync?.status;
|
|
737
|
+
if (sync && sync !== 'ok')
|
|
738
|
+
return `!${sync}`;
|
|
739
|
+
if (trigger.kind === 'once' && trigger.once && trigger.once.firedAt) {
|
|
740
|
+
return 'spent';
|
|
741
|
+
}
|
|
742
|
+
return 'yes';
|
|
743
|
+
}
|
|
714
744
|
function renderTriggerList(triggers, log) {
|
|
715
745
|
if (triggers.length === 0) {
|
|
716
746
|
log('No triggers.');
|
|
@@ -719,18 +749,25 @@ function renderTriggerList(triggers, log) {
|
|
|
719
749
|
(0, format_1.renderTable)(triggers.map((trigger) => ({
|
|
720
750
|
id: trigger.id ?? '-',
|
|
721
751
|
kind: trigger.kind ?? '-',
|
|
722
|
-
enabled: trigger
|
|
752
|
+
enabled: armedLabel(trigger),
|
|
723
753
|
scope: scopeLabel(trigger),
|
|
724
754
|
next: nextRunLabel(trigger),
|
|
725
755
|
label: trigger.label ?? '',
|
|
726
756
|
})), [
|
|
727
757
|
{ key: 'id', header: 'ID', verbatim: true },
|
|
728
758
|
{ key: 'kind', header: 'KIND', maxWidth: 14 },
|
|
729
|
-
{ key: 'enabled', header: '
|
|
759
|
+
{ key: 'enabled', header: 'ARMED' },
|
|
730
760
|
{ key: 'scope', header: 'SCOPE', maxWidth: 42 },
|
|
731
761
|
{ key: 'next', header: 'NEXT/LAST', maxWidth: 24 },
|
|
732
762
|
{ key: 'label', header: 'LABEL', maxWidth: 32 },
|
|
733
763
|
], log);
|
|
764
|
+
const unsynced = triggers.filter((t) => armedLabel(t).startsWith('!'));
|
|
765
|
+
if (unsynced.length > 0) {
|
|
766
|
+
log('');
|
|
767
|
+
log(`${unsynced.length} trigger(s) are enabled but the scheduler has not registered them — ` +
|
|
768
|
+
'they will not fire until the orphan reconciler succeeds. ' +
|
|
769
|
+
'See `scheduleSync.lastError` in `triggers show <id> --json`.');
|
|
770
|
+
}
|
|
734
771
|
}
|
|
735
772
|
/**
|
|
736
773
|
* The `duplicate_subscription` warning a create response may carry, as the
|
|
@@ -841,6 +878,37 @@ function renderTriggerSummary(trigger, log, options = {}) {
|
|
|
841
878
|
const next = nextRunLabel(trigger);
|
|
842
879
|
if (next !== '-')
|
|
843
880
|
log(`Next/last:${next.length > 0 ? ` ${next}` : ''}`);
|
|
881
|
+
/*
|
|
882
|
+
* What actually happened when it fired.
|
|
883
|
+
*
|
|
884
|
+
* This summary printed nothing about outcomes at all: two one-shot runs
|
|
885
|
+
* fired, died, and the only surface that held the reason was `audit.lastError`
|
|
886
|
+
* in raw `--json` (OSK-7842). And the count alone misleads in the same
|
|
887
|
+
* direction, because `fireCount` counts SUCCESSES — so a trigger that fails
|
|
888
|
+
* every single time reads `fires 0` next to a recent fire time, which is what
|
|
889
|
+
* a trigger that has never run looks like too.
|
|
890
|
+
*
|
|
891
|
+
* Both numbers are therefore printed together, and only when there is
|
|
892
|
+
* something to say. `failureCount` is absent on rows last written before it
|
|
893
|
+
* existed, so it is reported only when present rather than defaulted to 0 —
|
|
894
|
+
* "not counted" must not render as "never failed".
|
|
895
|
+
*/
|
|
896
|
+
const audit = trigger.audit;
|
|
897
|
+
if (audit) {
|
|
898
|
+
const fires = audit.fireCount ?? 0;
|
|
899
|
+
const failures = audit.failureCount;
|
|
900
|
+
if (fires > 0 || failures !== undefined || audit.lastResult || audit.lastError) {
|
|
901
|
+
const parts = [`${fires} succeeded`];
|
|
902
|
+
if (failures !== undefined)
|
|
903
|
+
parts.push(`${failures} failed`);
|
|
904
|
+
if (audit.lastResult)
|
|
905
|
+
parts.push(`last ${audit.lastResult}`);
|
|
906
|
+
log(`Fires: ${parts.join(', ')}`);
|
|
907
|
+
}
|
|
908
|
+
// The reason, at the surface a reader reaches for — not only in `--json`.
|
|
909
|
+
if (audit.lastError)
|
|
910
|
+
log(`Last error: ${audit.lastError}`);
|
|
911
|
+
}
|
|
844
912
|
if (trigger.webhook?.configured !== undefined) {
|
|
845
913
|
log(`Webhook: ${trigger.webhook.configured ? 'configured' : 'not configured'}`);
|
|
846
914
|
}
|
|
@@ -6,7 +6,23 @@ import type { CommandManifest } from './command-manifest';
|
|
|
6
6
|
* domain. These smaller views are derived from that same manifest; there is no
|
|
7
7
|
* second, hand-maintained command catalogue to drift from the binary.
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* A bound on an agent's FIRST read, not an inventory of today's topics.
|
|
11
|
+
*
|
|
12
|
+
* The overview is one header line plus every domain name, so its cost grows
|
|
13
|
+
* linearly with the topic count — and it had reached exactly 200, meaning the
|
|
14
|
+
* next legitimate domain anyone added failed the hygiene audit no matter how
|
|
15
|
+
* small it was. Adding four commands under `api-keys` measured 201. A guard
|
|
16
|
+
* pinned to the current total stops expressing "keep the first read cheap" and
|
|
17
|
+
* starts expressing "do not add topics", which is not what it is for.
|
|
18
|
+
*
|
|
19
|
+
* Raised with headroom rather than to exactly fit, so the next person does not
|
|
20
|
+
* have to make this same judgment for one token. If it is reached again, the
|
|
21
|
+
* better question is whether the new commands have a natural home in an
|
|
22
|
+
* existing domain — folding is preferable to a new topic when one exists — and
|
|
23
|
+
* only then whether the bound is still the right size.
|
|
24
|
+
*/
|
|
25
|
+
export declare const USAGE_OVERVIEW_TOKEN_BUDGET = 240;
|
|
10
26
|
export declare const USAGE_DOMAIN_TOKEN_BUDGET = 500;
|
|
11
27
|
export type UsageCommand = {
|
|
12
28
|
command: string;
|
|
@@ -17,7 +17,23 @@ const command_manifest_1 = require("./command-manifest");
|
|
|
17
17
|
* domain. These smaller views are derived from that same manifest; there is no
|
|
18
18
|
* second, hand-maintained command catalogue to drift from the binary.
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* A bound on an agent's FIRST read, not an inventory of today's topics.
|
|
22
|
+
*
|
|
23
|
+
* The overview is one header line plus every domain name, so its cost grows
|
|
24
|
+
* linearly with the topic count — and it had reached exactly 200, meaning the
|
|
25
|
+
* next legitimate domain anyone added failed the hygiene audit no matter how
|
|
26
|
+
* small it was. Adding four commands under `api-keys` measured 201. A guard
|
|
27
|
+
* pinned to the current total stops expressing "keep the first read cheap" and
|
|
28
|
+
* starts expressing "do not add topics", which is not what it is for.
|
|
29
|
+
*
|
|
30
|
+
* Raised with headroom rather than to exactly fit, so the next person does not
|
|
31
|
+
* have to make this same judgment for one token. If it is reached again, the
|
|
32
|
+
* better question is whether the new commands have a natural home in an
|
|
33
|
+
* existing domain — folding is preferable to a new topic when one exists — and
|
|
34
|
+
* only then whether the bound is still the right size.
|
|
35
|
+
*/
|
|
36
|
+
exports.USAGE_OVERVIEW_TOKEN_BUDGET = 240;
|
|
21
37
|
exports.USAGE_DOMAIN_TOKEN_BUDGET = 500;
|
|
22
38
|
const GENERIC_FLAGS = new Set(['bare', 'help', 'json', 'token', 'workspace']);
|
|
23
39
|
/**
|