openkbs 0.0.92 → 0.0.93

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openkbs",
3
- "version": "0.0.92",
3
+ "version": "0.0.93",
4
4
  "description": "OpenKBS - Command Line Interface",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/actions.js CHANGED
@@ -1135,6 +1135,8 @@ async function fnAction(subCommand, args = []) {
1135
1135
  return await fnEnvAction(kbToken, args[0], args.slice(1));
1136
1136
  case 'invoke':
1137
1137
  return await fnInvokeAction(kbToken, args[0], args.slice(1));
1138
+ case 'schedule':
1139
+ return await fnScheduleAction(kbToken, args[0], args.slice(1));
1138
1140
  default:
1139
1141
  console.log('Usage: openkbs fn <command> [options]');
1140
1142
  console.log('');
@@ -1145,11 +1147,14 @@ async function fnAction(subCommand, args = []) {
1145
1147
  console.log(' logs <name> View function logs');
1146
1148
  console.log(' env <name> [KEY=value] View or set environment variables');
1147
1149
  console.log(' invoke <name> [payload] Invoke a function');
1150
+ console.log(' schedule <name> [expr] View/set/enable/disable/remove schedule');
1148
1151
  console.log('');
1149
1152
  console.log('Options for push:');
1150
1153
  console.log(' --region <region> Region (us-east-1, eu-central-1, ap-southeast-1)');
1151
1154
  console.log(' --memory <mb> Memory size (128-3008 MB)');
1152
1155
  console.log(' --timeout <seconds> Timeout (1-900 seconds)');
1156
+ console.log(' --schedule <expr> Schedule expression (e.g. "rate(1 hour)")');
1157
+ console.log(' --http-access Enable HTTP access for scheduled functions');
1153
1158
  }
1154
1159
  }
1155
1160
 
@@ -1182,8 +1187,9 @@ async function fnListAction(kbToken) {
1182
1187
  functions.forEach(f => {
1183
1188
  const name = f.functionName.padEnd(maxNameLen);
1184
1189
  const region = f.region || 'unknown';
1185
- const url = f.customUrl || f.functionUrl || 'N/A';
1186
- console.log(` ${name} ${region} ${url}`);
1190
+ const url = f.customUrl || f.functionUrl || (f.schedule ? '(scheduled)' : 'N/A');
1191
+ const scheduleInfo = f.schedule ? ` [${f.schedule}]` : '';
1192
+ console.log(` ${name} ${region} ${url}${scheduleInfo}`);
1187
1193
  });
1188
1194
  } catch (error) {
1189
1195
  console.red('Error listing functions:', error.message);
@@ -1201,6 +1207,8 @@ async function fnDeployAction(kbToken, functionName, args) {
1201
1207
  let timeout = 30;
1202
1208
  let runtime = null; // null = use default (nodejs24.x)
1203
1209
  let handler = null; // null = use default (index.handler)
1210
+ let schedule = null;
1211
+ let httpAccess = null;
1204
1212
 
1205
1213
  for (let i = 0; i < args.length; i++) {
1206
1214
  if (args[i] === '--region' && args[i + 1]) {
@@ -1213,6 +1221,10 @@ async function fnDeployAction(kbToken, functionName, args) {
1213
1221
  runtime = args[++i];
1214
1222
  } else if (args[i] === '--handler' && args[i + 1]) {
1215
1223
  handler = args[++i];
1224
+ } else if (args[i] === '--schedule' && args[i + 1]) {
1225
+ schedule = args[++i];
1226
+ } else if (args[i] === '--http-access') {
1227
+ httpAccess = true;
1216
1228
  }
1217
1229
  }
1218
1230
 
@@ -1273,12 +1285,14 @@ async function fnDeployAction(kbToken, functionName, args) {
1273
1285
  if (existingFunc) {
1274
1286
  // Update existing function
1275
1287
  console.log('Updating existing function...');
1276
- response = await makePostRequest(KB_API_URL, {
1288
+ const updateParams = {
1277
1289
  token: kbToken,
1278
1290
  action: 'updateElasticFunction',
1279
1291
  functionName,
1280
1292
  code
1281
- });
1293
+ };
1294
+ if (schedule) updateParams.schedule = schedule;
1295
+ response = await makePostRequest(KB_API_URL, updateParams);
1282
1296
  } else {
1283
1297
  // Create new function
1284
1298
  console.log('Creating new function...');
@@ -1293,6 +1307,8 @@ async function fnDeployAction(kbToken, functionName, args) {
1293
1307
  };
1294
1308
  if (runtime) createParams.runtime = runtime;
1295
1309
  if (handler) createParams.handler = handler;
1310
+ if (schedule) createParams.schedule = schedule;
1311
+ if (httpAccess !== null) createParams.httpAccess = httpAccess;
1296
1312
  response = await makePostRequest(KB_API_URL, createParams);
1297
1313
  }
1298
1314
 
@@ -1307,6 +1323,9 @@ async function fnDeployAction(kbToken, functionName, args) {
1307
1323
  if (response.customUrl) {
1308
1324
  console.log(`Custom URL: ${response.customUrl}`);
1309
1325
  }
1326
+ if (response.schedule) {
1327
+ console.log(`Schedule: ${response.schedule}`);
1328
+ }
1310
1329
  } catch (error) {
1311
1330
  console.red('Deploy failed:', error.message);
1312
1331
  }
@@ -1336,6 +1355,71 @@ async function fnDeleteAction(kbToken, functionName) {
1336
1355
  }
1337
1356
  }
1338
1357
 
1358
+ async function fnScheduleAction(kbToken, functionName, args) {
1359
+ if (!functionName) {
1360
+ return console.red('Function name required. Usage: openkbs fn schedule <name> [expression|enable|disable|remove]');
1361
+ }
1362
+
1363
+ const subCommand = args[0];
1364
+
1365
+ try {
1366
+ if (!subCommand) {
1367
+ // Show current schedule
1368
+ const response = await makePostRequest(KB_API_URL, {
1369
+ token: kbToken,
1370
+ action: 'getElasticFunction',
1371
+ functionName
1372
+ });
1373
+ if (response.error) return console.red('Error:', response.error);
1374
+ if (response.schedule) {
1375
+ console.log(`Schedule: ${response.schedule}`);
1376
+ console.log(`Name: ${response.scheduleName || 'N/A'}`);
1377
+ } else {
1378
+ console.log(`No schedule set for '${functionName}'.`);
1379
+ }
1380
+ } else if (subCommand === 'enable') {
1381
+ const response = await makePostRequest(KB_API_URL, {
1382
+ token: kbToken,
1383
+ action: 'updateElasticFunctionSchedule',
1384
+ functionName,
1385
+ enabled: true
1386
+ });
1387
+ if (response.error) return console.red('Error:', response.error);
1388
+ console.green(`Schedule for '${functionName}' enabled.`);
1389
+ } else if (subCommand === 'disable') {
1390
+ const response = await makePostRequest(KB_API_URL, {
1391
+ token: kbToken,
1392
+ action: 'updateElasticFunctionSchedule',
1393
+ functionName,
1394
+ enabled: false
1395
+ });
1396
+ if (response.error) return console.red('Error:', response.error);
1397
+ console.green(`Schedule for '${functionName}' disabled.`);
1398
+ } else if (subCommand === 'remove') {
1399
+ const response = await makePostRequest(KB_API_URL, {
1400
+ token: kbToken,
1401
+ action: 'updateElasticFunctionSchedule',
1402
+ functionName,
1403
+ schedule: null
1404
+ });
1405
+ if (response.error) return console.red('Error:', response.error);
1406
+ console.green(`Schedule for '${functionName}' removed.`);
1407
+ } else {
1408
+ // Set schedule expression
1409
+ const response = await makePostRequest(KB_API_URL, {
1410
+ token: kbToken,
1411
+ action: 'updateElasticFunctionSchedule',
1412
+ functionName,
1413
+ schedule: subCommand
1414
+ });
1415
+ if (response.error) return console.red('Error:', response.error);
1416
+ console.green(`Schedule for '${functionName}' set to: ${subCommand}`);
1417
+ }
1418
+ } catch (error) {
1419
+ console.red('Schedule operation failed:', error.message);
1420
+ }
1421
+ }
1422
+
1339
1423
  async function fnLogsAction(kbToken, functionName, args) {
1340
1424
  if (!functionName) {
1341
1425
  return console.red('Function name required. Usage: openkbs fn logs <name>');
@@ -2477,6 +2561,8 @@ async function elasticDeployAction() {
2477
2561
  if (fnConfig.timeout) args.push('--timeout', String(fnConfig.timeout));
2478
2562
  if (fnConfig.runtime) args.push('--runtime', fnConfig.runtime);
2479
2563
  if (fnConfig.handler) args.push('--handler', fnConfig.handler);
2564
+ if (fnConfig.schedule) args.push('--schedule', fnConfig.schedule);
2565
+ if (fnConfig.httpAccess) args.push('--http-access');
2480
2566
 
2481
2567
  console.log(` Deploying ${name}...`);
2482
2568
  await fnDeployAction(kbToken, name, args);
@@ -100,7 +100,8 @@ my-platform/
100
100
  },
101
101
  "pulse": true,
102
102
  "functions": [
103
- { "name": "api", "runtime": "nodejs24.x", "memory": 512, "timeout": 30 }
103
+ { "name": "api", "runtime": "nodejs24.x", "memory": 512, "timeout": 30 },
104
+ { "name": "cleanup", "schedule": "rate(1 hour)", "timeout": 900 }
104
105
  ],
105
106
  "site": "./site"
106
107
  }
@@ -127,7 +128,10 @@ openkbs destroy # Remove all resources (DANGEROUS)
127
128
  ```bash
128
129
  openkbs fn list # List Lambda functions
129
130
  openkbs fn push api # Deploy function
131
+ openkbs fn push cleanup --schedule "rate(1 hour)" # Deploy with schedule
130
132
  openkbs fn logs api # View function logs
133
+ openkbs fn schedule cleanup # View schedule
134
+ openkbs fn schedule cleanup disable # Disable schedule
131
135
  openkbs postgres shell # Connect to Postgres
132
136
  openkbs storage ls # List S3 objects
133
137
  openkbs pulse status # WebSocket status
@@ -246,6 +250,42 @@ Configure in `settings.json`:
246
250
 
247
251
  Priority items are auto-injected into LLM context.
248
252
 
253
+ ## Spec Mode
254
+
255
+ When the user is in **Spec Mode**, you act as a Product Manager helping define specifications.
256
+
257
+ ### Workflow
258
+ 1. Discuss requirements with the user — ask clarifying questions
259
+ 2. Explore the codebase to understand the current architecture
260
+ 3. Write the specification as a `.md` file in the `spec/` folder
261
+ 4. Call `ExitPlanMode` to present the specification for user approval
262
+ 5. If rejected or changes requested, revise and re-submit
263
+
264
+ ### Spec File Format
265
+ Create files in `spec/` folder with descriptive names (e.g., `spec/user-authentication.md`):
266
+
267
+ - **Goals** — What this feature achieves
268
+ - **Requirements** — Functional requirements (numbered list)
269
+ - **User Stories** — As a [role], I want [action], so that [benefit]
270
+ - **Acceptance Criteria** — Testable conditions for completeness
271
+ - **Constraints** — Technical or business limitations
272
+ - **Out of Scope** — What is explicitly NOT included
273
+
274
+ ### Markdown Features
275
+ The spec viewer supports GitHub Flavored Markdown (GFM). Use these for well-structured specs:
276
+ - **Tables** — for requirement matrices, field definitions, API specs
277
+ - **Task lists** — `- [ ]` / `- [x]` for checklists
278
+ - **Strikethrough** — `~~text~~` for deprecated items
279
+ - **Autolinks** — URLs are automatically linked
280
+ - **Headings, lists, bold, italic, code blocks** — all standard markdown
281
+
282
+ ### Rules
283
+ - Do NOT write implementation code in spec mode
284
+ - Focus on WHAT to build, not HOW
285
+ - Keep specs concise and actionable
286
+ - One spec file per feature/topic
287
+ - Use tables for structured data (requirements, fields, APIs)
288
+
249
289
  ## Additional Resources
250
290
 
251
291
  ### Reference Documentation
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "0.1.25"
2
+ "version": "0.1.27"
3
3
  }
@@ -23,7 +23,9 @@ OpenKBS provides managed cloud infrastructure that scales automatically.
23
23
  },
24
24
  "pulse": true,
25
25
  "functions": [
26
- { "name": "hello", "runtime": "nodejs24.x", "memory": 512, "timeout": 30 }
26
+ { "name": "api", "runtime": "nodejs24.x", "memory": 512, "timeout": 30 },
27
+ { "name": "cleanup", "runtime": "nodejs24.x", "memory": 256, "timeout": 900, "schedule": "rate(1 hour)" },
28
+ { "name": "reports", "runtime": "nodejs24.x", "memory": 512, "timeout": 300, "schedule": "cron(0 12 * * ? *)" }
27
29
  ],
28
30
  "site": "./site"
29
31
  }
@@ -66,11 +68,62 @@ export const handler = async (event) => {
66
68
  ```bash
67
69
  openkbs fn list # List all functions
68
70
  openkbs fn push hello --region us-east-1 # Deploy function
71
+ openkbs fn push hello --schedule "rate(1 hour)" # Deploy with schedule
72
+ openkbs fn push hello --schedule "rate(1 hour)" --http-access # Schedule + HTTP
69
73
  openkbs fn delete hello # Delete function
70
74
  openkbs fn logs hello # View logs
71
75
  openkbs fn env hello # View env vars
72
76
  openkbs fn env hello API_KEY=secret # Set env var
73
77
  openkbs fn invoke hello '{"test": true}' # Invoke function
78
+ openkbs fn schedule hello # View current schedule
79
+ openkbs fn schedule hello "rate(5 minutes)" # Set schedule
80
+ openkbs fn schedule hello enable # Enable schedule
81
+ openkbs fn schedule hello disable # Disable schedule
82
+ openkbs fn schedule hello remove # Remove schedule
83
+ ```
84
+
85
+ ### Scheduled Functions
86
+
87
+ Functions with a `schedule` field are invoked automatically by EventBridge Scheduler. By default, scheduled functions do **not** get HTTP access (no Function URL / CloudFront). Add `"httpAccess": true` to enable both.
88
+
89
+ **Schedule expressions:**
90
+ - `rate(1 hour)`, `rate(5 minutes)`, `rate(1 day)`
91
+ - `cron(0 12 * * ? *)` — daily at 12:00 UTC
92
+ - `cron(0/15 * * * ? *)` — every 15 minutes
93
+
94
+ **openkbs.json example:**
95
+ ```json
96
+ {
97
+ "functions": [
98
+ { "name": "api", "runtime": "nodejs24.x", "memory": 512, "timeout": 30 },
99
+ { "name": "cleanup", "schedule": "rate(1 hour)", "timeout": 900 },
100
+ { "name": "reports", "schedule": "cron(0 12 * * ? *)", "httpAccess": true }
101
+ ]
102
+ }
103
+ ```
104
+
105
+ **Event payload** received by the Lambda handler:
106
+ ```json
107
+ {
108
+ "source": "openkbs.scheduler",
109
+ "kbId": "abc123",
110
+ "functionName": "cleanup",
111
+ "scheduleExpression": "rate(1 hour)"
112
+ }
113
+ ```
114
+
115
+ **Handler example:**
116
+ ```javascript
117
+ export const handler = async (event) => {
118
+ if (event.source === 'openkbs.scheduler') {
119
+ // Invoked by schedule
120
+ console.log(`Running scheduled task: ${event.functionName}`);
121
+ // ... do work ...
122
+ return { statusCode: 200, body: 'OK' };
123
+ }
124
+ // Invoked via HTTP (if httpAccess is enabled)
125
+ return { statusCode: 200, body: JSON.stringify({ message: 'Hello' }) };
126
+ };
74
127
  ```
75
128
 
76
129
  ### Supported Runtimes
package/version.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.92",
3
- "releaseDate": "2026-02-21",
4
- "releaseNotes": "OpenKBS CLI version 0.0.92"
2
+ "version": "0.0.93",
3
+ "releaseDate": "2026-03-03",
4
+ "releaseNotes": "OpenKBS CLI version 0.0.93"
5
5
  }