issuecrew 0.0.0-stage → 0.7.0

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ok0
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/NOTICE ADDED
@@ -0,0 +1,118 @@
1
+ issuecrew
2
+ Copyright (c) 2026 ok0
3
+
4
+ This project includes material ported or adapted from dsh-superagent-prototype
5
+ (https://github.com/deepseek-ai/dsh-superagent-prototype), distributed under
6
+ the MIT License reproduced below.
7
+
8
+ ----------------------------------------------------------------------
9
+ MIT License
10
+
11
+ Copyright (c) 2026 DeepSeek Harness Team
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ ----------------------------------------------------------------------
31
+
32
+ Ported files
33
+ ------------
34
+ Each ported file starts with the header "// Ported from dsh-superagent-prototype (MIT) <reference path>" (Markdown files: "<!-- Ported from dsh-superagent-prototype (MIT) <reference path> -->").
35
+
36
+ prompts/admission.md <- prompts/admission.md
37
+ prompts/dispatch.md <- prompts/dispatch.md
38
+ prompts/handoff-router.md <- prompts/handoff-orchestrator.md
39
+ prompts/handoff-worker.md <- prompts/handoff-worker.md
40
+ prompts/handoff.md <- prompts/handoff.md
41
+ prompts/replies.md <- prompts/replies.md
42
+ prompts/router.md <- prompts/orchestrator.md
43
+ prompts/shared.md <- prompts/shared.md
44
+ prompts/subscriptions.md <- prompts/subscriptions.md
45
+ prompts/team/communication.md <- prompts/team/communication.md
46
+ prompts/team/delivery.md <- prompts/team/delivery.md
47
+ prompts/team/scope.md <- prompts/team/scope.md
48
+ prompts/work.md <- prompts/work.md
49
+ prompts/worker.md <- prompts/worker.md
50
+ skills/github.md <- skills/dsh-superagent-github/SKILL.md
51
+ src/app/assessment.ts <- src/app/assessment.ts
52
+ src/app/cache.ts <- src/app/cache.ts
53
+ src/app/cards.ts <- src/app/cards.ts
54
+ src/app/effects.ts <- src/app/effects.ts
55
+ src/app/kv.ts <- src/kv.ts
56
+ src/app/links.ts <- src/app/links.ts (with triggerMessage from src/executor/dsh.ts)
57
+ src/app/notices.ts <- src/app/notices.ts
58
+ src/app/outbox.ts <- src/app/outbox.ts
59
+ src/app/passes.ts <- src/app/passes.ts
60
+ src/app/prompts.ts <- src/app/prompts.ts
61
+ src/app/resources.ts <- src/app/resources.ts
62
+ src/app/store.ts <- src/app/store.ts
63
+ src/app/store-read.ts <- src/app/store-read.ts
64
+ src/app/tools/executor.ts <- src/app/tools/executor.ts
65
+ src/app/tools/main.ts <- src/app/tools/main.ts
66
+ src/app/tools/tool.ts <- src/app/tools/tool.ts
67
+ src/app/versions.ts <- src/app/versions.ts
68
+ src/core/assignments.ts <- src/core/assignments.ts
69
+ src/core/engine.ts <- src/core/engine.ts
70
+ src/core/errors.ts <- src/core/errors.ts
71
+ src/core/evals.ts <- src/core/evals.ts
72
+ src/core/ids.ts <- src/core/ids.ts
73
+ src/core/index.ts <- src/core/index.ts
74
+ src/core/intake.ts <- src/core/intake.ts
75
+ src/core/memory.ts <- src/core/memory.ts
76
+ src/core/model.ts <- src/core/model.ts
77
+ src/core/part.ts <- src/core/part.ts
78
+ src/core/ports.ts <- src/core/ports.ts
79
+ src/core/reasons.ts <- src/core/reasons.ts
80
+ src/core/replies.ts <- src/core/replies.ts
81
+ src/core/stage.ts <- src/core/stage.ts
82
+ src/core/tickets.ts <- src/core/tickets.ts
83
+ src/executor/recovery.ts <- src/executor/dsh.ts (restart recovery)
84
+ src/infra/commands.ts <- src/infra/commands.ts
85
+ src/infra/health.ts <- src/infra/health.ts
86
+ src/infra/paths.ts <- src/infra/paths.ts
87
+ src/infra/text.ts <- src/infra/text.ts
88
+ src/policy/admission.ts <- src/admission.ts
89
+ src/policy/limits.ts <- src/limits.ts
90
+ src/policy/policy.ts <- src/policy.ts
91
+ src/sources/admission-context.ts <- src/sources/admission-context.ts
92
+ src/sources/github/channel.ts <- src/sources/github-channel.ts
93
+ src/sources/github/pull.ts <- src/sources/github-pull.ts
94
+ src/sources/github/read.ts <- src/sources/github-read.ts
95
+ src/sources/github/source.ts <- src/sources/github.ts
96
+ src/sources/github/trigger.ts <- src/sources/github-trigger.ts
97
+ src/sources/host.ts <- src/sources/host.ts (with sourceContextOf from src/app/source-context.ts)
98
+ src/sources/kind.ts <- src/sources/kind.ts
99
+ src/sources/poll.ts <- src/sources/poll.ts
100
+ src/sources/registry.ts <- src/sources/registry.ts
101
+ tests/admission-context.spec.ts <- tests/admission-context.spec.ts
102
+ tests/assessment.spec.ts <- tests/assessment.spec.ts
103
+ tests/cache.spec.ts <- tests/cache.spec.ts
104
+ tests/core-engine.spec.ts <- tests/core-engine.spec.ts
105
+ tests/effects.spec.ts <- tests/effects.spec.ts
106
+ tests/followups.spec.ts <- tests/followups.spec.ts
107
+ tests/fixtures/async.ts <- tests/fixtures/async.ts
108
+ tests/fixtures/engine.ts <- tests/core-engine.spec.ts (harness)
109
+ tests/fixtures/host.ts <- tests/fixtures/host.ts (rewritten over the fake runtime)
110
+ tests/github-read.spec.ts <- tests/github-read.spec.ts
111
+ tests/outbox.spec.ts <- tests/outbox.spec.ts
112
+ tests/passes.spec.ts <- tests/passes.spec.ts
113
+ tests/policy.spec.ts <- tests/policy.spec.ts
114
+ tests/queue.spec.ts <- tests/queue.spec.ts (L28)
115
+ tests/registry.spec.ts <- tests/registry.spec.ts
116
+ tests/router-tools.spec.ts <- tests/tools.spec.ts (Router cases)
117
+ tests/stage.spec.ts <- tests/stage.spec.ts
118
+ tests/store.spec.ts <- tests/store.spec.ts
package/README.md CHANGED
@@ -1,3 +1,58 @@
1
- # Temporary Holding Version
1
+ # issuecrew
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ ![Four requests, three allowed, each in its own git worktree at the same time, ending in two pull requests and one reply](docs/assets/hero.svg)
4
+
5
+ issuecrew is a proactive coding agent for GitHub repositories. Powered by Claude. It polls the repositories you configure. When a person on the allowlist asks it for work, it opens a ticket, does the work in its own session and git worktree, and answers in the original conversation, for example with a pull request.
6
+
7
+ Take as little human attention as possible, and give as much value as possible. The agent acts only when an allowed person asks or when a rule you wrote allows it, and it speaks only when someone must act or can use a result.
8
+
9
+ ## How it works
10
+
11
+ ![Flow: an allowed person mentions the agent, allowlist admission, a ticket, its own session and git worktree, then a reply comment or a pull request](docs/assets/flow.svg)
12
+
13
+ ## Quick start
14
+
15
+ ```sh
16
+ npm i -g issuecrew
17
+ export ISSUECREW_GITHUB_TOKEN=<agent account token>
18
+ export ANTHROPIC_API_KEY=<API key> # either: API key
19
+ export CLAUDE_CODE_OAUTH_TOKEN=<token> # or: Claude subscription (token from `claude setup-token`)
20
+ issuecrew start --config issuecrew.json
21
+ ```
22
+
23
+ It needs Node.js 22.19 or later. `npx issuecrew start --config issuecrew.json` runs it without a global install.
24
+
25
+ `auth.mode` picks which one (`api-key` or `subscription`); Bedrock and Vertex also work. See [docs/authentication.md](docs/authentication.md) for both modes and the subscription terms warning.
26
+
27
+ The config needs `repositories` and `policy.allowed`; `auth.mode` defaults to `api-key` and needs its credential. See [docs/getting-started.md](docs/getting-started.md), which also covers building from source.
28
+
29
+ A container image is published as `ghcr.io/ok0/issuecrew`. See [Docker](docs/deploy.md#docker) to run it.
30
+
31
+ ## Documentation
32
+
33
+ - [Getting started](docs/getting-started.md): install, agent account, start
34
+ - [Configuration](docs/configuration.md): settings and defaults
35
+ - [Authentication](docs/authentication.md): auth modes and start refusals
36
+ - [Runtime contract](docs/runtime-contract.md)
37
+ - [Deploy](docs/deploy.md): run as a service
38
+ - [Running multiple accounts/projects](docs/deploy.md#running-multiple-accountsprojects): one instance per account or project
39
+ - [Security](docs/security.md): trust policy
40
+ - [Contributing](CONTRIBUTING.md): setup, checks and pull requests
41
+
42
+ ## Works with issuecrew-planner
43
+
44
+ ![issuecrew and issuecrew-planner: each works on its own, and the planner's GitHub issues can optionally feed the agent](docs/assets/works-with.svg)
45
+
46
+ Each tool works on its own, and they can be used together. issuecrew handles one request in one repository at a time. For a change that spans several repositories, [issuecrew-planner](https://www.npmjs.com/package/issuecrew-planner) splits it into one GitHub issue per repository, with a shared contract and a merge order, and mentions the agent in each issue. issuecrew then works through those issues like any other request. You don't need the planner to use the agent.
47
+
48
+ ## Known limitations
49
+
50
+ The worker cannot run end-to-end tests that need services, databases, browsers or Docker inside the sandbox, and it has no per-ticket setup: it does not prepare dependencies in each ticket's worktree. Both are open for later review. See [Known limitations](docs/deploy.md#known-limitations).
51
+
52
+ ## Test repositories
53
+
54
+ Live tests write only to the repository named by `ISSUECREW_LIVE_REPO` and may read the optional `ISSUECREW_LIVE_REPORT_REPO`. Without these settings the live tests that need GitHub are skipped. Seed the playground with `pnpm live:seed` (`pnpm live:seed --upgrade` replaces an older seed in one commit) and clean it with `pnpm live:cleanup`. See [Run live tests against your own playground](CONTRIBUTING.md#run-live-tests-against-your-own-playground). The project's own live runs use [ok0/issuecrew-playground](https://github.com/ok0/issuecrew-playground) as the playground.
55
+
56
+ ## License
57
+
58
+ MIT. See [LICENSE](LICENSE) and [NOTICE](NOTICE).
package/lib/cli.js ADDED
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ // src/infra/redact.ts
3
+ /** Masking of secret values and token shapes in text shown to people or written to logs. */
4
+ const REDACTED = "[redacted]";
5
+ function redactor(env, mask = "***") {
6
+ const values = [];
7
+ for (const [name, value] of Object.entries(env)) if (typeof value === "string" && value.length >= 8 && /(TOKEN|SECRET|PASSWORD|API_KEY|ACCESS_KEY|CREDENTIAL)/i.test(name)) values.push(value);
8
+ return (text) => {
9
+ let out = text;
10
+ for (const value of values) out = out.split(value).join(mask);
11
+ return out.replace(/\bgh[pousr]_[A-Za-z0-9_]{16,}/g, mask).replace(/\b[A-Za-z]+_pat_[A-Za-z0-9_]{16,}/g, mask).replace(/\bsk-ant-[A-Za-z0-9_-]{8,}/g, mask).replace(/x-access-token:[^@\s]+@/g, `x-access-token:${mask}@`);
12
+ };
13
+ }
14
+ function redact(text, env, mask = "***") {
15
+ return redactor(env, mask)(text);
16
+ }
17
+ function logFormat(argv, env) {
18
+ let value = env["ISSUECREW_LOG_FORMAT"] || void 0;
19
+ for (let i = 0; i < argv.length; i++) {
20
+ const arg = argv[i];
21
+ if (arg === "--config") i++;
22
+ else if (arg === "--log-format") {
23
+ value = argv[i + 1];
24
+ if (value === void 0) return void 0;
25
+ i++;
26
+ }
27
+ }
28
+ if (value === void 0) return "text";
29
+ return value === "text" || value === "json" ? value : void 0;
30
+ }
31
+ // src/cli/bin.ts
32
+ /** After main() returns, the process is force-exited after this grace if something still holds the event loop. */
33
+ const EXIT_GRACE_MS = 3e3;
34
+ const argv = process.argv.slice(2);
35
+ const json = argv[0] === "start" && logFormat(argv.slice(1), process.env) === "json";
36
+ const mask = redactor(process.env, REDACTED);
37
+ const event = (level, name, detail) => mask(JSON.stringify({
38
+ level,
39
+ at: (/* @__PURE__ */ new Date()).toISOString(),
40
+ event: name,
41
+ detail
42
+ })) + "\n";
43
+ if (json) {
44
+ process.removeAllListeners("warning");
45
+ process.on("warning", (warning) => {
46
+ process.stdout.write(event("warn", "node.warning", `${warning.name}: ${warning.message}`));
47
+ });
48
+ process.on("uncaughtException", (error) => {
49
+ process.stdout.write(event("error", "cli.failed", String(error)));
50
+ process.exit(1);
51
+ });
52
+ }
53
+ const exitSoon = () => {
54
+ setTimeout(() => {
55
+ process.exit();
56
+ }, EXIT_GRACE_MS).unref();
57
+ };
58
+ import("./main-Bx8ul26o.js").then(({ main }) => main(argv, {
59
+ out: (s) => {
60
+ process.stdout.write(s);
61
+ },
62
+ err: (s) => {
63
+ process.stderr.write(s);
64
+ },
65
+ cwd: process.cwd(),
66
+ env: process.env,
67
+ signals: process
68
+ })).then((code) => {
69
+ process.exitCode = code;
70
+ exitSoon();
71
+ }, (error) => {
72
+ if (json) process.stdout.write(event("error", "cli.failed", String(error)));
73
+ else process.stderr.write(`issuecrew: ${String(error)}\n`);
74
+ process.exitCode = 1;
75
+ exitSoon();
76
+ });
77
+ export { redactor as i, REDACTED as n, redact as r, logFormat as t };