@agentteams/runner 0.0.97 → 0.0.99
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/api-client.d.ts +1 -0
- package/dist/api-client.js +20 -1
- package/dist/api-client.js.map +1 -1
- package/dist/api-client.test.js +48 -1
- package/dist/api-client.test.js.map +1 -1
- package/dist/autostart.d.ts +37 -8
- package/dist/autostart.js +158 -68
- package/dist/autostart.js.map +1 -1
- package/dist/autostart.test.js +130 -76
- package/dist/autostart.test.js.map +1 -1
- package/dist/commands/start.js +2 -2
- package/dist/commands/stop.d.ts +10 -1
- package/dist/commands/stop.js +11 -7
- package/dist/commands/stop.js.map +1 -1
- package/dist/commands/stop.test.d.ts +1 -0
- package/dist/commands/stop.test.js +34 -0
- package/dist/commands/stop.test.js.map +1 -0
- package/dist/commands/uninstall.d.ts +13 -1
- package/dist/commands/uninstall.js +21 -10
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/uninstall.test.d.ts +1 -0
- package/dist/commands/uninstall.test.js +42 -0
- package/dist/commands/uninstall.test.js.map +1 -0
- package/dist/daemon-control.d.ts +2 -1
- package/dist/daemon-control.js +16 -6
- package/dist/daemon-control.js.map +1 -1
- package/dist/daemon-control.test.js +27 -3
- package/dist/daemon-control.test.js.map +1 -1
- package/dist/executable.test.js +13 -0
- package/dist/executable.test.js.map +1 -1
- package/dist/handlers/trigger-handler.d.ts +2 -0
- package/dist/handlers/trigger-handler.js +36 -5
- package/dist/handlers/trigger-handler.js.map +1 -1
- package/dist/handlers/trigger-handler.test.js +298 -0
- package/dist/handlers/trigger-handler.test.js.map +1 -1
- package/dist/poller.test.js +23 -0
- package/dist/poller.test.js.map +1 -1
- package/dist/runners/capabilities.js +1 -0
- package/dist/runners/capabilities.js.map +1 -1
- package/dist/runners/capabilities.test.js +13 -1
- package/dist/runners/capabilities.test.js.map +1 -1
- package/dist/runners/codex.test.js +1 -1
- package/dist/runners/codex.test.js.map +1 -1
- package/dist/runners/cursor-cli.d.ts +27 -0
- package/dist/runners/cursor-cli.js +276 -0
- package/dist/runners/cursor-cli.js.map +1 -0
- package/dist/runners/cursor-cli.test.d.ts +1 -0
- package/dist/runners/cursor-cli.test.js +189 -0
- package/dist/runners/cursor-cli.test.js.map +1 -0
- package/dist/runners/index.js +3 -0
- package/dist/runners/index.js.map +1 -1
- package/dist/runners/index.test.js +2 -0
- package/dist/runners/index.test.js.map +1 -1
- package/dist/runners/stream-json-parser.d.ts +9 -0
- package/dist/runners/stream-json-parser.js +143 -0
- package/dist/runners/stream-json-parser.js.map +1 -1
- package/dist/runners/stream-json-parser.test.js +117 -1
- package/dist/runners/stream-json-parser.test.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/utils/git-worktree.js +2 -1
- package/dist/utils/git-worktree.js.map +1 -1
- package/dist/utils/git-worktree.test.js +2 -2
- package/dist/utils/git-worktree.test.js.map +1 -1
- package/dist/utils/resolve-member-repo.d.ts +39 -0
- package/dist/utils/resolve-member-repo.js +180 -0
- package/dist/utils/resolve-member-repo.js.map +1 -0
- package/dist/utils/resolve-member-repo.test.d.ts +1 -0
- package/dist/utils/resolve-member-repo.test.js +201 -0
- package/dist/utils/resolve-member-repo.test.js.map +1 -0
- package/package.json +2 -2
- package/readme.md +24 -6
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { execFileSync } from 'node:child_process';
|
|
3
|
+
import { mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { basename, join } from 'node:path';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
6
|
+
import test from 'node:test';
|
|
7
|
+
import { findMemberRepoCandidates, normalizeRemoteUrl, resolveWorktreeAuthPath } from './resolve-member-repo.js';
|
|
8
|
+
const makeTempDir = (prefix) => mkdtempSync(join(tmpdir(), prefix));
|
|
9
|
+
const initGitRepo = (dir, originUrl) => {
|
|
10
|
+
execFileSync('git', ['init', dir], { stdio: 'pipe' });
|
|
11
|
+
execFileSync('git', ['-C', dir, 'config', 'user.email', 'test@test.com'], { stdio: 'pipe' });
|
|
12
|
+
execFileSync('git', ['-C', dir, 'config', 'user.name', 'Test'], { stdio: 'pipe' });
|
|
13
|
+
execFileSync('git', ['-C', dir, 'commit', '--allow-empty', '-m', 'initial'], { stdio: 'pipe' });
|
|
14
|
+
if (originUrl) {
|
|
15
|
+
execFileSync('git', ['-C', dir, 'remote', 'add', 'origin', originUrl], { stdio: 'pipe' });
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const cleanupDir = (dir) => {
|
|
19
|
+
rmSync(dir, { recursive: true, force: true });
|
|
20
|
+
};
|
|
21
|
+
test('normalizeRemoteUrl unifies https, scp-ssh, and ssh scheme forms', () => {
|
|
22
|
+
const expected = 'github.com/rlarua/kma-ui';
|
|
23
|
+
assert.equal(normalizeRemoteUrl('https://github.com/rlarua/kma-ui.git'), expected);
|
|
24
|
+
assert.equal(normalizeRemoteUrl('https://github.com/rlarua/kma-ui'), expected);
|
|
25
|
+
assert.equal(normalizeRemoteUrl('https://github.com/rlarua/kma-ui/'), expected);
|
|
26
|
+
assert.equal(normalizeRemoteUrl('git@github.com:rlarua/kma-ui.git'), expected);
|
|
27
|
+
assert.equal(normalizeRemoteUrl('ssh://git@github.com/rlarua/kma-ui.git'), expected);
|
|
28
|
+
assert.equal(normalizeRemoteUrl('ssh://git@github.com:22/rlarua/kma-ui.git'), expected);
|
|
29
|
+
assert.equal(normalizeRemoteUrl('HTTPS://GitHub.com/RLarua/KMA-UI.git'), expected);
|
|
30
|
+
});
|
|
31
|
+
// custom port는 서버 신원의 일부다: 같은 호스트의 다른 포트는 다른 Git 서버이므로
|
|
32
|
+
// 불일치해야 하고, 프로토콜 기본 포트만 무포트 URL과 일치한다.
|
|
33
|
+
test('normalizeRemoteUrl keeps non-default ports and strips protocol-default ports', () => {
|
|
34
|
+
assert.equal(normalizeRemoteUrl('https://git.example.com:8443/team/repo.git'), 'git.example.com:8443/team/repo');
|
|
35
|
+
assert.notEqual(normalizeRemoteUrl('https://git.example.com:8443/team/repo.git'), normalizeRemoteUrl('https://git.example.com:9443/team/repo.git'));
|
|
36
|
+
assert.notEqual(normalizeRemoteUrl('https://git.example.com:8443/team/repo.git'), normalizeRemoteUrl('https://git.example.com/team/repo.git'));
|
|
37
|
+
// Explicit default ports match the port-less form.
|
|
38
|
+
assert.equal(normalizeRemoteUrl('https://git.example.com:443/team/repo.git'), 'git.example.com/team/repo');
|
|
39
|
+
assert.equal(normalizeRemoteUrl('http://git.example.com:80/team/repo.git'), 'git.example.com/team/repo');
|
|
40
|
+
assert.equal(normalizeRemoteUrl('ssh://git@git.example.com:22/team/repo.git'), 'git.example.com/team/repo');
|
|
41
|
+
assert.equal(normalizeRemoteUrl('git://git.example.com:9418/team/repo.git'), 'git.example.com/team/repo');
|
|
42
|
+
// Non-default ssh port stays part of the identity.
|
|
43
|
+
assert.equal(normalizeRemoteUrl('ssh://git@git.example.com:2222/team/repo.git'), 'git.example.com:2222/team/repo');
|
|
44
|
+
});
|
|
45
|
+
test('normalizeRemoteUrl rejects empty or unrecognizable values', () => {
|
|
46
|
+
assert.equal(normalizeRemoteUrl(''), null);
|
|
47
|
+
assert.equal(normalizeRemoteUrl(' '), null);
|
|
48
|
+
assert.equal(normalizeRemoteUrl('not a url'), null);
|
|
49
|
+
assert.equal(normalizeRemoteUrl('git@github.com:'), null);
|
|
50
|
+
});
|
|
51
|
+
// 판정 기준 계약 테스트: CLI findMemberRepos(cli/src/utils/projectLayout.ts)와 동일하게
|
|
52
|
+
// 1뎁스 물리 디렉터리만 후보로 삼고 숨김/node_modules/심링크/비-git/중첩 작업트리를 제외한다.
|
|
53
|
+
test('findMemberRepoCandidates matches the CLI findMemberRepos judgement contract', () => {
|
|
54
|
+
const root = makeTempDir('resolve-member-contract-');
|
|
55
|
+
try {
|
|
56
|
+
// Included: plain member git repos at depth 1
|
|
57
|
+
initGitRepo(join(root, 'repo-a'));
|
|
58
|
+
initGitRepo(join(root, 'repo-b'));
|
|
59
|
+
// Excluded: hidden directory, even if it is a git repo
|
|
60
|
+
initGitRepo(join(root, '.hidden-repo'));
|
|
61
|
+
// Excluded: node_modules, even if it is a git repo
|
|
62
|
+
initGitRepo(join(root, 'node_modules'));
|
|
63
|
+
// Excluded: non-git plain directory
|
|
64
|
+
mkdirSync(join(root, 'plain-dir'));
|
|
65
|
+
// Excluded: plain file
|
|
66
|
+
writeFileSync(join(root, 'README.md'), '# root');
|
|
67
|
+
// Excluded: symlinked directory pointing at a real git repo
|
|
68
|
+
symlinkSync(join(root, 'repo-a'), join(root, 'linked-repo'), 'dir');
|
|
69
|
+
// Excluded: directory that is merely inside another repository's work tree
|
|
70
|
+
mkdirSync(join(root, 'repo-a', 'nested'));
|
|
71
|
+
const candidates = findMemberRepoCandidates(root);
|
|
72
|
+
assert.deepEqual(candidates.map((candidate) => basename(candidate)), ['repo-a', 'repo-b']);
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
cleanupDir(root);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
test('findMemberRepoCandidates returns empty list for unreadable root', () => {
|
|
79
|
+
assert.deepEqual(findMemberRepoCandidates(join(tmpdir(), `nonexistent-${Date.now()}`)), []);
|
|
80
|
+
});
|
|
81
|
+
test('resolveWorktreeAuthPath returns authPath as-is when it is a git repository', () => {
|
|
82
|
+
const repo = makeTempDir('resolve-member-git-');
|
|
83
|
+
try {
|
|
84
|
+
initGitRepo(repo);
|
|
85
|
+
assert.deepEqual(resolveWorktreeAuthPath(repo, null), { path: repo });
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
cleanupDir(repo);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
test('resolveWorktreeAuthPath resolves the single member repo matching remoteUrl', () => {
|
|
92
|
+
const root = makeTempDir('resolve-member-match-');
|
|
93
|
+
try {
|
|
94
|
+
initGitRepo(join(root, 'kma-ui'), 'git@github.com:rlarua/kma-ui.git');
|
|
95
|
+
initGitRepo(join(root, 'kma-api'), 'git@github.com:rlarua/kma-api.git');
|
|
96
|
+
const resolution = resolveWorktreeAuthPath(root, 'https://github.com/rlarua/kma-ui.git');
|
|
97
|
+
assert.deepEqual(resolution, { path: join(root, 'kma-ui') });
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
cleanupDir(root);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
test('resolveWorktreeAuthPath fails with guidance when remoteUrl is null', () => {
|
|
104
|
+
const root = makeTempDir('resolve-member-null-');
|
|
105
|
+
try {
|
|
106
|
+
initGitRepo(join(root, 'kma-ui'), 'git@github.com:rlarua/kma-ui.git');
|
|
107
|
+
const resolution = resolveWorktreeAuthPath(root, null);
|
|
108
|
+
assert.ok('error' in resolution);
|
|
109
|
+
assert.match(resolution.error, /has no remote URL/);
|
|
110
|
+
assert.match(resolution.error, /Turn off the runner box/);
|
|
111
|
+
assert.doesNotMatch(resolution.error, /git init/);
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
cleanupDir(root);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
test('resolveWorktreeAuthPath fails with guidance when no member repo matches', () => {
|
|
118
|
+
const root = makeTempDir('resolve-member-none-');
|
|
119
|
+
try {
|
|
120
|
+
initGitRepo(join(root, 'kma-ui'), 'git@github.com:rlarua/kma-ui.git');
|
|
121
|
+
const resolution = resolveWorktreeAuthPath(root, 'https://github.com/rlarua/other-repo.git');
|
|
122
|
+
assert.ok('error' in resolution);
|
|
123
|
+
assert.match(resolution.error, /no member repository/);
|
|
124
|
+
assert.match(resolution.error, /Turn off the runner box/);
|
|
125
|
+
assert.doesNotMatch(resolution.error, /git init/);
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
cleanupDir(root);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
test('resolveWorktreeAuthPath fails with guidance when multiple member repos match', () => {
|
|
132
|
+
const root = makeTempDir('resolve-member-dup-');
|
|
133
|
+
try {
|
|
134
|
+
initGitRepo(join(root, 'kma-ui'), 'git@github.com:rlarua/kma-ui.git');
|
|
135
|
+
initGitRepo(join(root, 'kma-ui-copy'), 'https://github.com/rlarua/kma-ui.git');
|
|
136
|
+
const resolution = resolveWorktreeAuthPath(root, 'https://github.com/rlarua/kma-ui.git');
|
|
137
|
+
assert.ok('error' in resolution);
|
|
138
|
+
assert.match(resolution.error, /multiple member repositories/);
|
|
139
|
+
assert.match(resolution.error, /kma-ui/);
|
|
140
|
+
assert.match(resolution.error, /kma-ui-copy/);
|
|
141
|
+
assert.match(resolution.error, /Turn off the runner box/);
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
cleanupDir(root);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
test('resolveWorktreeAuthPath fails when the remote URL is unrecognizable', () => {
|
|
148
|
+
const root = makeTempDir('resolve-member-badurl-');
|
|
149
|
+
try {
|
|
150
|
+
initGitRepo(join(root, 'kma-ui'), 'git@github.com:rlarua/kma-ui.git');
|
|
151
|
+
const resolution = resolveWorktreeAuthPath(root, 'not a url');
|
|
152
|
+
assert.ok('error' in resolution);
|
|
153
|
+
assert.match(resolution.error, /not recognized/);
|
|
154
|
+
assert.match(resolution.error, /Turn off the runner box/);
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
cleanupDir(root);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
// 오류 메시지는 TriggerLogReporter/worktreeError로 서버에 영구 전송되므로
|
|
161
|
+
// credential 포함 remote URL의 비밀값이 어떤 실패 경로에서도 노출되면 안 된다.
|
|
162
|
+
test('resolveWorktreeAuthPath never leaks credentials from the remote URL into errors', () => {
|
|
163
|
+
const root = makeTempDir('resolve-member-cred-');
|
|
164
|
+
try {
|
|
165
|
+
initGitRepo(join(root, 'kma-ui'), 'git@github.com:rlarua/kma-ui.git');
|
|
166
|
+
initGitRepo(join(root, 'other-a'), 'https://github.com/rlarua/other.git');
|
|
167
|
+
initGitRepo(join(root, 'other-b'), 'git@github.com:rlarua/other.git');
|
|
168
|
+
const secret = 'user:s3cret-token';
|
|
169
|
+
// Zero matches
|
|
170
|
+
const none = resolveWorktreeAuthPath(root, `https://${secret}@example.com/team/none.git`);
|
|
171
|
+
assert.ok('error' in none);
|
|
172
|
+
assert.doesNotMatch(none.error, /s3cret-token/);
|
|
173
|
+
assert.match(none.error, /example\.com\/team\/none/);
|
|
174
|
+
// Multiple matches
|
|
175
|
+
const dup = resolveWorktreeAuthPath(root, `https://${secret}@github.com/rlarua/other.git`);
|
|
176
|
+
assert.ok('error' in dup);
|
|
177
|
+
assert.doesNotMatch(dup.error, /s3cret-token/);
|
|
178
|
+
assert.match(dup.error, /github\.com\/rlarua\/other/);
|
|
179
|
+
// Unrecognizable URL: raw value must not be echoed at all
|
|
180
|
+
const bad = resolveWorktreeAuthPath(root, `://${secret}@:not-a-url`);
|
|
181
|
+
assert.ok('error' in bad);
|
|
182
|
+
assert.doesNotMatch(bad.error, /s3cret-token/);
|
|
183
|
+
assert.match(bad.error, /not recognized/);
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
cleanupDir(root);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
test('resolveWorktreeAuthPath ignores member repos without an origin remote', () => {
|
|
190
|
+
const root = makeTempDir('resolve-member-no-origin-');
|
|
191
|
+
try {
|
|
192
|
+
initGitRepo(join(root, 'no-origin'));
|
|
193
|
+
initGitRepo(join(root, 'kma-ui'), 'git@github.com:rlarua/kma-ui.git');
|
|
194
|
+
const resolution = resolveWorktreeAuthPath(root, 'https://github.com/rlarua/kma-ui.git');
|
|
195
|
+
assert.deepEqual(resolution, { path: join(root, 'kma-ui') });
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
cleanupDir(root);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
//# sourceMappingURL=resolve-member-repo.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-member-repo.test.js","sourceRoot":"","sources":["../../src/utils/resolve-member-repo.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAEjH,MAAM,WAAW,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;AAEpF,MAAM,WAAW,GAAG,CAAC,GAAW,EAAE,SAAkB,EAAQ,EAAE;IAC5D,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACtD,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7F,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACnF,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAChG,IAAI,SAAS,EAAE,CAAC;QACd,YAAY,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,GAAW,EAAQ,EAAE;IACvC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAChD,CAAC,CAAC;AAEF,IAAI,CAAC,iEAAiE,EAAE,GAAG,EAAE;IAC3E,MAAM,QAAQ,GAAG,0BAA0B,CAAC;IAC5C,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,sCAAsC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACnF,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,kCAAkC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC/E,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,mCAAmC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAChF,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,kCAAkC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC/E,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,wCAAwC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACrF,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,2CAA2C,CAAC,EAAE,QAAQ,CAAC,CAAC;IACxF,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,sCAAsC,CAAC,EAAE,QAAQ,CAAC,CAAC;AACrF,CAAC,CAAC,CAAC;AAEH,uDAAuD;AACvD,uCAAuC;AACvC,IAAI,CAAC,8EAA8E,EAAE,GAAG,EAAE;IACxF,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,4CAA4C,CAAC,EAAE,gCAAgC,CAAC,CAAC;IACjH,MAAM,CAAC,QAAQ,CACb,kBAAkB,CAAC,4CAA4C,CAAC,EAChE,kBAAkB,CAAC,4CAA4C,CAAC,CACjE,CAAC;IACF,MAAM,CAAC,QAAQ,CACb,kBAAkB,CAAC,4CAA4C,CAAC,EAChE,kBAAkB,CAAC,uCAAuC,CAAC,CAC5D,CAAC;IAEF,mDAAmD;IACnD,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,2CAA2C,CAAC,EAAE,2BAA2B,CAAC,CAAC;IAC3G,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,yCAAyC,CAAC,EAAE,2BAA2B,CAAC,CAAC;IACzG,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,4CAA4C,CAAC,EAAE,2BAA2B,CAAC,CAAC;IAC5G,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,0CAA0C,CAAC,EAAE,2BAA2B,CAAC,CAAC;IAE1G,mDAAmD;IACnD,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,8CAA8C,CAAC,EAAE,gCAAgC,CAAC,CAAC;AACrH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2DAA2D,EAAE,GAAG,EAAE;IACrE,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3C,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC;IACpD,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC,CAAC;AAC5D,CAAC,CAAC,CAAC;AAEH,0EAA0E;AAC1E,+DAA+D;AAC/D,IAAI,CAAC,6EAA6E,EAAE,GAAG,EAAE;IACvF,MAAM,IAAI,GAAG,WAAW,CAAC,0BAA0B,CAAC,CAAC;IACrD,IAAI,CAAC;QACH,8CAA8C;QAC9C,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAClC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAElC,uDAAuD;QACvD,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;QAExC,mDAAmD;QACnD,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;QAExC,oCAAoC;QACpC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;QAEnC,uBAAuB;QACvB,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;QAEjD,4DAA4D;QAC5D,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,KAAK,CAAC,CAAC;QAEpE,2EAA2E;QAC3E,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;QAE1C,MAAM,UAAU,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,CAAC,SAAS,CACd,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,EAClD,CAAC,QAAQ,EAAE,QAAQ,CAAC,CACrB,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,GAAG,EAAE;IAC3E,MAAM,CAAC,SAAS,CAAC,wBAAwB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC9F,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4EAA4E,EAAE,GAAG,EAAE;IACtF,MAAM,IAAI,GAAG,WAAW,CAAC,qBAAqB,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,WAAW,CAAC,IAAI,CAAC,CAAC;QAClB,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,4EAA4E,EAAE,GAAG,EAAE;IACtF,MAAM,IAAI,GAAG,WAAW,CAAC,uBAAuB,CAAC,CAAC;IAClD,IAAI,CAAC;QACH,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,kCAAkC,CAAC,CAAC;QACtE,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,mCAAmC,CAAC,CAAC;QAExE,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAC;QACzF,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oEAAoE,EAAE,GAAG,EAAE;IAC9E,MAAM,IAAI,GAAG,WAAW,CAAC,sBAAsB,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,kCAAkC,CAAC,CAAC;QAEtE,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACvD,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,UAAU,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAC;QAC1D,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACpD,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yEAAyE,EAAE,GAAG,EAAE;IACnF,MAAM,IAAI,GAAG,WAAW,CAAC,sBAAsB,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,kCAAkC,CAAC,CAAC;QAEtE,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,EAAE,0CAA0C,CAAC,CAAC;QAC7F,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,UAAU,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAC;QAC1D,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IACpD,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8EAA8E,EAAE,GAAG,EAAE;IACxF,MAAM,IAAI,GAAG,WAAW,CAAC,qBAAqB,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,kCAAkC,CAAC,CAAC;QACtE,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,sCAAsC,CAAC,CAAC;QAE/E,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAC;QACzF,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,UAAU,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC;QAC/D,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAC;IAC5D,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qEAAqE,EAAE,GAAG,EAAE;IAC/E,MAAM,IAAI,GAAG,WAAW,CAAC,wBAAwB,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,kCAAkC,CAAC,CAAC;QAEtE,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC9D,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,UAAU,CAAC,CAAC;QACjC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,yBAAyB,CAAC,CAAC;IAC5D,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,yDAAyD;AACzD,wDAAwD;AACxD,IAAI,CAAC,iFAAiF,EAAE,GAAG,EAAE;IAC3F,MAAM,IAAI,GAAG,WAAW,CAAC,sBAAsB,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,kCAAkC,CAAC,CAAC;QACtE,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,qCAAqC,CAAC,CAAC;QAC1E,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,iCAAiC,CAAC,CAAC;QAEtE,MAAM,MAAM,GAAG,mBAAmB,CAAC;QAEnC,eAAe;QACf,MAAM,IAAI,GAAG,uBAAuB,CAAC,IAAI,EAAE,WAAW,MAAM,4BAA4B,CAAC,CAAC;QAC1F,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;QAC3B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAAC;QAErD,mBAAmB;QACnB,MAAM,GAAG,GAAG,uBAAuB,CAAC,IAAI,EAAE,WAAW,MAAM,8BAA8B,CAAC,CAAC;QAC3F,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,4BAA4B,CAAC,CAAC;QAEtD,0DAA0D;QAC1D,MAAM,GAAG,GAAG,uBAAuB,CAAC,IAAI,EAAE,MAAM,MAAM,aAAa,CAAC,CAAC;QACrE,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAC5C,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uEAAuE,EAAE,GAAG,EAAE;IACjF,MAAM,IAAI,GAAG,WAAW,CAAC,2BAA2B,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;QACrC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,kCAAkC,CAAC,CAAC;QAEtE,MAAM,UAAU,GAAG,uBAAuB,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAC;QACzF,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentteams/runner",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.99",
|
|
4
4
|
"description": "AgentRunner - Background runner that polls and executes AI agent tasks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"typecheck": "tsc --noEmit",
|
|
17
17
|
"dev": "tsx watch src/index.ts",
|
|
18
18
|
"test": "tsx --test \"src/**/*.test.ts\"",
|
|
19
|
-
"lint": "eslint
|
|
19
|
+
"lint": "eslint \"src/**/*.ts\" --cache --cache-location .eslintcache --cache-strategy content",
|
|
20
20
|
"format": "prettier --write .",
|
|
21
21
|
"format:check": "prettier --check .",
|
|
22
22
|
"start": "node dist/index.js",
|
package/readme.md
CHANGED
|
@@ -38,7 +38,7 @@ The `init` command:
|
|
|
38
38
|
3. Registers an OS-level autostart service and starts the runner immediately
|
|
39
39
|
- **macOS**: `~/Library/LaunchAgents/run.agentteams.runner.plist` (launchd)
|
|
40
40
|
- **Linux**: `~/.config/systemd/user/agentrunner.service` (systemd)
|
|
41
|
-
- **Windows**:
|
|
41
|
+
- **Windows**: Task Scheduler task `AgentRunner` (current-user logon trigger)
|
|
42
42
|
|
|
43
43
|
### Options
|
|
44
44
|
|
|
@@ -91,9 +91,9 @@ Example output:
|
|
|
91
91
|
agentrunner stop
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
-
Sends SIGTERM to the running process for a graceful shutdown.
|
|
94
|
+
Sends SIGTERM to the running process for a graceful shutdown. On Windows, it ends the current `AgentRunner` scheduled-task instance first so the failure policy does not restart an intentionally stopped runner. The task remains registered and can start again at the next logon.
|
|
95
95
|
|
|
96
|
-
>
|
|
96
|
+
> On macOS and Linux, the registered OS supervisor may restart the runner automatically.
|
|
97
97
|
> Use `uninstall` to stop completely.
|
|
98
98
|
|
|
99
99
|
### 5. Restart (`restart`)
|
|
@@ -105,6 +105,7 @@ agentrunner restart
|
|
|
105
105
|
Restarts the runner using the current environment:
|
|
106
106
|
|
|
107
107
|
- If autostart is registered, AgentRunner restarts through the registered OS service.
|
|
108
|
+
- On Windows, restart ends the existing `AgentRunner` task instance before running it again.
|
|
108
109
|
- If autostart is not registered, AgentRunner starts a new detached background process.
|
|
109
110
|
|
|
110
111
|
### 6. Update (`update`)
|
|
@@ -123,8 +124,8 @@ agentrunner uninstall
|
|
|
123
124
|
|
|
124
125
|
Performs the following:
|
|
125
126
|
|
|
126
|
-
1.
|
|
127
|
-
2.
|
|
127
|
+
1. Removes or disables the autostart supervisor so it cannot respawn the runner
|
|
128
|
+
2. Stops the running process
|
|
128
129
|
3. Cleans up the PID file
|
|
129
130
|
|
|
130
131
|
## Configuration
|
|
@@ -170,9 +171,26 @@ If a process is already running for the same `agentConfigId`, new triggers are `
|
|
|
170
171
|
- **Runner logs**: console output (forwarded to OS log system when autostarted)
|
|
171
172
|
- **macOS**: `/tmp/agentrunner.log`, `/tmp/agentrunner-error.log`
|
|
172
173
|
- **Linux**: `journalctl --user -u agentrunner -f`
|
|
173
|
-
- **Windows**:
|
|
174
|
+
- **Windows**: `%USERPROFILE%\.agentteams\agentrunner.log`
|
|
174
175
|
- **Task logs**: `<workdir>/.agentteams/daemonLog/daemon-<triggerId>.log`
|
|
175
176
|
|
|
177
|
+
### Windows recovery checks
|
|
178
|
+
|
|
179
|
+
The `AgentRunner` scheduled task ignores duplicate starts and retries failed exits up to three times at one-minute intervals. Inspect it and follow the append-only daemon log with:
|
|
180
|
+
|
|
181
|
+
```powershell
|
|
182
|
+
schtasks /Query /TN "AgentRunner" /V /FO LIST
|
|
183
|
+
Get-Content "$env:USERPROFILE\.agentteams\agentrunner.log" -Wait
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
For a release smoke test on a disposable Windows test machine:
|
|
187
|
+
|
|
188
|
+
1. Run `agentrunner restart` and verify the scheduled task gets a new runner PID without opening a console window.
|
|
189
|
+
2. End the runner process unexpectedly and verify Task Scheduler starts it again after the configured delay.
|
|
190
|
+
3. Disconnect and reconnect the network, or suspend and resume Windows. API requests that remain stalled are aborted after 30 seconds and retried; verify a later poll attempt or successful poll appears in the log.
|
|
191
|
+
4. Run `agentrunner status`, then `agentrunner stop`. Verify the current task instance stops and does not immediately respawn.
|
|
192
|
+
5. Run `agentrunner uninstall` only when cleanup is intended, and verify `schtasks /Query /TN "AgentRunner"` reports that the task no longer exists.
|
|
193
|
+
|
|
176
194
|
## Troubleshooting
|
|
177
195
|
|
|
178
196
|
### `Missing token. Usage: agentrunner init --token <token> ...`
|