@skrr-ai/cli 0.1.102 → 0.1.103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-command.js +24 -0
- package/dist/commands/agent/message/send.js +6 -2
- package/dist/commands/agents/triggers/create.js +7 -17
- package/dist/commands/agents/triggers/update.js +41 -28
- package/dist/commands/commitments/preflight.js +18 -1
- package/dist/commands/commitments/roster.d.ts +15 -0
- package/dist/commands/commitments/roster.js +39 -0
- package/dist/commands/commitments/show.js +1 -1
- package/dist/commands/commitments/status.d.ts +17 -0
- package/dist/commands/commitments/status.js +41 -0
- package/dist/commands/commitments/update.js +12 -0
- package/dist/commands/daemon/logs.d.ts +39 -1
- package/dist/commands/daemon/logs.js +140 -13
- package/dist/commands/followups/checkin.js +46 -3
- package/dist/commands/tasks/approvals/resolve.d.ts +12 -0
- package/dist/commands/tasks/approvals/resolve.js +21 -5
- package/dist/commands/triggers/create.js +8 -17
- package/dist/commands/triggers/fire.js +3 -0
- package/dist/commands/triggers/update.js +41 -27
- package/dist/commands/widgets/check.d.ts +39 -0
- package/dist/commands/widgets/check.js +179 -0
- package/dist/lib/agent-mailbox.d.ts +0 -1
- package/dist/lib/agent-mailbox.js +0 -1
- package/dist/lib/commitment-loop-status.d.ts +16 -0
- package/dist/lib/commitment-loop-status.js +164 -0
- package/dist/lib/commitments.d.ts +28 -1
- package/dist/lib/commitments.js +184 -5
- package/dist/lib/delegated-cli.d.ts +23 -1
- package/dist/lib/delegated-cli.js +61 -4
- package/dist/lib/first-party-harness.d.ts +1 -1
- package/dist/lib/first-party-harness.js +1 -1
- package/dist/lib/session-task-write.d.ts +13 -0
- package/dist/lib/session-task-write.js +63 -3
- package/dist/lib/triggers.d.ts +26 -0
- package/dist/lib/triggers.js +134 -1
- package/dist/lib/widgetCheck.d.ts +123 -0
- package/dist/lib/widgetCheck.js +998 -0
- package/dist/lib/widgetStaticScan.d.ts +111 -0
- package/dist/lib/widgetStaticScan.js +833 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.d.ts +9 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/deviceIdentityBridge.js +12 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.d.ts +9 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/deviceIdentityBridge.js +12 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +11902 -8696
- package/oclif.manifest.json +218 -5
- package/package.json +2 -2
package/dist/lib/triggers.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.triggerApi = exports.AgentTriggerScopeError = exports.SCOPE_IMPLIED_REF_KEY = exports.TRIGGER_EVENT_CATALOG = exports.TRIGGER_EVENT_ENTITY_TYPES = exports.TRIGGER_CHAT_AUTH_MODES = exports.TRIGGER_CHAT_RESPONSE_MODES = exports.TRIGGER_CHAT_MODES = exports.TRIGGER_FORM_RESPONSE_MODES = exports.TRIGGER_CONCURRENCY_POLICIES = exports.TRIGGER_EVENT_FILTER_MODES = exports.TRIGGER_EXECUTOR_MODES = exports.TRIGGER_SCOPE_KINDS = exports.TRIGGER_KINDS = void 0;
|
|
3
|
+
exports.triggerApi = exports.AgentTriggerScopeError = exports.FLAG_OWNER_KINDS = exports.SCOPE_IMPLIED_REF_KEY = exports.TRIGGER_EVENT_CATALOG = exports.TRIGGER_EVENT_ENTITY_TYPES = exports.TRIGGER_CHAT_AUTH_MODES = exports.TRIGGER_CHAT_RESPONSE_MODES = exports.TRIGGER_CHAT_MODES = exports.TRIGGER_FORM_RESPONSE_MODES = exports.TRIGGER_CONCURRENCY_POLICIES = exports.TRIGGER_EVENT_FILTER_MODES = exports.TRIGGER_EXECUTOR_MODES = exports.TRIGGER_SCOPE_KINDS = exports.TRIGGER_KINDS = void 0;
|
|
4
4
|
exports.validateEventReference = validateEventReference;
|
|
5
5
|
exports.validateEventFilter = validateEventFilter;
|
|
6
6
|
exports.serverEventCatalogIncludes = serverEventCatalogIncludes;
|
|
@@ -13,6 +13,8 @@ exports.buildScheduleConfigFromFlags = buildScheduleConfigFromFlags;
|
|
|
13
13
|
exports.assertScheduleTimingShape = assertScheduleTimingShape;
|
|
14
14
|
exports.buildOnceConfigFromFlags = buildOnceConfigFromFlags;
|
|
15
15
|
exports.buildSelfScheduledConfigFromFlags = buildSelfScheduledConfigFromFlags;
|
|
16
|
+
exports.buildEventConfigFromFlags = buildEventConfigFromFlags;
|
|
17
|
+
exports.buildStochasticConfigFromFlags = buildStochasticConfigFromFlags;
|
|
16
18
|
exports.buildFormConfigFromFlags = buildFormConfigFromFlags;
|
|
17
19
|
exports.buildChatMessageConfigFromFlags = buildChatMessageConfigFromFlags;
|
|
18
20
|
exports.parseExecutionReferences = parseExecutionReferences;
|
|
@@ -21,6 +23,8 @@ exports.assertEmbeddedActionTokensBound = assertEmbeddedActionTokensBound;
|
|
|
21
23
|
exports.setDefined = setDefined;
|
|
22
24
|
exports.mergeObjectField = mergeObjectField;
|
|
23
25
|
exports.mergeTriggerKindConfig = mergeTriggerKindConfig;
|
|
26
|
+
exports.assertKindFlagsApply = assertKindFlagsApply;
|
|
27
|
+
exports.describeScheduledFire = describeScheduledFire;
|
|
24
28
|
exports.withQuery = withQuery;
|
|
25
29
|
exports.agentScope = agentScope;
|
|
26
30
|
exports.spaceSubscriberScope = spaceSubscriberScope;
|
|
@@ -461,6 +465,29 @@ function buildSelfScheduledConfigFromFlags(flags) {
|
|
|
461
465
|
});
|
|
462
466
|
return selfScheduled;
|
|
463
467
|
}
|
|
468
|
+
function buildEventConfigFromFlags(flags, filterValues) {
|
|
469
|
+
const event = {};
|
|
470
|
+
setDefined(event, {
|
|
471
|
+
entityType: flags.entity,
|
|
472
|
+
eventType: flags.event,
|
|
473
|
+
filterMode: flags['filter-mode'],
|
|
474
|
+
filterField: flags['filter-field'],
|
|
475
|
+
filterValue: filterValues && filterValues.length > 1 ? filterValues : filterValues?.[0],
|
|
476
|
+
debounceMs: flags['debounce-ms'],
|
|
477
|
+
maxPerHour: flags['max-per-hour'],
|
|
478
|
+
});
|
|
479
|
+
return event;
|
|
480
|
+
}
|
|
481
|
+
function buildStochasticConfigFromFlags(flags) {
|
|
482
|
+
const stochastic = {};
|
|
483
|
+
setDefined(stochastic, {
|
|
484
|
+
probability: flags.probability === undefined ? undefined : Number(flags.probability),
|
|
485
|
+
jitterMs: flags['jitter-ms'],
|
|
486
|
+
maxFiresPerDay: flags['max-fires-per-day'],
|
|
487
|
+
evalIntervalMinutes: flags['eval-interval-minutes'],
|
|
488
|
+
});
|
|
489
|
+
return stochastic;
|
|
490
|
+
}
|
|
464
491
|
function buildFormConfigFromFlags(flags) {
|
|
465
492
|
const form = {};
|
|
466
493
|
const fields = parseJsonArray(flags['form-fields'], '--form-fields');
|
|
@@ -633,6 +660,112 @@ function mergeTriggerKindConfig(target, kind, configs) {
|
|
|
633
660
|
return;
|
|
634
661
|
mergeObjectField(target, key, configs[key]);
|
|
635
662
|
}
|
|
663
|
+
/**
|
|
664
|
+
* The kinds whose config block each kind-specific flag fills. A flag that is not listed
|
|
665
|
+
* (--label, --mode, --prompt, --concurrency-key …) belongs to every kind.
|
|
666
|
+
*
|
|
667
|
+
* `mergeTriggerKindConfig` keeps only the block the chosen kind owns, so a flag for another
|
|
668
|
+
* kind used to be accepted and thrown away: `--max-fires-per-day 1` on an on_demand trigger
|
|
669
|
+
* stored no cap, `preflight` said `no_cap`, and the second fire still ran (OSK-15491).
|
|
670
|
+
* Declared beside the builders above, which are what read these flags.
|
|
671
|
+
*/
|
|
672
|
+
exports.FLAG_OWNER_KINDS = Object.freeze({
|
|
673
|
+
cron: ['schedule'],
|
|
674
|
+
'interval-ms': ['schedule'],
|
|
675
|
+
'interval-minutes': ['schedule'],
|
|
676
|
+
'daily-time': ['schedule'],
|
|
677
|
+
'max-runs': ['schedule'],
|
|
678
|
+
'end-at': ['schedule'],
|
|
679
|
+
'stale-catchup-ms': ['schedule'],
|
|
680
|
+
timezone: ['schedule', 'once'],
|
|
681
|
+
'max-fires-per-day': ['schedule', 'stochastic', 'self_scheduled'],
|
|
682
|
+
at: ['once'],
|
|
683
|
+
'next-run-at': ['once', 'self_scheduled'],
|
|
684
|
+
entity: ['event'],
|
|
685
|
+
event: ['event'],
|
|
686
|
+
'filter-mode': ['event'],
|
|
687
|
+
'filter-field': ['event'],
|
|
688
|
+
'filter-value': ['event'],
|
|
689
|
+
'debounce-ms': ['event'],
|
|
690
|
+
'max-per-hour': ['event'],
|
|
691
|
+
probability: ['stochastic'],
|
|
692
|
+
'jitter-ms': ['stochastic'],
|
|
693
|
+
'eval-interval-minutes': ['stochastic'],
|
|
694
|
+
'form-title': ['form'],
|
|
695
|
+
'form-subtitle': ['form'],
|
|
696
|
+
'form-fields': ['form'],
|
|
697
|
+
'form-response-mode': ['form'],
|
|
698
|
+
'thank-you-message': ['form'],
|
|
699
|
+
'redirect-url': ['form'],
|
|
700
|
+
'ip-allowlist': ['form'],
|
|
701
|
+
'ignore-bots': ['form'],
|
|
702
|
+
'submit-button-label': ['form'],
|
|
703
|
+
'chat-mode': ['chat_message'],
|
|
704
|
+
'chat-response-mode': ['chat_message'],
|
|
705
|
+
'allowed-origin': ['chat_message'],
|
|
706
|
+
'allow-file-uploads': ['chat_message'],
|
|
707
|
+
'allowed-mime-types': ['chat_message'],
|
|
708
|
+
'initial-message': ['chat_message'],
|
|
709
|
+
'suggested-prompt': ['chat_message'],
|
|
710
|
+
'input-placeholder': ['chat_message'],
|
|
711
|
+
'auth-mode': ['chat_message'],
|
|
712
|
+
'load-previous-session': ['chat_message'],
|
|
713
|
+
'chat-title': ['chat_message'],
|
|
714
|
+
'chat-subtitle': ['chat_message'],
|
|
715
|
+
});
|
|
716
|
+
const flagWasPassed = (value) => value !== undefined && value !== null && !(Array.isArray(value) && value.length === 0);
|
|
717
|
+
/**
|
|
718
|
+
* Refuse a kind-specific flag the trigger's kind cannot use, naming each one and the kinds that
|
|
719
|
+
* take it. Silence here is the defect: the caller believes a limit is in force.
|
|
720
|
+
*/
|
|
721
|
+
function assertKindFlagsApply(kind, flags, options = {}) {
|
|
722
|
+
if (typeof kind !== 'string' || !(kind in CONFIG_KEY_BY_TRIGGER_KIND))
|
|
723
|
+
return;
|
|
724
|
+
const misplaced = Object.entries(exports.FLAG_OWNER_KINDS).filter(([flag, owners]) => flagWasPassed(flags[flag]) && !owners.includes(kind));
|
|
725
|
+
if (misplaced.length === 0)
|
|
726
|
+
return;
|
|
727
|
+
const named = misplaced.map(([flag, owners]) => `--${flag} (${owners.join(', ')})`);
|
|
728
|
+
const verb = misplaced.length === 1 ? 'does' : 'do';
|
|
729
|
+
let subject = `--kind ${kind}`;
|
|
730
|
+
let fix = ' Remove it, or choose a kind that takes it.';
|
|
731
|
+
const holdsNothing = !CONFIG_KEY_BY_TRIGGER_KIND[kind];
|
|
732
|
+
if (options.kindIsFixed) {
|
|
733
|
+
subject = `this trigger, whose kind is ${kind}`;
|
|
734
|
+
fix = ' A trigger kind cannot be changed after creation, so remove it.';
|
|
735
|
+
if (holdsNothing)
|
|
736
|
+
fix = ` An ${kind} trigger has no per-trigger settings.${fix}`;
|
|
737
|
+
}
|
|
738
|
+
else if (holdsNothing) {
|
|
739
|
+
fix = ` An ${kind} trigger has no per-trigger settings; remove it, or choose a kind that takes it.`;
|
|
740
|
+
}
|
|
741
|
+
throw new Error(`${named.join(', ')} ${verb} not apply to ${subject}.${fix}`);
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* The sentence for a fire's `scheduledFire` report: what a MANUAL fire skipped that a scheduled
|
|
745
|
+
* one would not. A manual fire is exempt from the enabled gate, the working/quiet-hours overlay and
|
|
746
|
+
* the autonomy ladder, so on its own it certifies nothing about whether the trigger will ever fire
|
|
747
|
+
* by itself (OSK-15492). Absent when the server reported nothing to say.
|
|
748
|
+
*/
|
|
749
|
+
function describeScheduledFire(result) {
|
|
750
|
+
const report = result.scheduledFire;
|
|
751
|
+
if (typeof report !== 'object' || report === null)
|
|
752
|
+
return undefined;
|
|
753
|
+
const { wouldRun, reason, bypassed } = report;
|
|
754
|
+
const why = typeof reason === 'string' && reason ? ` (${reason})` : '';
|
|
755
|
+
if (Array.isArray(bypassed) && bypassed.length > 0) {
|
|
756
|
+
const gates = bypassed
|
|
757
|
+
.map((entry) => `${String(entry.gate)}${entry.reason ? ` (${String(entry.reason)})` : ''}`)
|
|
758
|
+
.join(', ');
|
|
759
|
+
return `Note: this manual fire bypassed ${gates}; a scheduled fire would not run.`;
|
|
760
|
+
}
|
|
761
|
+
if (wouldRun === false) {
|
|
762
|
+
return `Note: a scheduled fire would not run${why}; a manual fire is exempt from that check.`;
|
|
763
|
+
}
|
|
764
|
+
if (wouldRun === null) {
|
|
765
|
+
return `Note: whether a scheduled fire would run could not be determined${why}.`;
|
|
766
|
+
}
|
|
767
|
+
return undefined;
|
|
768
|
+
}
|
|
636
769
|
function withQuery(path, params) {
|
|
637
770
|
const search = new URLSearchParams();
|
|
638
771
|
for (const [key, value] of Object.entries(params)) {
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { type RenderUiWidgetFenceInput } from '@skrr-ai/data-provider';
|
|
2
|
+
export declare const WIDGET_CHECK_REPORT_VERSION: 1;
|
|
3
|
+
export type WidgetIssueSeverity = 'error' | 'warn';
|
|
4
|
+
export type WidgetIssueSource = 'grammar' | 'schema' | 'limit' | 'syntax' | 'static' | 'content';
|
|
5
|
+
export interface WidgetIssue {
|
|
6
|
+
severity: WidgetIssueSeverity;
|
|
7
|
+
source: WidgetIssueSource;
|
|
8
|
+
/** Stable machine code, for example `fence/invalid-header` or `static/network-api`. */
|
|
9
|
+
code: string;
|
|
10
|
+
message: string;
|
|
11
|
+
fix?: string;
|
|
12
|
+
/** The part of the widget the finding is about: a section, `header`, `title`, `total`. */
|
|
13
|
+
section?: string;
|
|
14
|
+
/**
|
|
15
|
+
* 1-based. For a `grammar` finding: the line of the INPUT. For a section-level
|
|
16
|
+
* finding (syntax, static): the line within that section's own text.
|
|
17
|
+
*/
|
|
18
|
+
line?: number;
|
|
19
|
+
/** True for static findings: a guess from reading the source, not the sandbox's verdict. */
|
|
20
|
+
heuristic?: true;
|
|
21
|
+
}
|
|
22
|
+
export type LimitKey = 'css' | 'html' | 'js' | 'total' | 'title' | 'fallback';
|
|
23
|
+
export interface WidgetUsage {
|
|
24
|
+
/** Characters (UTF-16 code units): what every limit measures. */
|
|
25
|
+
used: number;
|
|
26
|
+
max: number;
|
|
27
|
+
/** Not clamped: a widget at 207% of its limit says 207. */
|
|
28
|
+
percent: number;
|
|
29
|
+
over: boolean;
|
|
30
|
+
/** Set when the parser stopped counting at the cap, so `used` is a floor. */
|
|
31
|
+
atLeast?: true;
|
|
32
|
+
}
|
|
33
|
+
export type WidgetKind = 'fence' | 'payload' | 'tool-input';
|
|
34
|
+
export interface WidgetReport {
|
|
35
|
+
id: string;
|
|
36
|
+
title: string | null;
|
|
37
|
+
kind: WidgetKind;
|
|
38
|
+
/** Fence input only: the line of the input where this block starts. */
|
|
39
|
+
line?: number;
|
|
40
|
+
/** The widget is final (`complete: true`); false for a refused or cut-off block. */
|
|
41
|
+
complete: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* False when the content was never read (a refused header, a block past the
|
|
44
|
+
* per-message cap): `bytes` and `limits` are then zeros that mean "unknown",
|
|
45
|
+
* not "empty".
|
|
46
|
+
*/
|
|
47
|
+
measured: boolean;
|
|
48
|
+
/** The ingest would persist it. A refused widget shows an error state instead. */
|
|
49
|
+
accepted: boolean;
|
|
50
|
+
/** Accepted AND no error-severity finding (and no warning under `strict`). */
|
|
51
|
+
ok: boolean;
|
|
52
|
+
/** UTF-8 bytes, for information. The limits count characters. */
|
|
53
|
+
bytes: {
|
|
54
|
+
css: number;
|
|
55
|
+
html: number;
|
|
56
|
+
js: number;
|
|
57
|
+
total: number;
|
|
58
|
+
};
|
|
59
|
+
limits: Record<LimitKey, WidgetUsage>;
|
|
60
|
+
issues: WidgetIssue[];
|
|
61
|
+
}
|
|
62
|
+
export interface WidgetCheckError {
|
|
63
|
+
code: string;
|
|
64
|
+
message: string;
|
|
65
|
+
fix?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface WidgetCheckReport {
|
|
68
|
+
reportVersion: typeof WIDGET_CHECK_REPORT_VERSION;
|
|
69
|
+
/** Every widget would be accepted and none has an error-severity finding. */
|
|
70
|
+
ok: boolean;
|
|
71
|
+
format: 'fence' | 'json' | 'unknown';
|
|
72
|
+
widgets: WidgetReport[];
|
|
73
|
+
/** Problems with the input as a whole (nothing to check, unreadable JSON, too large). */
|
|
74
|
+
errors: WidgetCheckError[];
|
|
75
|
+
/** Notes about the input as a whole that do not refuse anything. */
|
|
76
|
+
warnings: WidgetCheckError[];
|
|
77
|
+
summary: {
|
|
78
|
+
widgets: number;
|
|
79
|
+
accepted: number;
|
|
80
|
+
ok: number;
|
|
81
|
+
errors: number;
|
|
82
|
+
warnings: number;
|
|
83
|
+
};
|
|
84
|
+
heuristic: string;
|
|
85
|
+
}
|
|
86
|
+
export declare const WIDGET_CHECK_HEURISTIC_NOTE: string;
|
|
87
|
+
/** More than this is refused unread: six widgets at their caps are about 1.2 MB. */
|
|
88
|
+
export declare const WIDGET_CHECK_MAX_INPUT_CHARS: number;
|
|
89
|
+
export type WidgetCheckFormat = 'auto' | 'fence' | 'json';
|
|
90
|
+
export interface WidgetCheckOptions {
|
|
91
|
+
format?: WidgetCheckFormat;
|
|
92
|
+
/** Warnings also make the check fail. */
|
|
93
|
+
strict?: boolean;
|
|
94
|
+
}
|
|
95
|
+
export interface WidgetCheckResult {
|
|
96
|
+
report: WidgetCheckReport;
|
|
97
|
+
/** What `--render-fence` may serialise: only widgets the schema accepted, by index. */
|
|
98
|
+
renderable: Array<{
|
|
99
|
+
index: number;
|
|
100
|
+
input: RenderUiWidgetFenceInput;
|
|
101
|
+
}>;
|
|
102
|
+
}
|
|
103
|
+
/** The report for an input that could not even be read (a missing file, a terminal as stdin). */
|
|
104
|
+
export declare function inputErrorReport(error: WidgetCheckError): WidgetCheckReport;
|
|
105
|
+
/**
|
|
106
|
+
* Check one input: a file's text that contains a widget block, or a JSON widget.
|
|
107
|
+
* Total: never throws, whatever the input.
|
|
108
|
+
*/
|
|
109
|
+
export declare function checkWidgetInput(raw: string, options?: WidgetCheckOptions): WidgetCheckResult;
|
|
110
|
+
export interface RenderedFences {
|
|
111
|
+
fences: string[];
|
|
112
|
+
errors: WidgetCheckError[];
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Serialise the JSON widgets that passed the schema to correctly delimited fence
|
|
116
|
+
* blocks, and prove each one: the block is parsed back with the same parser the
|
|
117
|
+
* ingest uses and must yield the same title, sections and fallback. The colon
|
|
118
|
+
* count is chosen by `renderUiWidgetFence`, so a widget whose code contains a line
|
|
119
|
+
* of colons still gets a closing line it cannot end early.
|
|
120
|
+
*/
|
|
121
|
+
export declare function renderWidgetFences(result: WidgetCheckResult): RenderedFences;
|
|
122
|
+
/** The report as lines of plain text, for a person or a model reading a terminal. */
|
|
123
|
+
export declare function formatWidgetCheckReport(report: WidgetCheckReport): string[];
|