@kafca/agentdock 0.1.58 → 0.1.62

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.
Files changed (127) hide show
  1. package/README.md +18 -0
  2. package/dist/renderer/assets/AutomationList-BgJgAdVO.js +16 -0
  3. package/dist/renderer/assets/{Badge-BfY1VaHS.js → Badge-Bq2hPVcR.js} +1 -1
  4. package/dist/renderer/assets/{Card-DWA_Tww_.js → Card-BPJNSZce.js} +1 -1
  5. package/dist/renderer/assets/{Config-nHj3g1U5.js → Config-aSFqlI88.js} +2 -2
  6. package/dist/renderer/assets/Dashboard-D3ezFmb7.js +36 -0
  7. package/dist/renderer/assets/{EmptyState-zatDjLj_.js → EmptyState-DK496gBq.js} +1 -1
  8. package/dist/renderer/assets/{HighlightedMarkdown-CsM5n70d.js → HighlightedMarkdown-Ckre5jNv.js} +1 -1
  9. package/dist/renderer/assets/{Input-R1XdFK1K.js → Input-C5C1d0ba.js} +1 -1
  10. package/dist/renderer/assets/{KnowledgeDetail-Co5sxeGd.js → KnowledgeDetail-N8Ey1ikc.js} +2 -2
  11. package/dist/renderer/assets/{KnowledgeHome-DwziPw5m.js → KnowledgeHome-9aF8nJEf.js} +2 -2
  12. package/dist/renderer/assets/{Logs-NwZUtR_G.js → Logs-sgAdwEeS.js} +2 -2
  13. package/dist/renderer/assets/{Modal-CrcIwIFL.js → Modal-BB10hTRc.js} +3 -3
  14. package/dist/renderer/assets/{Page-Dp0obeSw.js → Page-DfC319Ck.js} +1 -1
  15. package/dist/renderer/assets/{Select-6mVQaf84.js → Select-RHJBmNER.js} +1 -1
  16. package/dist/renderer/assets/{ThreadChat-BFzbn3L6.js → ThreadChat-BU1zCdr4.js} +3 -3
  17. package/dist/renderer/assets/{Workspace-DCmo8BMm.js → Workspace-BoZCz7S8.js} +1 -1
  18. package/dist/renderer/assets/{arrow-left-9rjg_Hp4.js → arrow-left-D2V1eZSD.js} +1 -1
  19. package/dist/renderer/assets/{book-open-Bu8GCHnG.js → book-open-DUcBn7Bb.js} +1 -1
  20. package/dist/renderer/assets/{channels-BxVbG-6j.js → channels-DMhDSlf2.js} +2 -2
  21. package/dist/renderer/assets/{chevron-down-BE8uQmWM.js → chevron-down-Ca2FQDB7.js} +1 -1
  22. package/dist/renderer/assets/en-Bnr4nMzg.js +1 -0
  23. package/dist/renderer/assets/es-B1GIFh3i.js +1 -0
  24. package/dist/renderer/assets/{index-BIKL3fTP.css → index-B6WcpkJF.css} +1 -1
  25. package/dist/renderer/assets/{index-B7TeF6Es.js → index-BlnvlekJ.js} +1 -1
  26. package/dist/renderer/assets/index-DRJ5wgw_.js +162 -0
  27. package/dist/renderer/assets/ja-CDWPWqEW.js +1 -0
  28. package/dist/renderer/assets/{knowledge-Kl19SqGS.js → knowledge-D1-k56eY.js} +1 -1
  29. package/dist/renderer/assets/{pencil-CPB7SK1m.js → pencil-BhWdv_86.js} +1 -1
  30. package/dist/renderer/assets/{plus-Bt26z-4q.js → plus-BacLMlK3.js} +1 -1
  31. package/dist/renderer/assets/{save-Une7GMxT.js → save-Bpoxbzau.js} +1 -1
  32. package/dist/renderer/assets/{search-DE0agJjJ.js → search-BVJcpdFX.js} +1 -1
  33. package/dist/renderer/assets/{shield-check-De7xaXZh.js → shield-check-C2cw_Ip6.js} +1 -1
  34. package/dist/renderer/assets/{threads-BnsNL5ei.js → threads-DOsBQBg_.js} +1 -1
  35. package/dist/renderer/assets/{trash-2-6iGF59Ac.js → trash-2-Bs3rEm3g.js} +1 -1
  36. package/dist/renderer/assets/zh-MSddxMDX.js +1 -0
  37. package/dist/renderer/assets/zh-TW-C_LNWX0o.js +1 -0
  38. package/dist/renderer/index.html +2 -2
  39. package/dist-electron/electron/managed-skills/agent-browser/SKILL.md +41 -0
  40. package/dist-electron/electron/managed-skills/agent-browser/references/authentication.md +83 -0
  41. package/dist-electron/electron/managed-skills/agent-browser/references/commands.md +50 -0
  42. package/dist-electron/electron/managed-skills/agent-browser/references/profiling.md +20 -0
  43. package/dist-electron/electron/managed-skills/agent-browser/references/proxy-support.md +18 -0
  44. package/dist-electron/electron/managed-skills/agent-browser/references/session-management.md +17 -0
  45. package/dist-electron/electron/managed-skills/agent-browser/references/snapshot-refs.md +17 -0
  46. package/dist-electron/electron/managed-skills/agent-browser/references/video-recording.md +21 -0
  47. package/dist-electron/electron/managed-skills/agent-browser/templates/authenticated-session.sh +11 -0
  48. package/dist-electron/electron/managed-skills/agent-browser/templates/capture-workflow.sh +12 -0
  49. package/dist-electron/electron/managed-skills/agent-browser/templates/form-automation.sh +10 -0
  50. package/dist-electron/electron/managed-skills/condition-trigger/SKILL.md +21 -0
  51. package/dist-electron/electron/managed-skills/condition-trigger/scripts/register-condition-trigger.sh +106 -0
  52. package/dist-electron/electron/managed-skills/knowledge-base/SKILL.md +13 -0
  53. package/dist-electron/electron/managed-skills/knowledge-base/scripts/search-knowledge.sh +80 -0
  54. package/dist-electron/packages/contracts/src/automations.js +211 -0
  55. package/dist-electron/packages/contracts/src/index.js +1 -0
  56. package/dist-electron/packages/core-sdk/src/automations.js +87 -0
  57. package/dist-electron/packages/core-sdk/src/client.js +101 -0
  58. package/dist-electron/packages/core-sdk/src/index.js +2 -1
  59. package/dist-electron/services/local-ai-core/src/acp/store/automation-script-store.js +415 -0
  60. package/dist-electron/services/local-ai-core/src/acp/store/automation-store.js +829 -0
  61. package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +158 -0
  62. package/dist-electron/services/local-ai-core/src/acp/store/schema.js +81 -0
  63. package/dist-electron/services/local-ai-core/src/automation/automation-action-executor.js +144 -0
  64. package/dist-electron/services/local-ai-core/src/automation/automation-condition-engine.js +79 -0
  65. package/dist-electron/services/local-ai-core/src/automation/automation-conversation-executor.js +39 -73
  66. package/dist-electron/services/local-ai-core/src/automation/automation-monitor-service.js +695 -260
  67. package/dist-electron/services/local-ai-core/src/automation/automation-script-service.js +507 -0
  68. package/dist-electron/services/local-ai-core/src/automation/automation-service.js +1019 -0
  69. package/dist-electron/services/local-ai-core/src/automation/automation-trigger-engine.js +141 -0
  70. package/dist-electron/services/local-ai-core/src/automation/condition-evaluator.js +60 -17
  71. package/dist-electron/services/local-ai-core/src/automation/legacy-automation-mappers.js +286 -0
  72. package/dist-electron/services/local-ai-core/src/automation/scripts/anthropic-sandbox-runner.js +792 -0
  73. package/dist-electron/services/local-ai-core/src/automation/scripts/sandbox-runner.js +2 -0
  74. package/dist-electron/services/local-ai-core/src/automation/scripts/script-package.js +475 -0
  75. package/dist-electron/services/local-ai-core/src/automation/scripts/script-protocol-runner.js +266 -0
  76. package/dist-electron/services/local-ai-core/src/automation/scripts/secret-resolver.js +37 -0
  77. package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-poller.js +1 -2
  78. package/dist-electron/services/local-ai-core/src/channel/weixin/transport.js +9 -8
  79. package/dist-electron/services/local-ai-core/src/cli/lac.js +229 -0
  80. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +21 -0
  81. package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +76 -0
  82. package/dist-electron/services/local-ai-core/src/runtime/handlers/automations-handler.js +322 -0
  83. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +20 -0
  84. package/dist-electron/services/local-ai-core/src/runtime/managed-skill-catalog.js +37 -0
  85. package/dist-electron/services/local-ai-core/src/runtime/server-helpers.js +14 -4
  86. package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +75 -0
  87. package/dist-electron/services/local-ai-core/src/runtime/server.js +21 -0
  88. package/dist-electron/services/local-ai-core/src/runtime/standalone.js +1 -0
  89. package/dist-electron/services/local-ai-core/src/scheduler/cron.js +151 -39
  90. package/dist-electron/services/local-ai-core/src/scheduler/scheduled-conversation-executor.js +2 -4
  91. package/dist-electron/services/local-ai-core/src/scheduler/scheduled-job-application-service.js +64 -12
  92. package/dist-electron/services/local-ai-core/src/scheduler/scheduler-service.js +71 -4
  93. package/dist-electron/services/local-ai-core/src/scheduler/thread-resolution.js +10 -0
  94. package/dist-electron/services/local-ai-core/src/thread/agent-message-policy.js +16 -1
  95. package/dist-electron/src/pages/Automation/automation-page-model.js +76 -0
  96. package/dist-electron/tests/contracts/agent-message-policy.test.js +32 -0
  97. package/dist-electron/tests/contracts/architecture-docs.test.js +30 -0
  98. package/dist-electron/tests/contracts/automation-contracts.test.js +154 -0
  99. package/dist-electron/tests/contracts/automation-renderer-model.test.js +47 -0
  100. package/dist-electron/tests/electron/automation-action-executor.test.js +75 -0
  101. package/dist-electron/tests/electron/automation-compatibility.test.js +463 -0
  102. package/dist-electron/tests/electron/automation-deployment.test.js +66 -0
  103. package/dist-electron/tests/electron/automation-engine.test.js +264 -0
  104. package/dist-electron/tests/electron/automation-monitor.test.js +1333 -0
  105. package/dist-electron/tests/electron/automation-sandbox-runner.test.js +333 -0
  106. package/dist-electron/tests/electron/automation-script-approval.test.js +553 -0
  107. package/dist-electron/tests/electron/automation-script-package.test.js +499 -0
  108. package/dist-electron/tests/electron/automation-script-runner.test.js +120 -0
  109. package/dist-electron/tests/electron/automation-service.test.js +1078 -0
  110. package/dist-electron/tests/electron/automation-store.test.js +593 -0
  111. package/dist-electron/tests/electron/condition-trigger-skill.test.js +93 -0
  112. package/dist-electron/tests/electron/core-client.test.js +99 -0
  113. package/dist-electron/tests/electron/lac-cli.test.js +110 -0
  114. package/dist-electron/tests/electron/workspace-task-store.test.js +25 -0
  115. package/dist-electron/tests/integration/automation-routes.test.js +186 -0
  116. package/dist-electron/tests/integration/automation-sandbox-runtime.test.js +92 -0
  117. package/package.json +5 -6
  118. package/dist/renderer/assets/CronList-BwkA_I7v.js +0 -1
  119. package/dist/renderer/assets/Dashboard-D0_A7k02.js +0 -41
  120. package/dist/renderer/assets/MonitorList-CS1uLS5A.js +0 -1
  121. package/dist/renderer/assets/en-CmAr_0e6.js +0 -1
  122. package/dist/renderer/assets/es-Cs9x52ca.js +0 -1
  123. package/dist/renderer/assets/index-BkI9POxj.js +0 -167
  124. package/dist/renderer/assets/ja-DtvtBRTW.js +0 -1
  125. package/dist/renderer/assets/play-DGAO4OCu.js +0 -6
  126. package/dist/renderer/assets/zh-CcJ9vBZj.js +0 -1
  127. package/dist/renderer/assets/zh-TW-elI72AC1.js +0 -1
@@ -0,0 +1,80 @@
1
+ #!/bin/sh
2
+ set -u
3
+
4
+ API_BASE="${KNOWLEDGE_API_BASE_URL:-http://127.0.0.1:9831/api/local/v1}"
5
+ LIMIT="${KNOWLEDGE_SEARCH_LIMIT:-5}"
6
+
7
+ escape_json() {
8
+ printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'
9
+ }
10
+
11
+ print_results() {
12
+ KB_ID="$1"
13
+ RESPONSE="$2"
14
+ RESPONSE_JSON="$RESPONSE" KB_ID="$KB_ID" node <<'NODE'
15
+ const responseText = process.env.RESPONSE_JSON || '';
16
+ const kbId = process.env.KB_ID || 'unknown';
17
+
18
+ try {
19
+ const payload = JSON.parse(responseText);
20
+ const results = Array.isArray(payload?.data?.results)
21
+ ? payload.data.results
22
+ : Array.isArray(payload?.results)
23
+ ? payload.results
24
+ : null;
25
+
26
+ if (!results) {
27
+ console.log('Error: invalid response payload');
28
+ console.log('');
29
+ process.exit(0);
30
+ }
31
+
32
+ if (results.length === 0) {
33
+ console.log('No results');
34
+ console.log('');
35
+ process.exit(0);
36
+ }
37
+
38
+ for (const item of results) {
39
+ const title = String(item?.title || kbId);
40
+ const fileName = String(item?.fileName || 'unknown');
41
+ const score = typeof item?.score === 'number' ? item.score : 0;
42
+ const snippet = String(item?.snippet || '').trim();
43
+ console.log(`- Title: ${title}`);
44
+ console.log(` File: ${fileName}`);
45
+ console.log(` Score: ${score}`);
46
+ console.log(` Snippet: ${snippet || '(empty)'}`);
47
+ }
48
+ console.log('');
49
+ } catch (error) {
50
+ console.log(`Error: ${error instanceof Error ? error.message : String(error)}`);
51
+ console.log('');
52
+ }
53
+ NODE
54
+ echo
55
+ }
56
+
57
+ if [ "$#" -lt 2 ]; then
58
+ echo "Usage: search-knowledge.sh \"<query>\" \"<kb_id_1>\" [kb_id_2 ...]" >&2
59
+ exit 1
60
+ fi
61
+
62
+ QUERY="$1"
63
+ shift
64
+ ESCAPED_QUERY=$(escape_json "$QUERY")
65
+
66
+ for KB_ID in "$@"; do
67
+ echo "=== Knowledge Base: $KB_ID ==="
68
+ RESPONSE=$(curl -fsS -X POST "$API_BASE/knowledge/bases/$KB_ID/search" \
69
+ -H 'Content-Type: application/json' \
70
+ --data "{\"query\":\"$ESCAPED_QUERY\",\"limit\":$LIMIT}" 2>&1)
71
+ STATUS=$?
72
+
73
+ if [ "$STATUS" -ne 0 ]; then
74
+ echo "Error: $RESPONSE"
75
+ echo
76
+ continue
77
+ fi
78
+
79
+ print_results "$KB_ID" "$RESPONSE"
80
+ done
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeAutomationActivation = normalizeAutomationActivation;
4
+ exports.normalizeAutomationCondition = normalizeAutomationCondition;
5
+ exports.normalizeAutomationDefinition = normalizeAutomationDefinition;
6
+ const local_core_js_1 = require("./local-core.js");
7
+ function asRecord(value, label) {
8
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
9
+ throw new Error(`${label} must be an object.`);
10
+ }
11
+ return value;
12
+ }
13
+ function requiredString(value, label) {
14
+ if (typeof value !== 'string' || !value.trim()) {
15
+ throw new Error(`${label} is required.`);
16
+ }
17
+ return value.trim();
18
+ }
19
+ function optionalString(value, label) {
20
+ if (value === undefined)
21
+ return undefined;
22
+ return requiredString(value, label);
23
+ }
24
+ function isoTimestamp(value, label) {
25
+ const normalized = requiredString(value, label);
26
+ const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/.exec(normalized);
27
+ if (!match || Number.isNaN(Date.parse(normalized))) {
28
+ throw new Error(`${label} must be a valid ISO timestamp.`);
29
+ }
30
+ const [, yearText, monthText, dayText, hourText, minuteText, secondText] = match;
31
+ const year = Number(yearText);
32
+ const month = Number(monthText);
33
+ const day = Number(dayText);
34
+ const calendarDate = new Date(Date.UTC(year, month - 1, day));
35
+ if (calendarDate.getUTCFullYear() !== year ||
36
+ calendarDate.getUTCMonth() !== month - 1 ||
37
+ calendarDate.getUTCDate() !== day ||
38
+ Number(hourText) > 23 ||
39
+ Number(minuteText) > 59 ||
40
+ Number(secondText) > 59) {
41
+ throw new Error(`${label} must be a valid ISO timestamp.`);
42
+ }
43
+ return normalized;
44
+ }
45
+ function optionalIsoTimestamp(value, label) {
46
+ if (value === undefined)
47
+ return undefined;
48
+ return isoTimestamp(value, label);
49
+ }
50
+ function nonNegativeInteger(value, label) {
51
+ if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {
52
+ throw new Error(`${label} must be a non-negative integer.`);
53
+ }
54
+ return value;
55
+ }
56
+ function normalizeAutomationExecutionMode(value) {
57
+ if (typeof value !== 'string' || !value.trim()) {
58
+ throw new Error('Automation action executionMode must be a non-empty string.');
59
+ }
60
+ const normalized = (0, local_core_js_1.normalizeScheduledJobExecutionMode)(value.trim());
61
+ if (normalized === 'same-thread')
62
+ return 'same-thread';
63
+ if (normalized === 'side-thread')
64
+ return 'side-thread';
65
+ throw new Error('Automation action executionMode must be same-thread or side-thread.');
66
+ }
67
+ function normalizeRoute(value) {
68
+ const route = asRecord(value, 'Automation delivery route');
69
+ const normalized = {
70
+ type: requiredString(route.type, 'Automation delivery route type'),
71
+ channelId: requiredString(route.channelId, 'Automation delivery route channelId'),
72
+ };
73
+ const instanceId = optionalString(route.instanceId, 'Automation delivery route instanceId');
74
+ const participantId = optionalString(route.participantId, 'Automation delivery route participantId');
75
+ const threadId = optionalString(route.threadId, 'Automation delivery route threadId');
76
+ if (instanceId)
77
+ normalized.instanceId = instanceId;
78
+ if (participantId)
79
+ normalized.participantId = participantId;
80
+ if (threadId)
81
+ normalized.threadId = threadId;
82
+ if (route.metadata !== undefined)
83
+ normalized.metadata = asRecord(route.metadata, 'Automation delivery route metadata');
84
+ return normalized;
85
+ }
86
+ function normalizeAutomationActivation(value) {
87
+ const input = asRecord(value, 'Automation activation');
88
+ switch (input.kind) {
89
+ case 'cron':
90
+ return {
91
+ kind: 'cron',
92
+ expression: requiredString(input.expression, 'Automation cron expression'),
93
+ timezone: requiredString(input.timezone, 'Automation cron timezone'),
94
+ };
95
+ case 'once':
96
+ return { kind: 'once', runAt: isoTimestamp(input.runAt, 'Automation runAt') };
97
+ case 'interval': {
98
+ const intervalMs = nonNegativeInteger(input.intervalMs, 'Automation intervalMs');
99
+ if (intervalMs === 0)
100
+ throw new Error('Automation intervalMs must be greater than zero.');
101
+ return { kind: 'interval', intervalMs };
102
+ }
103
+ case 'provider-event':
104
+ return {
105
+ kind: 'provider-event',
106
+ sourceType: requiredString(input.sourceType, 'Automation provider sourceType'),
107
+ sourceConfig: asRecord(input.sourceConfig, 'Automation provider sourceConfig'),
108
+ };
109
+ default:
110
+ throw new Error('Automation activation kind must be cron, once, interval, or provider-event.');
111
+ }
112
+ }
113
+ function normalizeAutomationCondition(value) {
114
+ const input = asRecord(value, 'Automation condition');
115
+ switch (input.kind) {
116
+ case 'always':
117
+ return { kind: 'always' };
118
+ case 'expression':
119
+ return { kind: 'expression', expression: requiredString(input.expression, 'Automation condition expression') };
120
+ case 'approved-script':
121
+ if (input.edge !== 'rising')
122
+ throw new Error('Automation approved-script edge must be rising.');
123
+ return {
124
+ kind: 'approved-script',
125
+ scriptId: requiredString(input.scriptId, 'Automation condition scriptId'),
126
+ approvedVersionId: requiredString(input.approvedVersionId, 'Automation condition approvedVersionId'),
127
+ edge: 'rising',
128
+ };
129
+ default:
130
+ throw new Error('Automation condition kind must be always, expression, or approved-script.');
131
+ }
132
+ }
133
+ function normalizeAutomationDefinition(value) {
134
+ const input = asRecord(value, 'Automation definition');
135
+ const action = asRecord(input.action, 'Automation action');
136
+ if (action.kind !== 'agent-prompt')
137
+ throw new Error('Automation action kind must be agent-prompt.');
138
+ const executionMode = normalizeAutomationExecutionMode(action.executionMode);
139
+ const delivery = asRecord(input.delivery, 'Automation delivery');
140
+ const policies = asRecord(input.policies, 'Automation policies');
141
+ if (policies.concurrency !== 'skip-if-running') {
142
+ throw new Error('Automation concurrency policy must be skip-if-running.');
143
+ }
144
+ if (input.health !== 'healthy' && input.health !== 'blocked') {
145
+ throw new Error('Automation health must be healthy or blocked.');
146
+ }
147
+ if (typeof input.enabled !== 'boolean')
148
+ throw new Error('Automation enabled must be a boolean.');
149
+ const normalized = {
150
+ id: requiredString(input.id, 'Automation id'),
151
+ workspaceId: requiredString(input.workspaceId, 'Automation workspaceId'),
152
+ title: requiredString(input.title, 'Automation title'),
153
+ enabled: input.enabled,
154
+ health: input.health,
155
+ activation: normalizeAutomationActivation(input.activation),
156
+ condition: normalizeAutomationCondition(input.condition),
157
+ action: {
158
+ kind: 'agent-prompt',
159
+ promptTemplate: requiredString(action.promptTemplate, 'Automation promptTemplate'),
160
+ executionMode,
161
+ },
162
+ delivery: {
163
+ platform: requiredString(delivery.platform, 'Automation delivery platform').toLowerCase(),
164
+ route: normalizeRoute(delivery.route),
165
+ },
166
+ policies: {
167
+ concurrency: 'skip-if-running',
168
+ cooldownMs: nonNegativeInteger(policies.cooldownMs, 'Automation cooldownMs'),
169
+ },
170
+ consecutiveEvaluationFailures: nonNegativeInteger(input.consecutiveEvaluationFailures, 'Automation consecutiveEvaluationFailures'),
171
+ createdAt: isoTimestamp(input.createdAt, 'Automation createdAt'),
172
+ updatedAt: isoTimestamp(input.updatedAt, 'Automation updatedAt'),
173
+ };
174
+ const blockedReason = optionalString(input.blockedReason, 'Automation blockedReason');
175
+ const lastEvaluationAt = optionalIsoTimestamp(input.lastEvaluationAt, 'Automation lastEvaluationAt');
176
+ const lastTriggeredAt = optionalIsoTimestamp(input.lastTriggeredAt, 'Automation lastTriggeredAt');
177
+ if (blockedReason)
178
+ normalized.blockedReason = blockedReason;
179
+ if (lastEvaluationAt)
180
+ normalized.lastEvaluationAt = lastEvaluationAt;
181
+ if (lastTriggeredAt)
182
+ normalized.lastTriggeredAt = lastTriggeredAt;
183
+ if (input.lastSuccessfulMatch !== undefined) {
184
+ if (typeof input.lastSuccessfulMatch !== 'boolean') {
185
+ throw new Error('Automation lastSuccessfulMatch must be a boolean.');
186
+ }
187
+ normalized.lastSuccessfulMatch = input.lastSuccessfulMatch;
188
+ }
189
+ if (input.originKind === 'native' ||
190
+ input.originKind === 'scheduled-job' ||
191
+ input.originKind === 'automation-monitor') {
192
+ normalized.originKind = input.originKind;
193
+ }
194
+ else if (input.originKind !== undefined) {
195
+ throw new Error('Automation originKind is invalid.');
196
+ }
197
+ if (input.legacyMetadata !== undefined) {
198
+ if (input.originKind !== 'scheduled-job') {
199
+ throw new Error('Automation legacyMetadata requires scheduled-job origin.');
200
+ }
201
+ const legacyMetadata = asRecord(input.legacyMetadata, 'Automation legacyMetadata');
202
+ const scheduledDescription = legacyMetadata.scheduledDescription;
203
+ if (scheduledDescription !== undefined && typeof scheduledDescription !== 'string') {
204
+ throw new Error('Automation legacy scheduledDescription must be a string.');
205
+ }
206
+ normalized.legacyMetadata = {
207
+ ...(scheduledDescription !== undefined ? { scheduledDescription } : {}),
208
+ };
209
+ }
210
+ return normalized;
211
+ }
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("../../../shared/desktop"), exports);
18
18
  __exportStar(require("./local-core"), exports);
19
+ __exportStar(require("./automations"), exports);
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listAutomations = listAutomations;
4
+ exports.createAutomation = createAutomation;
5
+ exports.getAutomation = getAutomation;
6
+ exports.updateAutomation = updateAutomation;
7
+ exports.deleteAutomation = deleteAutomation;
8
+ exports.checkAutomation = checkAutomation;
9
+ exports.listAutomationEvaluations = listAutomationEvaluations;
10
+ exports.listAutomationRuns = listAutomationRuns;
11
+ exports.listAutomationScripts = listAutomationScripts;
12
+ exports.createAutomationScript = createAutomationScript;
13
+ exports.getAutomationScript = getAutomationScript;
14
+ exports.updateAutomationScript = updateAutomationScript;
15
+ exports.listAutomationScriptVersions = listAutomationScriptVersions;
16
+ exports.submitAutomationScriptVersion = submitAutomationScriptVersion;
17
+ exports.requestAutomationScriptTestApproval = requestAutomationScriptTestApproval;
18
+ exports.executeAutomationScriptTest = executeAutomationScriptTest;
19
+ exports.requestAutomationScriptEnableApproval = requestAutomationScriptEnableApproval;
20
+ exports.approveAutomationScriptVersion = approveAutomationScriptVersion;
21
+ exports.rejectAutomationScriptVersion = rejectAutomationScriptVersion;
22
+ exports.revokeAutomationScriptVersion = revokeAutomationScriptVersion;
23
+ const request_js_1 = require("./request.js");
24
+ function scoped(path, workspaceId) {
25
+ return `${path}${(0, request_js_1.buildQuery)({ workspace_id: workspaceId })}`;
26
+ }
27
+ function listAutomations(workspaceId) {
28
+ return (0, request_js_1.coreRequest)('GET', scoped('/automations', workspaceId));
29
+ }
30
+ function createAutomation(input) {
31
+ return (0, request_js_1.coreRequest)('POST', '/automations', input);
32
+ }
33
+ function getAutomation(automationId, workspaceId) {
34
+ return (0, request_js_1.coreRequest)('GET', scoped(`/automations/${encodeURIComponent(automationId)}`, workspaceId));
35
+ }
36
+ function updateAutomation(automationId, workspaceId, input) {
37
+ return (0, request_js_1.coreRequest)('PATCH', scoped(`/automations/${encodeURIComponent(automationId)}`, workspaceId), input);
38
+ }
39
+ function deleteAutomation(automationId, workspaceId) {
40
+ return (0, request_js_1.coreRequest)('DELETE', scoped(`/automations/${encodeURIComponent(automationId)}`, workspaceId));
41
+ }
42
+ function checkAutomation(automationId, workspaceId) {
43
+ return (0, request_js_1.coreRequest)('POST', scoped(`/automations/${encodeURIComponent(automationId)}/check`, workspaceId));
44
+ }
45
+ function listAutomationEvaluations(automationId, workspaceId) {
46
+ return (0, request_js_1.coreRequest)('GET', scoped(`/automations/${encodeURIComponent(automationId)}/evaluations`, workspaceId));
47
+ }
48
+ function listAutomationRuns(automationId, workspaceId) {
49
+ return (0, request_js_1.coreRequest)('GET', scoped(`/automations/${encodeURIComponent(automationId)}/runs`, workspaceId));
50
+ }
51
+ function listAutomationScripts(workspaceId) {
52
+ return (0, request_js_1.coreRequest)('GET', scoped('/automation-scripts', workspaceId));
53
+ }
54
+ function createAutomationScript(input) {
55
+ return (0, request_js_1.coreRequest)('POST', '/automation-scripts', input);
56
+ }
57
+ function getAutomationScript(scriptId, workspaceId) {
58
+ return (0, request_js_1.coreRequest)('GET', scoped(`/automation-scripts/${encodeURIComponent(scriptId)}`, workspaceId));
59
+ }
60
+ function updateAutomationScript(scriptId, workspaceId, input) {
61
+ return (0, request_js_1.coreRequest)('PATCH', scoped(`/automation-scripts/${encodeURIComponent(scriptId)}`, workspaceId), input);
62
+ }
63
+ function listAutomationScriptVersions(scriptId, workspaceId) {
64
+ return (0, request_js_1.coreRequest)('GET', scoped(`/automation-scripts/${encodeURIComponent(scriptId)}/versions`, workspaceId));
65
+ }
66
+ /** Uploads a bounded source bundle; the server owns staging, hash, and interpreter selection. */
67
+ function submitAutomationScriptVersion(scriptId, workspaceId, files) {
68
+ return (0, request_js_1.coreRequest)('POST', scoped(`/automation-scripts/${encodeURIComponent(scriptId)}/versions`, workspaceId), { files });
69
+ }
70
+ function requestAutomationScriptTestApproval(versionId, workspaceId, actor) {
71
+ return (0, request_js_1.coreRequest)('POST', scoped(`/automation-scripts/versions/${encodeURIComponent(versionId)}/test-approval`, workspaceId), { actor });
72
+ }
73
+ function executeAutomationScriptTest(versionId, workspaceId, actor) {
74
+ return (0, request_js_1.coreRequest)('POST', scoped(`/automation-scripts/versions/${encodeURIComponent(versionId)}/test`, workspaceId), { actor });
75
+ }
76
+ function requestAutomationScriptEnableApproval(versionId, workspaceId, actor) {
77
+ return (0, request_js_1.coreRequest)('POST', scoped(`/automation-scripts/versions/${encodeURIComponent(versionId)}/enable-approval`, workspaceId), { actor });
78
+ }
79
+ function approveAutomationScriptVersion(versionId, workspaceId, approvalId, actor) {
80
+ return (0, request_js_1.coreRequest)('POST', scoped(`/automation-scripts/versions/${encodeURIComponent(versionId)}/approve`, workspaceId), { approvalId, actor });
81
+ }
82
+ function rejectAutomationScriptVersion(versionId, workspaceId, approvalId, actor) {
83
+ return (0, request_js_1.coreRequest)('POST', scoped(`/automation-scripts/versions/${encodeURIComponent(versionId)}/reject`, workspaceId), { approvalId, actor });
84
+ }
85
+ function revokeAutomationScriptVersion(versionId, workspaceId, actor) {
86
+ return (0, request_js_1.coreRequest)('POST', scoped(`/automation-scripts/versions/${encodeURIComponent(versionId)}/revoke`, workspaceId), { actor });
87
+ }
@@ -20,6 +20,10 @@ exports.LOCAL_CORE_EVENT_NAMES = [
20
20
  'scheduler.run.updated',
21
21
  'automation.monitor.updated',
22
22
  'automation.monitor.run.updated',
23
+ 'automation.definition.updated',
24
+ 'automation.evaluation.updated',
25
+ 'automation.run.updated',
26
+ 'automation.script-version.updated',
23
27
  'presence.updated',
24
28
  'stream.updated',
25
29
  ];
@@ -133,6 +137,95 @@ function isAutomationMonitorRun(value) {
133
137
  hasString(value, 'status') &&
134
138
  hasString(value, 'triggeredAt');
135
139
  }
140
+ function isAutomationDefinition(value) {
141
+ return isRecord(value) && hasString(value, 'id') && hasString(value, 'workspaceId') && hasString(value, 'title') &&
142
+ hasBoolean(value, 'enabled') && (value.health === 'healthy' || value.health === 'blocked') &&
143
+ isAutomationActivation(value.activation) && isAutomationCondition(value.condition) && isAutomationAction(value.action) &&
144
+ isAutomationDelivery(value.delivery) && isAutomationPolicies(value.policies) &&
145
+ isNonNegativeInteger(value.consecutiveEvaluationFailures) &&
146
+ hasString(value, 'createdAt') && hasString(value, 'updatedAt') &&
147
+ (value.health !== 'blocked' || hasString(value, 'blockedReason')) &&
148
+ (value.blockedReason === undefined || typeof value.blockedReason === 'string') &&
149
+ (value.lastSuccessfulMatch === undefined || typeof value.lastSuccessfulMatch === 'boolean') &&
150
+ (value.lastEvaluationAt === undefined || typeof value.lastEvaluationAt === 'string') &&
151
+ (value.lastTriggeredAt === undefined || typeof value.lastTriggeredAt === 'string');
152
+ }
153
+ function isAutomationEvaluation(value) {
154
+ if (!isRecord(value) || !hasString(value, 'id') || !hasString(value, 'automationId') || !hasString(value, 'activationKind') ||
155
+ !['cron', 'once', 'interval', 'provider-event'].includes(String(value.activationKind)) || !hasString(value, 'status') || !hasString(value, 'startedAt'))
156
+ return false;
157
+ if (value.status === 'running') {
158
+ return value.conditionOutcome === undefined && value.triggerDecision === undefined && value.finishedAt === undefined &&
159
+ value.durationMs === undefined && value.exitCode === undefined && value.errorCategory === undefined &&
160
+ value.stdout === undefined && value.stderr === undefined && value.resultSummary === undefined && value.payload === undefined &&
161
+ value.nextState === undefined && value.sandboxViolations === undefined && value.networkAudit === undefined;
162
+ }
163
+ if (value.status !== 'finished' || !hasString(value, 'finishedAt'))
164
+ return false;
165
+ if (value.conditionOutcome === 'matched')
166
+ return ['triggered', 'not_rising', 'skipped_cooldown', 'skipped_action_running'].includes(String(value.triggerDecision));
167
+ if (value.conditionOutcome === 'not_matched')
168
+ return value.triggerDecision === 'not_rising';
169
+ if (value.conditionOutcome === 'error')
170
+ return value.triggerDecision === 'not_evaluated';
171
+ return value.conditionOutcome === 'skipped' && ['not_evaluated', 'skipped_concurrent', 'skipped_cooldown', 'skipped_action_running'].includes(String(value.triggerDecision));
172
+ }
173
+ function isAutomationRun(value) {
174
+ return isRecord(value) && hasString(value, 'id') && hasString(value, 'automationId') && hasString(value, 'evaluationId') &&
175
+ ['queued', 'running', 'succeeded', 'failed', 'skipped'].includes(String(value.status)) &&
176
+ ['same-thread', 'side-thread'].includes(String(value.executionMode)) && hasString(value, 'createdAt') &&
177
+ (value.deliveryStatus === undefined || ['pending', 'delivering', 'delivered', 'failed'].includes(String(value.deliveryStatus))) &&
178
+ (value.threadId === undefined || typeof value.threadId === 'string') && (value.acpRunId === undefined || typeof value.acpRunId === 'string') &&
179
+ (value.error === undefined || typeof value.error === 'string');
180
+ }
181
+ function isAutomationScriptVersion(value) {
182
+ return isRecord(value) && hasString(value, 'id') && hasString(value, 'scriptId') && hasString(value, 'status') &&
183
+ ['draft', 'pending_test_approval', 'test_authorized', 'testing', 'tested', 'pending_approval', 'approved', 'rejected', 'revoked'].includes(String(value.status)) &&
184
+ hasString(value, 'packageSha256') && hasString(value, 'packagePath') && hasString(value, 'shebang') &&
185
+ hasString(value, 'interpreterPath') && hasString(value, 'interpreterVersion') && isRecord(value.capabilities) &&
186
+ isRecord(value.config) && isRecord(value.configSchema) && (value.networkMode === 'none' || value.networkMode === 'public') &&
187
+ hasBoolean(value, 'internalAccess') && isStringArray(value.allowedReadDirs) && isStringArray(value.secretRefs) &&
188
+ isStringArray(value.env) && isRecord(value.limits) && isNonNegativeInteger(value.limits.timeoutMs) &&
189
+ isNonNegativeInteger(value.limits.stdoutBytes) && isNonNegativeInteger(value.limits.stderrBytes) &&
190
+ isNonNegativeInteger(value.limits.payloadBytes) && isNonNegativeInteger(value.limits.stateBytes) &&
191
+ isRecord(value.staticCheck) && isRecord(value.testPlan) && hasString(value, 'createdAt') && hasString(value, 'updatedAt');
192
+ }
193
+ function isAutomationActivation(value) {
194
+ if (!isRecord(value))
195
+ return false;
196
+ if (value.kind === 'cron')
197
+ return hasString(value, 'expression') && hasString(value, 'timezone');
198
+ if (value.kind === 'once')
199
+ return hasString(value, 'runAt');
200
+ if (value.kind === 'interval')
201
+ return typeof value.intervalMs === 'number' && isNonNegativeInteger(value.intervalMs) && value.intervalMs > 0;
202
+ return value.kind === 'provider-event' && hasString(value, 'sourceType') && isRecord(value.sourceConfig);
203
+ }
204
+ function isAutomationCondition(value) {
205
+ if (!isRecord(value))
206
+ return false;
207
+ if (value.kind === 'always')
208
+ return true;
209
+ if (value.kind === 'expression')
210
+ return hasString(value, 'expression');
211
+ return value.kind === 'approved-script' && hasString(value, 'scriptId') && hasString(value, 'approvedVersionId') && value.edge === 'rising';
212
+ }
213
+ function isAutomationAction(value) {
214
+ return isRecord(value) && value.kind === 'agent-prompt' && hasString(value, 'promptTemplate') &&
215
+ (value.executionMode === 'same-thread' || value.executionMode === 'side-thread');
216
+ }
217
+ function isAutomationDelivery(value) {
218
+ return isRecord(value) && hasString(value, 'platform') && isChannelRoute(value.route);
219
+ }
220
+ function isAutomationPolicies(value) {
221
+ return isRecord(value) && value.concurrency === 'skip-if-running' && isNonNegativeInteger(value.cooldownMs);
222
+ }
223
+ function isStringArray(value) {
224
+ return Array.isArray(value) && value.every((item) => typeof item === 'string');
225
+ }
226
+ function isNonNegativeInteger(value) {
227
+ return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
228
+ }
136
229
  function isInstalledAgentRuntime(value) {
137
230
  return isRecord(value) &&
138
231
  hasString(value, 'agentType') &&
@@ -206,6 +299,14 @@ function isLocalCoreEvent(value) {
206
299
  return isAutomationMonitor(value.monitor);
207
300
  case 'automation.monitor.run.updated':
208
301
  return isAutomationMonitorRun(value.run);
302
+ case 'automation.definition.updated':
303
+ return isAutomationDefinition(value.automation);
304
+ case 'automation.evaluation.updated':
305
+ return isAutomationEvaluation(value.evaluation);
306
+ case 'automation.run.updated':
307
+ return isAutomationRun(value.run);
308
+ case 'automation.script-version.updated':
309
+ return isAutomationScriptVersion(value.version);
209
310
  case 'presence.updated':
210
311
  return hasBoolean(value, 'live') && (value.stream === undefined || isDesktopBridgeEvent(value.stream));
211
312
  case 'stream.updated':
@@ -36,11 +36,12 @@ var __importStar = (this && this.__importStar) || (function () {
36
36
  };
37
37
  })();
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.knowledge = exports.automation = exports.scheduler = exports.channels = exports.threads = exports.runtime = void 0;
39
+ exports.knowledge = exports.automations = exports.automation = exports.scheduler = exports.channels = exports.threads = exports.runtime = void 0;
40
40
  __exportStar(require("./client.js"), exports);
41
41
  exports.runtime = __importStar(require("./runtime.js"));
42
42
  exports.threads = __importStar(require("./threads.js"));
43
43
  exports.channels = __importStar(require("./channels.js"));
44
44
  exports.scheduler = __importStar(require("./scheduler.js"));
45
45
  exports.automation = __importStar(require("./automation.js"));
46
+ exports.automations = __importStar(require("./automations.js"));
46
47
  exports.knowledge = __importStar(require("./knowledge.js"));