@openagt/skill-scheduler 0.0.0-stage → 0.1.10
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/LICENSE +21 -0
- package/SKILL.md +28 -0
- package/bin/scheduler +11 -0
- package/dist/automation-file.d.ts +61 -0
- package/dist/automation-file.d.ts.map +1 -0
- package/dist/automation-file.js +153 -0
- package/dist/automation-file.js.map +1 -0
- package/dist/automation.d.ts +189 -0
- package/dist/automation.d.ts.map +1 -0
- package/dist/automation.js +237 -0
- package/dist/automation.js.map +1 -0
- package/dist/cleanup.d.ts +31 -0
- package/dist/cleanup.d.ts.map +1 -0
- package/dist/cleanup.js +20 -0
- package/dist/cleanup.js.map +1 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +416 -0
- package/dist/cli.js.map +1 -0
- package/dist/dashboard/dashboard.css +3 -0
- package/dist/dashboard/dashboard.js +2323 -0
- package/dist/hook-lines.d.ts +11 -0
- package/dist/hook-lines.d.ts.map +1 -0
- package/dist/hook-lines.js +12 -0
- package/dist/hook-lines.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +40 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +95 -0
- package/dist/init.js.map +1 -0
- package/dist/names.d.ts +83 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +89 -0
- package/dist/names.js.map +1 -0
- package/dist/pace.d.ts +86 -0
- package/dist/pace.d.ts.map +1 -0
- package/dist/pace.js +99 -0
- package/dist/pace.js.map +1 -0
- package/dist/quota-boundary.d.ts +123 -0
- package/dist/quota-boundary.d.ts.map +1 -0
- package/dist/quota-boundary.js +181 -0
- package/dist/quota-boundary.js.map +1 -0
- package/dist/records.d.ts +45 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +85 -0
- package/dist/records.js.map +1 -0
- package/dist/schedule.d.ts +241 -0
- package/dist/schedule.d.ts.map +1 -0
- package/dist/schedule.js +379 -0
- package/dist/schedule.js.map +1 -0
- package/dist/scheduler.d.ts +75 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +244 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/start-point.d.ts +40 -0
- package/dist/start-point.d.ts.map +1 -0
- package/dist/start-point.js +88 -0
- package/dist/start-point.js.map +1 -0
- package/dist/state.d.ts +194 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +208 -0
- package/dist/state.js.map +1 -0
- package/dist/test-repo.d.ts +20 -0
- package/dist/test-repo.d.ts.map +1 -0
- package/dist/test-repo.js +56 -0
- package/dist/test-repo.js.map +1 -0
- package/dist/tick.d.ts +119 -0
- package/dist/tick.d.ts.map +1 -0
- package/dist/tick.js +311 -0
- package/dist/tick.js.map +1 -0
- package/dist/write-line.d.ts +38 -0
- package/dist/write-line.d.ts.map +1 -0
- package/dist/write-line.js +121 -0
- package/dist/write-line.js.map +1 -0
- package/package.json +65 -3
- package/README.md +0 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Suleiman Shahbari
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scheduler
|
|
3
|
+
description: "Start and stop the project's scheduler, switch the commands it starts on a schedule on or off, set their pace, or start one now, when the person asks you to."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Scheduler
|
|
7
|
+
|
|
8
|
+
The scheduler starts agents on a schedule: the project's skills say which commands can run on one, and each machine switches them on for itself. It runs in its own process and needs no dashboard.
|
|
9
|
+
|
|
10
|
+
Run the `scheduler` command at the project's root, always by its full name: `npx @openagt/skill-scheduler@0.1`. It prints one JSON document; a refusal exits 1 with why on stderr; a wrong command line exits 2 with the usage.
|
|
11
|
+
|
|
12
|
+
Change it only when the person asks: every run it starts spends their quota.
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
npx @openagt/skill-scheduler@0.1 status on, running, the switches, and schedule: every command
|
|
16
|
+
that can run on a schedule, with its pace (every), its check (when)
|
|
17
|
+
npx @openagt/skill-scheduler@0.1 start the scheduler on, ticking every minute in its own process
|
|
18
|
+
npx @openagt/skill-scheduler@0.1 stop the scheduler off; runs in flight go to their end
|
|
19
|
+
npx @openagt/skill-scheduler@0.1 switch <command> on|off whether a command runs on this machine; every one starts off
|
|
20
|
+
npx @openagt/skill-scheduler@0.1 pace <command> <N<m|h|d|w|mo>|work|skill> [HH:MM]
|
|
21
|
+
how often at most it starts; work: whenever its check finds work;
|
|
22
|
+
skill: its skill's own pace again
|
|
23
|
+
npx @openagt/skill-scheduler@0.1 now <command> one run of it now, whatever its switch and pace
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
A command is named as `status` names it, quoted when it has a word after it. A switched-on command starts nothing while the scheduler is off: switch it on, then `start`.
|
|
27
|
+
|
|
28
|
+
The rest, such as a command's agent, model, publish level, or the person's own automations, is in its usage: `npx @openagt/skill-scheduler@0.1` with no command prints it.
|
package/bin/scheduler
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runCli } from '../dist/cli.js'
|
|
3
|
+
|
|
4
|
+
runCli(process.argv.slice(2), { cwd: process.cwd(), stdout: line => console.log(line), stderr: line => console.error(line) })
|
|
5
|
+
.then(code => {
|
|
6
|
+
process.exitCode = code
|
|
7
|
+
})
|
|
8
|
+
.catch(err => {
|
|
9
|
+
console.error(err)
|
|
10
|
+
process.exitCode = 1
|
|
11
|
+
})
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The file of a person's own automation, written and read back. Shared with the project it is a
|
|
3
|
+
* command skill's file (`.claude/skills/<name>/SKILL.md`); kept on this machine alone it is the
|
|
4
|
+
* same text in the tool's own folder (`.scheduler/automations/<name>.md`). The front matter
|
|
5
|
+
* makes it a command (`disable-model-invocation`) and carries the `schedule` the person picked;
|
|
6
|
+
* the text after it is the prompt.
|
|
7
|
+
*
|
|
8
|
+
* The tool rewrites and removes a file only while the file reads as the tool writes one: rewriting
|
|
9
|
+
* it then loses nothing a person wrote, and no skill a person or a package wrote is taken for an
|
|
10
|
+
* automation.
|
|
11
|
+
*/
|
|
12
|
+
/** An automation as a person fills it in. */
|
|
13
|
+
export interface NewAutomation {
|
|
14
|
+
/** The command's name, without its slash: the skill's folder. */
|
|
15
|
+
name: string;
|
|
16
|
+
/** What the agent is told: the skill's whole text. */
|
|
17
|
+
prompt: string;
|
|
18
|
+
/** How often at most, as a skill writes it (`15m`, `1d`). */
|
|
19
|
+
every?: string;
|
|
20
|
+
/** The check, a shell line. */
|
|
21
|
+
when?: string;
|
|
22
|
+
/** What the check waits for, in one plain line. */
|
|
23
|
+
waitsFor?: string;
|
|
24
|
+
}
|
|
25
|
+
/** A text with each half of a broken character pair replaced: such a half is no text a file holds. */
|
|
26
|
+
export declare function wellFormed(text: string): string;
|
|
27
|
+
/** The front matter of a skill file as written here, between its two lines of dashes. */
|
|
28
|
+
export declare function frontMatterOf(text: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* The skill file of an automation: the front matter, then the prompt. The description is the
|
|
31
|
+
* prompt's first line, cut short: it is what the row says the command does. Every text a person
|
|
32
|
+
* typed is written quoted, so it can change no other key of the front matter, and the check as a
|
|
33
|
+
* block where it can be, so it reads in the file as typed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function automationSkill(automation: NewAutomation): string;
|
|
36
|
+
/**
|
|
37
|
+
* The automation a file holds, when the file is what {@link automationSkill} writes for one;
|
|
38
|
+
* nothing for any other file: a skill somebody wrote, or an automation changed by hand since it
|
|
39
|
+
* was saved into something the tool does not write. What is read back, written again, is the
|
|
40
|
+
* file itself, so rewriting it loses nothing.
|
|
41
|
+
*
|
|
42
|
+
* What the description says may differ, while its line is a quoted text as the tool writes it:
|
|
43
|
+
* it is the prompt's first line, written anew with every save, so a person who changed that line
|
|
44
|
+
* of the prompt by hand still has an automation, with a description a line behind. A description
|
|
45
|
+
* written any other way is a person's, and the file a skill of theirs.
|
|
46
|
+
*/
|
|
47
|
+
export declare function automationOf(name: string, md: string): NewAutomation | undefined;
|
|
48
|
+
/** What a file manager leaves in a folder a person only looked at: no part of a skill, and it goes with the folder. */
|
|
49
|
+
export declare const FOLDER_LITTER = ".DS_Store";
|
|
50
|
+
/** What saving an automation again writes beside its file before moving it over the file: left behind only by a save that was cut short, it is the tool's own, no part of a skill, and it goes with the next save or with the folder. */
|
|
51
|
+
export declare const HALF_SAVED = "SKILL.md.new";
|
|
52
|
+
/**
|
|
53
|
+
* Whether a skill's folder in the project is what saving a shared automation makes: a folder that
|
|
54
|
+
* is no link, holding the skill's file, no link either, and nothing else but what a file manager
|
|
55
|
+
* leaves behind and what a save of the tool's own that was cut short left. A skill that comes from a package is a link, and a skill with scripts beside its
|
|
56
|
+
* file holds more: neither is an automation, whatever its file says.
|
|
57
|
+
*/
|
|
58
|
+
export declare function standsAlone(repo: string, name: string): Promise<boolean>;
|
|
59
|
+
/** Whether a path is a file and no link to one: writing or deleting a link would reach a file kept somewhere else. */
|
|
60
|
+
export declare function isPlainFile(path: string): Promise<boolean>;
|
|
61
|
+
//# sourceMappingURL=automation-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automation-file.d.ts","sourceRoot":"","sources":["../src/automation-file.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;GAUG;AAEH,6CAA6C;AAC7C,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAWD,sGAAsG;AACtG,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AA0BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,aAAa,GAAG,MAAM,CAuBjE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAsBhF;AAsBD,uHAAuH;AACvH,eAAO,MAAM,aAAa,cAAc,CAAA;AAExC,yOAAyO;AACzO,eAAO,MAAM,UAAU,iBAAsB,CAAA;AAE7C;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAU9E;AAED,sHAAsH;AACtH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKhE"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { lstat, readdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { parse as parseYaml } from 'yaml';
|
|
4
|
+
import { RUN_SKILLS_DIR, SKILL_FILE } from './names.js';
|
|
5
|
+
/** How much of the prompt's first line stands as the skill's description, in characters. */
|
|
6
|
+
const DESCRIPTION_MAX = 150;
|
|
7
|
+
/** Characters a quoted value writes as an escape beyond what JSON escapes: DEL and the C1 controls, the two Unicode line ends, the byte order mark. */
|
|
8
|
+
const SPECIALS = /[\u007f-\u009f\u2028\u2029\ufeff]/g;
|
|
9
|
+
/** Characters a block cannot hold as typed: every control character but the line end, and the ones above. */
|
|
10
|
+
const CONTROLS = /[\u0000-\u0009\u000b-\u001f\u007f-\u009f\u2028\u2029\ufeff]/;
|
|
11
|
+
/** A text with each half of a broken character pair replaced: such a half is no text a file holds. */
|
|
12
|
+
export function wellFormed(text) {
|
|
13
|
+
return text.replace(/[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/g, '\ufffd');
|
|
14
|
+
}
|
|
15
|
+
/** The front matter of a skill file as written here, between its two lines of dashes. */
|
|
16
|
+
export function frontMatterOf(text) {
|
|
17
|
+
return text.slice(4, text.indexOf('\n---\n', 4));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A text as a quoted value of the front matter: every character that could end the value, the
|
|
21
|
+
* line or the front matter is written as an escape, three dashes in a row among them, since a
|
|
22
|
+
* coding agent's reader ends the front matter at the first three dashes anywhere. Half of a
|
|
23
|
+
* broken character pair, which no file holds as text, is replaced. It reads back as the text.
|
|
24
|
+
*/
|
|
25
|
+
function quoted(text) {
|
|
26
|
+
return JSON.stringify(wellFormed(text))
|
|
27
|
+
.replace(SPECIALS, c => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`)
|
|
28
|
+
.replaceAll('---', '--\\u002d');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Whether a check can stand in the file as a block, line for line as typed, the way the skills
|
|
32
|
+
* write theirs: no character a block would lose or read as layout (a control character, blanks at
|
|
33
|
+
* a line's end, blanks at its first line's start, where the block's indent is measured), and no
|
|
34
|
+
* three dashes. Any other check is written quoted, on one line.
|
|
35
|
+
*/
|
|
36
|
+
function fitsBlock(check) {
|
|
37
|
+
if (CONTROLS.test(check) || check.includes('---'))
|
|
38
|
+
return false;
|
|
39
|
+
const lines = check.split('\n');
|
|
40
|
+
return lines[0] === lines[0].trimStart() && lines.every(line => line === line.trimEnd());
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The skill file of an automation: the front matter, then the prompt. The description is the
|
|
44
|
+
* prompt's first line, cut short: it is what the row says the command does. Every text a person
|
|
45
|
+
* typed is written quoted, so it can change no other key of the front matter, and the check as a
|
|
46
|
+
* block where it can be, so it reads in the file as typed.
|
|
47
|
+
*/
|
|
48
|
+
export function automationSkill(automation) {
|
|
49
|
+
const prompt = wellFormed(automation.prompt.trim());
|
|
50
|
+
// Cut by whole characters: half an emoji is no text.
|
|
51
|
+
const first = Array.from(prompt.split('\n')[0].trim());
|
|
52
|
+
const description = first.length > DESCRIPTION_MAX ? `${first.slice(0, DESCRIPTION_MAX - 1).join('')}…` : first.join('');
|
|
53
|
+
const when = automation.when === undefined ? undefined : wellFormed(automation.when.trim());
|
|
54
|
+
const lines = [
|
|
55
|
+
'---',
|
|
56
|
+
`name: ${automation.name}`,
|
|
57
|
+
`description: ${quoted(description)}`,
|
|
58
|
+
'disable-model-invocation: true',
|
|
59
|
+
// With neither a pace nor a check the schedule is an empty row, which the reader refuses in its own words.
|
|
60
|
+
automation.every === undefined && when === undefined && automation.waitsFor === undefined ? 'schedule: {}' : 'schedule:',
|
|
61
|
+
// A pace as the tool writes one stands as it is; anything else typed there is quoted, and the reader then says what is wrong with it.
|
|
62
|
+
...(automation.every !== undefined ? [` every: ${/^\d+(m|h|d|w|mo)$/.test(automation.every) ? automation.every : quoted(automation.every)}`] : []),
|
|
63
|
+
...(automation.waitsFor !== undefined ? [` waits-for: ${quoted(automation.waitsFor.trim())}`] : []),
|
|
64
|
+
...(when === undefined ? [] : fitsBlock(when) ? [' when: |-', ...when.split('\n').map((line) => (line === '' ? '' : ` ${line}`))] : [` when: ${quoted(when)}`]),
|
|
65
|
+
'---',
|
|
66
|
+
'',
|
|
67
|
+
prompt,
|
|
68
|
+
'',
|
|
69
|
+
];
|
|
70
|
+
return lines.join('\n');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The automation a file holds, when the file is what {@link automationSkill} writes for one;
|
|
74
|
+
* nothing for any other file: a skill somebody wrote, or an automation changed by hand since it
|
|
75
|
+
* was saved into something the tool does not write. What is read back, written again, is the
|
|
76
|
+
* file itself, so rewriting it loses nothing.
|
|
77
|
+
*
|
|
78
|
+
* What the description says may differ, while its line is a quoted text as the tool writes it:
|
|
79
|
+
* it is the prompt's first line, written anew with every save, so a person who changed that line
|
|
80
|
+
* of the prompt by hand still has an automation, with a description a line behind. A description
|
|
81
|
+
* written any other way is a person's, and the file a skill of theirs.
|
|
82
|
+
*/
|
|
83
|
+
export function automationOf(name, md) {
|
|
84
|
+
const end = md.startsWith('---\n') ? md.indexOf('\n---\n', 4) : -1;
|
|
85
|
+
if (end < 0)
|
|
86
|
+
return undefined;
|
|
87
|
+
let data;
|
|
88
|
+
try {
|
|
89
|
+
data = parseYaml(md.slice(4, end));
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const schedule = isMap(data) ? data['schedule'] : undefined;
|
|
95
|
+
if (!isMap(schedule))
|
|
96
|
+
return undefined;
|
|
97
|
+
const { every, when } = schedule;
|
|
98
|
+
const waitsFor = schedule['waits-for'];
|
|
99
|
+
const automation = {
|
|
100
|
+
name,
|
|
101
|
+
prompt: md.slice(end + '\n---\n'.length).trim(),
|
|
102
|
+
...(every !== undefined ? { every: String(every) } : {}),
|
|
103
|
+
...(typeof when === 'string' ? { when } : {}),
|
|
104
|
+
...(typeof waitsFor === 'string' ? { waitsFor } : {}),
|
|
105
|
+
};
|
|
106
|
+
// A file with no such description is nothing the tool wrote: what the tool writes always has one.
|
|
107
|
+
return butDescription(md) === butDescription(automationSkill(automation)) ? automation : undefined;
|
|
108
|
+
}
|
|
109
|
+
/** A file without its description, where the tool writes it: on the third line, after the opening dashes and the name, as one quoted text and nothing after it. Nothing for a file with no such line. */
|
|
110
|
+
function butDescription(md) {
|
|
111
|
+
const lines = md.split('\n');
|
|
112
|
+
const said = lines[2]?.startsWith('description: "') ? lines[2].slice('description: '.length) : undefined;
|
|
113
|
+
return said !== undefined && isQuoted(said) ? [...lines.slice(0, 2), ...lines.slice(3)].join('\n') : undefined;
|
|
114
|
+
}
|
|
115
|
+
/** Whether a text is one quoted text as {@link quoted} writes it, whole: what follows a closing quote, a comment, is a person's writing. */
|
|
116
|
+
function isQuoted(text) {
|
|
117
|
+
try {
|
|
118
|
+
return typeof JSON.parse(text) === 'string';
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function isMap(value) {
|
|
125
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
126
|
+
}
|
|
127
|
+
/** What a file manager leaves in a folder a person only looked at: no part of a skill, and it goes with the folder. */
|
|
128
|
+
export const FOLDER_LITTER = '.DS_Store';
|
|
129
|
+
/** What saving an automation again writes beside its file before moving it over the file: left behind only by a save that was cut short, it is the tool's own, no part of a skill, and it goes with the next save or with the folder. */
|
|
130
|
+
export const HALF_SAVED = `${SKILL_FILE}.new`;
|
|
131
|
+
/**
|
|
132
|
+
* Whether a skill's folder in the project is what saving a shared automation makes: a folder that
|
|
133
|
+
* is no link, holding the skill's file, no link either, and nothing else but what a file manager
|
|
134
|
+
* leaves behind and what a save of the tool's own that was cut short left. A skill that comes from a package is a link, and a skill with scripts beside its
|
|
135
|
+
* file holds more: neither is an automation, whatever its file says.
|
|
136
|
+
*/
|
|
137
|
+
export async function standsAlone(repo, name) {
|
|
138
|
+
const folder = join(repo, RUN_SKILLS_DIR, name);
|
|
139
|
+
try {
|
|
140
|
+
const [dir, entries] = await Promise.all([lstat(folder), readdir(folder)]);
|
|
141
|
+
// The leftover of a save is a file: a link or a folder of that name is somebody's, and writing through it would reach something kept elsewhere.
|
|
142
|
+
const halfSaved = !entries.includes(HALF_SAVED) || (await isPlainFile(join(folder, HALF_SAVED)));
|
|
143
|
+
return dir.isDirectory() && halfSaved && entries.every(entry => entry === SKILL_FILE || entry === FOLDER_LITTER || entry === HALF_SAVED) && (await isPlainFile(join(folder, SKILL_FILE)));
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/** Whether a path is a file and no link to one: writing or deleting a link would reach a file kept somewhere else. */
|
|
150
|
+
export async function isPlainFile(path) {
|
|
151
|
+
return lstat(path).then(stat => stat.isFile(), () => false);
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=automation-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automation-file.js","sourceRoot":"","sources":["../src/automation-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
import { type GitRunner } from '@openagt/agent-data';
|
|
3
|
+
import { type NewAutomation } from './automation-file.js';
|
|
4
|
+
import { runCheck } from './tick.js';
|
|
5
|
+
/**
|
|
6
|
+
* A person's own automation: a prompt they wrote, saved as a command skill of the project, so it
|
|
7
|
+
* has a row like any skill's and the tick treats it as one. The skill's text is the
|
|
8
|
+
* prompt; its front matter makes it a command (`disable-model-invocation`) and carries the
|
|
9
|
+
* `schedule` the person picked: a pace, a check, or both.
|
|
10
|
+
*
|
|
11
|
+
* Shared with the project, it is a file in the person's checkout, in the folder the coding agent
|
|
12
|
+
* that runs scheduled commands reads. Like any skill a person writes there, it is no command to a
|
|
13
|
+
* run until it is on the commit a run's checkout starts from: the person commits it and brings it
|
|
14
|
+
* there. Kept on this machine alone, it is the same file in the tool's own folder, and a run is
|
|
15
|
+
* handed its text with a prompt that is the automation's name.
|
|
16
|
+
*
|
|
17
|
+
* Saved, it can be shown, saved again with other words under the same name, and removed: only
|
|
18
|
+
* while its file still reads as the tool writes one (`automation-file.ts`).
|
|
19
|
+
*/
|
|
20
|
+
export type AddRefusal = {
|
|
21
|
+
ok: false;
|
|
22
|
+
reason: 'bad-name';
|
|
23
|
+
detail: string;
|
|
24
|
+
} | {
|
|
25
|
+
ok: false;
|
|
26
|
+
reason: 'no-prompt';
|
|
27
|
+
} | {
|
|
28
|
+
ok: false;
|
|
29
|
+
reason: 'long-prompt';
|
|
30
|
+
detail: string;
|
|
31
|
+
} | {
|
|
32
|
+
ok: false;
|
|
33
|
+
reason: 'bad-schedule';
|
|
34
|
+
detail: string;
|
|
35
|
+
} | {
|
|
36
|
+
ok: false;
|
|
37
|
+
reason: 'taken';
|
|
38
|
+
folder: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Why an automation cannot be saved as written, or nothing: its name, its prompt, and its
|
|
42
|
+
* schedule by the very reader the tick reads skills with. What the reader reads back has to be
|
|
43
|
+
* what was typed, and the file has to read the same to a coding agent, whose reader ends the
|
|
44
|
+
* front matter at the first three dashes it meets anywhere.
|
|
45
|
+
*/
|
|
46
|
+
export declare function automationProblem(automation: NewAutomation): AddRefusal | undefined;
|
|
47
|
+
/** Where an automation's file was written, new or anew, and what whoever asked needs to say about it. */
|
|
48
|
+
export interface Written {
|
|
49
|
+
ok: true;
|
|
50
|
+
command: string;
|
|
51
|
+
/** The file written, from the repository root. */
|
|
52
|
+
file: string;
|
|
53
|
+
/** What a run's checkout starts from, as git names it: where a shared automation's file has to get to before its command can start. */
|
|
54
|
+
startsFrom: string;
|
|
55
|
+
/** Whether it is kept on this machine alone: it needs no commit, and its command can start at once. */
|
|
56
|
+
onThisMachine?: true;
|
|
57
|
+
/** What the file says now, as {@link SavedAutomation.version} names it, when it was written anew: what the next save from the same place is held against. */
|
|
58
|
+
version?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Save an automation, shared with the project or kept on this machine alone.
|
|
62
|
+
*
|
|
63
|
+
* Shared, it is a skill file of the project, which the person commits; like any skill, its command
|
|
64
|
+
* starts no run before the file is on the commit a run's checkout starts from. Kept on this
|
|
65
|
+
* machine, it is one file in the tool's own folder, hidden from git like the state: nobody else
|
|
66
|
+
* gets the row, nothing is to commit, and a run of it is handed its text.
|
|
67
|
+
*
|
|
68
|
+
* Refused when it cannot be read back as written, and when its name is taken, whatever its
|
|
69
|
+
* capitals: by a skill in any folder a coding agent reads skills from, or by an automation kept on
|
|
70
|
+
* this machine. An automation never replaces either, and on a disk that ignores capitals `Foo` and
|
|
71
|
+
* `foo` are one name. A write that fails leaves no empty folder behind, shared or kept here.
|
|
72
|
+
*/
|
|
73
|
+
export declare function addAutomation(repo: string, automation: NewAutomation, git: GitRunner, opts?: {
|
|
74
|
+
onThisMachine?: boolean;
|
|
75
|
+
write?: typeof writeFile;
|
|
76
|
+
}): Promise<Written | AddRefusal>;
|
|
77
|
+
/** An automation where it is saved: what `show` answers, and what `edit` and `remove` act on. */
|
|
78
|
+
export interface SavedAutomation {
|
|
79
|
+
automation: NewAutomation;
|
|
80
|
+
/** Its file, from the repository root. */
|
|
81
|
+
file: string;
|
|
82
|
+
/** Whether it is kept on this machine alone. */
|
|
83
|
+
onThisMachine?: true;
|
|
84
|
+
/** A name for what its file says now: a save may be held against it, so it does not write over a change made since. */
|
|
85
|
+
version: string;
|
|
86
|
+
}
|
|
87
|
+
/** Why a name is no automation the tool rewrites or removes. */
|
|
88
|
+
export type NotAnAutomation = {
|
|
89
|
+
ok: false;
|
|
90
|
+
reason: 'not-an-automation';
|
|
91
|
+
detail: string;
|
|
92
|
+
};
|
|
93
|
+
/** Why an automation was not saved again: its file says something else than whoever asked last read. */
|
|
94
|
+
export type ChangedSince = {
|
|
95
|
+
ok: false;
|
|
96
|
+
reason: 'changed-since';
|
|
97
|
+
detail: string;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* The automation of that name, where it is saved, or why the tool leaves what has the name alone.
|
|
101
|
+
*
|
|
102
|
+
* The tool rewrites and removes only what it wrote, and the schedule says what that is
|
|
103
|
+
* (`editable`): a command whose file reads as the tool writes one, in the tool's own folder, or
|
|
104
|
+
* alone in a skill folder of the project that is no link. A skill a person or a package wrote, and
|
|
105
|
+
* an automation changed by hand into something the tool does not write, are edited and removed by
|
|
106
|
+
* hand: rewriting one from here would lose what the tool does not write. What the schedule does
|
|
107
|
+
* not list is left alone too, with the schedule's own reason when it has one.
|
|
108
|
+
*/
|
|
109
|
+
export declare function savedAutomation(repo: string, name: string): Promise<SavedAutomation | NotAnAutomation>;
|
|
110
|
+
/** What `edit` changes of an automation: a part given takes the place of the file's, `null` takes a part out, and a part left out stays as the file says it. */
|
|
111
|
+
export interface AutomationChange {
|
|
112
|
+
prompt?: string | undefined;
|
|
113
|
+
every?: string | null | undefined;
|
|
114
|
+
when?: string | null | undefined;
|
|
115
|
+
waitsFor?: string | null | undefined;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Save an automation again under its name, with a new prompt or a new schedule: its file is
|
|
119
|
+
* written anew, where it is, with what was given in place of what it said and the rest as it
|
|
120
|
+
* was. What a check waits for goes out with the check, unless it is given too. Its name stays,
|
|
121
|
+
* and a run is counted by the name, so its past runs, its switch and a person's other picks for
|
|
122
|
+
* it stay its own.
|
|
123
|
+
*
|
|
124
|
+
* A shared one is a file of the project: the change is the person's to commit, and a run reads
|
|
125
|
+
* the prompt from the commit its checkout starts from, so it is told the new words only once the
|
|
126
|
+
* change is there, while the tick reads the new pace and the new check from the person's checkout
|
|
127
|
+
* at once. One kept on this machine has only its file: the next tick reads all of it.
|
|
128
|
+
*
|
|
129
|
+
* Refused for a name that is no automation the tool wrote ({@link savedAutomation}), and for what
|
|
130
|
+
* could not be saved new either ({@link automationProblem}, the length of a text kept here). With
|
|
131
|
+
* `was`, the version whoever asks last read, it is refused too when the file says something else
|
|
132
|
+
* by now: a form opened a while ago does not write over a change made to the file by hand since.
|
|
133
|
+
*/
|
|
134
|
+
export declare function editAutomation(repo: string, name: string, change: AutomationChange, git: GitRunner, opts?: {
|
|
135
|
+
write?: typeof writeFile;
|
|
136
|
+
was?: string;
|
|
137
|
+
}): Promise<Written | AddRefusal | NotAnAutomation | ChangedSince>;
|
|
138
|
+
/** What removing an automation did, and what whoever asked needs to say about it. */
|
|
139
|
+
export type Removed = {
|
|
140
|
+
ok: true;
|
|
141
|
+
command: string; /** The file that was deleted, from the repository root. */
|
|
142
|
+
file: string;
|
|
143
|
+
} & ({
|
|
144
|
+
/** Kept on this machine alone: it was in no git, and nothing of it is left anywhere. */
|
|
145
|
+
onThisMachine: true;
|
|
146
|
+
} | {
|
|
147
|
+
/**
|
|
148
|
+
* What git still holds of a shared one's file: `committed`, the file is in a commit, so the
|
|
149
|
+
* deletion is a change of the person's to commit and git can bring the file back; `staged`,
|
|
150
|
+
* it was added to the index and never committed, so a commit made now would still add it;
|
|
151
|
+
* `nothing`, git never knew the file, and it cannot be brought back; `unknown`, git could
|
|
152
|
+
* not be asked.
|
|
153
|
+
*/
|
|
154
|
+
git: 'committed' | 'staged' | 'nothing' | 'unknown';
|
|
155
|
+
/** What a run's checkout starts from, as git names it: until the deletion is there, everyone else who has the project keeps the command. */
|
|
156
|
+
startsFrom: string;
|
|
157
|
+
});
|
|
158
|
+
/**
|
|
159
|
+
* Remove an automation: its file is deleted, and the folder that held it alone, with what a file
|
|
160
|
+
* manager left beside it. Nothing is committed, and nothing git holds is changed: the deletion of
|
|
161
|
+
* a shared one is a change of the person's where the file is in a commit, and everyone else keeps
|
|
162
|
+
* the command until the deletion reaches them. What was never committed, a shared one's file or
|
|
163
|
+
* its last changes, and all of one kept on this machine, cannot be brought back. The records of
|
|
164
|
+
* its past runs stay.
|
|
165
|
+
*
|
|
166
|
+
* Refused for a name that is no automation the tool wrote ({@link savedAutomation}).
|
|
167
|
+
*/
|
|
168
|
+
export declare function removeAutomation(repo: string, name: string, git: GitRunner): Promise<Removed | NotAnAutomation>;
|
|
169
|
+
/** What trying a check answered. */
|
|
170
|
+
export interface Tried {
|
|
171
|
+
/** The time the check was given as `$LAST_RUN`. */
|
|
172
|
+
lastRun: string;
|
|
173
|
+
/** Whether the check ran to its end without an error. */
|
|
174
|
+
ran: boolean;
|
|
175
|
+
/** Whether what it printed would start an agent. */
|
|
176
|
+
due: boolean;
|
|
177
|
+
/** What it printed, cut as a run is handed it, with the line that says it was cut. */
|
|
178
|
+
printed: string;
|
|
179
|
+
/** Why it did not run, when it did not: that it took too long, or the last line of what it said went wrong. */
|
|
180
|
+
error?: string;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Run a check once, as the tick would, and say what it printed and whether an agent would start:
|
|
184
|
+
* nothing is saved and nothing is started. It asks what is new since a day ago. A try has less
|
|
185
|
+
* time than a tick gives a check ({@link TRY_TIMEOUT_MS}): whoever asks, a dashboard, waits for
|
|
186
|
+
* the answer, and gives up before a tick would.
|
|
187
|
+
*/
|
|
188
|
+
export declare function tryCheck(repo: string, shell: string, now: Date, check?: typeof runCheck, budgetMs?: number): Promise<Tried>;
|
|
189
|
+
//# sourceMappingURL=automation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automation.d.ts","sourceRoot":"","sources":["../src/automation.ts"],"names":[],"mappings":"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"}
|