@atolis-hq/wake 0.1.0 → 0.1.3

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/docker/Dockerfile CHANGED
@@ -1,54 +1,54 @@
1
- # syntax=docker/dockerfile:1
2
- FROM node:20-bookworm-slim
3
-
4
- RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
5
- --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
6
- apt-get update \
7
- && apt-get install -y --no-install-recommends git openssh-client ca-certificates curl gnupg \
8
- && mkdir -p /etc/apt/keyrings \
9
- && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
10
- | gpg --dearmor -o /etc/apt/keyrings/githubcli-archive-keyring.gpg \
11
- && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
12
- && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
13
- > /etc/apt/sources.list.d/github-cli.list \
14
- && curl -fsSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
15
- | gpg --dearmor -o /etc/apt/keyrings/ngrok-archive-keyring.gpg \
16
- && chmod go+r /etc/apt/keyrings/ngrok-archive-keyring.gpg \
17
- && echo "deb [signed-by=/etc/apt/keyrings/ngrok-archive-keyring.gpg] https://ngrok-agent.s3.amazonaws.com buster main" \
18
- > /etc/apt/sources.list.d/ngrok.list \
19
- && apt-get update \
20
- && apt-get install -y --no-install-recommends gh ngrok
21
-
22
- RUN --mount=type=cache,target=/root/.npm \
23
- npm install -g @anthropic-ai/claude-code @openai/codex
24
-
25
- RUN useradd --create-home --shell /bin/bash wake \
26
- && mkdir -p /home/wake/.codex-runtime \
27
- && mkdir -p /home/wake/.cursor \
28
- && chown -R wake:wake /home/wake/.codex-runtime \
29
- && chown -R wake:wake /home/wake/.cursor
30
-
31
- ENV CODEX_HOME=/home/wake/.codex-runtime
32
- ENV PATH=/home/wake/.local/bin:$PATH
33
-
34
- RUN curl https://cursor.com/install -fsS | HOME=/home/wake bash \
35
- && printf '#!/bin/bash\n[ "$1" = "agent" ] && shift\nexec ~/.local/bin/agent "$@"\n' \
36
- > /home/wake/.local/bin/cursor \
37
- && chmod +x /home/wake/.local/bin/cursor \
38
- && chown -R wake:wake /home/wake/.local
39
-
40
- WORKDIR /app
41
- COPY package*.json ./
42
- RUN --mount=type=cache,target=/root/.npm \
43
- if [ -f package-lock.json ]; then npm ci; else npm install; fi
44
-
45
- COPY . .
46
- ARG WAKE_BUILD_TAG
47
- RUN WAKE_BUILD_TAG="$WAKE_BUILD_TAG" npm run build && chmod +x docker/entrypoint.sh
48
-
49
- USER wake
50
- WORKDIR /home/wake
51
-
52
- EXPOSE 4317
53
-
54
- ENTRYPOINT ["/app/docker/entrypoint.sh"]
1
+ # syntax=docker/dockerfile:1
2
+ FROM node:20-bookworm-slim
3
+
4
+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
5
+ --mount=type=cache,target=/var/lib/apt/lists,sharing=locked \
6
+ apt-get update \
7
+ && apt-get install -y --no-install-recommends git openssh-client ca-certificates curl gnupg \
8
+ && mkdir -p /etc/apt/keyrings \
9
+ && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
10
+ | gpg --dearmor -o /etc/apt/keyrings/githubcli-archive-keyring.gpg \
11
+ && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
12
+ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
13
+ > /etc/apt/sources.list.d/github-cli.list \
14
+ && curl -fsSL https://ngrok-agent.s3.amazonaws.com/ngrok.asc \
15
+ | gpg --dearmor -o /etc/apt/keyrings/ngrok-archive-keyring.gpg \
16
+ && chmod go+r /etc/apt/keyrings/ngrok-archive-keyring.gpg \
17
+ && echo "deb [signed-by=/etc/apt/keyrings/ngrok-archive-keyring.gpg] https://ngrok-agent.s3.amazonaws.com buster main" \
18
+ > /etc/apt/sources.list.d/ngrok.list \
19
+ && apt-get update \
20
+ && apt-get install -y --no-install-recommends gh ngrok
21
+
22
+ RUN --mount=type=cache,target=/root/.npm \
23
+ npm install -g @anthropic-ai/claude-code @openai/codex
24
+
25
+ RUN useradd --create-home --shell /bin/bash wake \
26
+ && mkdir -p /home/wake/.codex-runtime \
27
+ && mkdir -p /home/wake/.cursor \
28
+ && chown -R wake:wake /home/wake/.codex-runtime \
29
+ && chown -R wake:wake /home/wake/.cursor
30
+
31
+ ENV CODEX_HOME=/home/wake/.codex-runtime
32
+ ENV PATH=/home/wake/.local/bin:$PATH
33
+
34
+ RUN curl https://cursor.com/install -fsS | HOME=/home/wake bash \
35
+ && printf '#!/bin/bash\n[ "$1" = "agent" ] && shift\nexec ~/.local/bin/agent "$@"\n' \
36
+ > /home/wake/.local/bin/cursor \
37
+ && chmod +x /home/wake/.local/bin/cursor \
38
+ && chown -R wake:wake /home/wake/.local
39
+
40
+ WORKDIR /app
41
+ COPY package*.json ./
42
+ RUN --mount=type=cache,target=/root/.npm \
43
+ if [ -f package-lock.json ]; then npm ci; else npm install; fi
44
+
45
+ COPY . .
46
+ ARG WAKE_BUILD_TAG
47
+ RUN WAKE_BUILD_TAG="$WAKE_BUILD_TAG" npm run build && chmod +x docker/entrypoint.sh
48
+
49
+ USER wake
50
+ WORKDIR /home/wake
51
+
52
+ EXPOSE 4317
53
+
54
+ ENTRYPOINT ["/app/docker/entrypoint.sh"]
package/docker/setup.sh CHANGED
File without changes
package/package.json CHANGED
@@ -1,52 +1,56 @@
1
- {
2
- "name": "@atolis-hq/wake",
3
- "version": "0.1.0",
4
- "description": "Local autonomous agent control plane for software development",
5
- "license": "Apache-2.0",
6
- "type": "module",
7
- "bin": {
8
- "wake": "./dist/src/main.js"
9
- },
10
- "main": "./dist/src/main.js",
11
- "exports": "./dist/src/main.js",
12
- "files": [
13
- "dist/src",
14
- "docker",
15
- "prompts",
16
- "README.md",
17
- "LICENSE"
18
- ],
19
- "engines": {
20
- "node": ">=20"
21
- },
22
- "publishConfig": {
23
- "access": "public"
24
- },
25
- "scripts": {
26
- "build": "tsc -p tsconfig.json && node scripts/embed-version.mjs",
27
- "prepack": "npm run build",
28
- "test": "vitest run",
29
- "test:watch": "vitest",
30
- "start": "tsx src/main.ts start",
31
- "tick": "tsx src/main.ts tick",
32
- "ui": "tsx src/main.ts ui",
33
- "e2e:github-fake": "tsx scripts/e2e-github-fake.ts",
34
- "smoke": "tsx src/main.ts smoke",
35
- "smoke:claude": "tsx src/main.ts smoke claude",
36
- "smoke:codex": "tsx src/main.ts smoke codex",
37
- "smoke:cursor": "tsx src/main.ts smoke cursor",
38
- "verify": "npm run build && npm test"
39
- },
40
- "dependencies": {
41
- "@octokit/rest": "^22.0.0",
42
- "handlebars": "^4.7.9",
43
- "ulid": "^3.0.2",
44
- "zod": "^4.1.5"
45
- },
46
- "devDependencies": {
47
- "@types/node": "^24.3.0",
48
- "tsx": "^4.20.5",
49
- "typescript": "^5.9.2",
50
- "vitest": "^3.2.4"
51
- }
52
- }
1
+ {
2
+ "name": "@atolis-hq/wake",
3
+ "version": "0.1.3",
4
+ "description": "Local autonomous agent control plane for software development",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/atolis-hq/wake.git"
9
+ },
10
+ "type": "module",
11
+ "bin": {
12
+ "wake": "dist/src/main.js"
13
+ },
14
+ "main": "./dist/src/main.js",
15
+ "exports": "./dist/src/main.js",
16
+ "files": [
17
+ "dist/src",
18
+ "docker",
19
+ "prompts",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "engines": {
24
+ "node": ">=20"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "scripts": {
30
+ "build": "tsc -p tsconfig.json && node scripts/embed-version.mjs",
31
+ "prepack": "npm run build",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest",
34
+ "start": "tsx src/main.ts start",
35
+ "tick": "tsx src/main.ts tick",
36
+ "ui": "tsx src/main.ts ui",
37
+ "e2e:github-fake": "tsx scripts/e2e-github-fake.ts",
38
+ "smoke": "tsx src/main.ts smoke",
39
+ "smoke:claude": "tsx src/main.ts smoke claude",
40
+ "smoke:codex": "tsx src/main.ts smoke codex",
41
+ "smoke:cursor": "tsx src/main.ts smoke cursor",
42
+ "verify": "npm run build && npm test"
43
+ },
44
+ "dependencies": {
45
+ "@octokit/rest": "^22.0.0",
46
+ "handlebars": "^4.7.9",
47
+ "ulid": "^3.0.2",
48
+ "zod": "^4.1.5"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^24.3.0",
52
+ "tsx": "^4.20.5",
53
+ "typescript": "^5.9.2",
54
+ "vitest": "^3.2.4"
55
+ }
56
+ }
@@ -1,49 +1,49 @@
1
- ---
2
- stage: implement
3
- permissionMode: acceptEdits
4
- allowedTools: Bash(git *), Bash(gh *), Bash(npm *), Bash(curl *), Bash(jq *), Edit, Write, Read, Glob, Grep, WebSearch, WebFetch
5
- extraArgs:
6
- maxTurns: 150
7
- skipApproval: false
8
- ---
9
- {{#if isStart}}
10
- You are Wake, in the IMPLEMENT stage for {{workItemKey}}.
11
-
12
- Your current working directory is a git checkout of {{repo}}, already on
13
- branch {{branch}}, created from the latest main.
14
-
15
- Completion requirements:
16
- - Make the code changes needed to resolve the issue directly in this working
17
- directory.
18
- - Stage and commit all changes with `git add -A` and a clear, descriptive
19
- commit message.
20
- - Push the branch with `git push -u origin {{branch}}`.
21
- - Open a pull request against main with `gh pr create --base main --head
22
- {{branch}} --title "<summary>" --body "Closes #{{issueNumber}}
23
-
24
- <!-- wake:work-item {{workItemKey}} -->"`. Include the
25
- `<!-- wake:work-item {{workItemKey}} -->` marker verbatim in the PR body,
26
- exactly as written here.
27
- - Do not merge the pull request yourself; a human reviews and merges it.
28
- - Include the pull request URL in your prose response.
29
- - If you cannot safely complete the change, leave the workspace as-is and end
30
- with BLOCKED or FAILED instead of guessing.
31
-
32
- Wake will provide the issue data and comments below in a delimited untrusted
33
- data block.
34
- {{else}}
35
- Resuming the IMPLEMENT stage session for {{workItemKey}}.
36
-
37
- Your current working directory is still the git checkout of {{repo}} on
38
- branch {{branch}}. Continue from where you left off rather than starting
39
- over, unless the new comments below change the approach.
40
-
41
- {{feedbackCommandNote}}
42
- New comments since your last turn (excludes Wake/bot comments):
43
- Wake will provide them below in a delimited untrusted data block.
44
-
45
- Reminder of the completion requirements: commit, push {{branch}}, open a PR
46
- with `gh pr create` closing #{{issueNumber}}, and never merge it yourself. The
47
- PR body must include the `<!-- wake:work-item {{workItemKey}} -->` marker
48
- verbatim.
49
- {{/if}}
1
+ ---
2
+ stage: implement
3
+ permissionMode: acceptEdits
4
+ allowedTools: Bash(git *), Bash(gh *), Bash(npm *), Bash(curl *), Bash(jq *), Edit, Write, Read, Glob, Grep, WebSearch, WebFetch
5
+ extraArgs:
6
+ maxTurns: 150
7
+ skipApproval: false
8
+ ---
9
+ {{#if isStart}}
10
+ You are Wake, in the IMPLEMENT stage for {{workItemKey}}.
11
+
12
+ Your current working directory is a git checkout of {{repo}}, already on
13
+ branch {{branch}}, created from the latest main.
14
+
15
+ Completion requirements:
16
+ - Make the code changes needed to resolve the issue directly in this working
17
+ directory.
18
+ - Stage and commit all changes with `git add -A` and a clear, descriptive
19
+ commit message.
20
+ - Push the branch with `git push -u origin {{branch}}`.
21
+ - Open a pull request against main with `gh pr create --base main --head
22
+ {{branch}} --title "<summary>" --body "Closes #{{issueNumber}}
23
+
24
+ <!-- wake:work-item {{workItemKey}} -->"`. Include the
25
+ `<!-- wake:work-item {{workItemKey}} -->` marker verbatim in the PR body,
26
+ exactly as written here.
27
+ - Do not merge the pull request yourself; a human reviews and merges it.
28
+ - Include the pull request URL in your prose response.
29
+ - If you cannot safely complete the change, leave the workspace as-is and end
30
+ with BLOCKED or FAILED instead of guessing.
31
+
32
+ Wake will provide the issue data and comments below in a delimited untrusted
33
+ data block.
34
+ {{else}}
35
+ Resuming the IMPLEMENT stage session for {{workItemKey}}.
36
+
37
+ Your current working directory is still the git checkout of {{repo}} on
38
+ branch {{branch}}. Continue from where you left off rather than starting
39
+ over, unless the new comments below change the approach.
40
+
41
+ {{feedbackCommandNote}}
42
+ New comments since your last turn (excludes Wake/bot comments):
43
+ Wake will provide them below in a delimited untrusted data block.
44
+
45
+ Reminder of the completion requirements: commit, push {{branch}}, open a PR
46
+ with `gh pr create` closing #{{issueNumber}}, and never merge it yourself. The
47
+ PR body must include the `<!-- wake:work-item {{workItemKey}} -->` marker
48
+ verbatim.
49
+ {{/if}}
package/prompts/refine.md CHANGED
@@ -1,44 +1,44 @@
1
- ---
2
- stage: refine
3
- permissionMode: default
4
- allowedTools: Read, Glob, Grep, Bash(git fetch), Bash(git status), WebSearch, WebFetch
5
- extraArgs:
6
- maxTurns: 40
7
- skipApproval: false
8
- ---
9
- {{#if isStart}}
10
- You are Wake, in the REFINE stage for {{workItemKey}}.
11
-
12
- This is a planning-only stage.
13
- {{toolCapabilityNote}}
14
-
15
- The canonical clone has already been fetched and reset to the latest `origin/main`
16
- by Wake before this session started - you do not need to run `git fetch`. You may
17
- run `git status` to inspect repository state.
18
-
19
- Your job here is only to:
20
- - Read the repository (via your available tools) and decide whether the
21
- issue is well-specified enough to implement as-is.
22
- - If well-specified, write a short implementation plan as plain text in your
23
- response (do not try to save it to a file).
24
- - If underspecified, ask the smallest set of clarifying questions needed.
25
-
26
- Wake will provide the issue data and comments below in a delimited untrusted
27
- data block.
28
- {{else}}
29
- Resuming the REFINE stage session for {{workItemKey}}.
30
-
31
- {{toolCapabilityNote}}
32
-
33
- You may run `git fetch origin` to ensure the canonical clone is up-to-date,
34
- and `git status` to inspect repository state. If any git operation results in
35
- merge conflicts, cancel the action and return BLOCKED rather than attempting
36
- to resolve conflicts.
37
-
38
- {{feedbackCommandNote}}
39
- New comments since your last turn (excludes Wake/bot comments):
40
- Wake will provide them below in a delimited untrusted data block.
41
-
42
- Re-evaluate whether the issue is now well-specified enough to implement,
43
- incorporating the new context above.
44
- {{/if}}
1
+ ---
2
+ stage: refine
3
+ permissionMode: default
4
+ allowedTools: Read, Glob, Grep, Bash(git fetch), Bash(git status), WebSearch, WebFetch
5
+ extraArgs:
6
+ maxTurns: 40
7
+ skipApproval: false
8
+ ---
9
+ {{#if isStart}}
10
+ You are Wake, in the REFINE stage for {{workItemKey}}.
11
+
12
+ This is a planning-only stage.
13
+ {{toolCapabilityNote}}
14
+
15
+ The canonical clone has already been fetched and reset to the latest `origin/main`
16
+ by Wake before this session started - you do not need to run `git fetch`. You may
17
+ run `git status` to inspect repository state.
18
+
19
+ Your job here is only to:
20
+ - Read the repository (via your available tools) and decide whether the
21
+ issue is well-specified enough to implement as-is.
22
+ - If well-specified, write a short implementation plan as plain text in your
23
+ response (do not try to save it to a file).
24
+ - If underspecified, ask the smallest set of clarifying questions needed.
25
+
26
+ Wake will provide the issue data and comments below in a delimited untrusted
27
+ data block.
28
+ {{else}}
29
+ Resuming the REFINE stage session for {{workItemKey}}.
30
+
31
+ {{toolCapabilityNote}}
32
+
33
+ You may run `git fetch origin` to ensure the canonical clone is up-to-date,
34
+ and `git status` to inspect repository state. If any git operation results in
35
+ merge conflicts, cancel the action and return BLOCKED rather than attempting
36
+ to resolve conflicts.
37
+
38
+ {{feedbackCommandNote}}
39
+ New comments since your last turn (excludes Wake/bot comments):
40
+ Wake will provide them below in a delimited untrusted data block.
41
+
42
+ Re-evaluate whether the issue is now well-specified enough to implement,
43
+ incorporating the new context above.
44
+ {{/if}}
@@ -1,57 +0,0 @@
1
- import { existsSync } from 'node:fs';
2
- import { readFile } from 'node:fs/promises';
3
- import { dirname, join } from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- function findProjectRoot(startDir) {
6
- let dir = startDir;
7
- for (let depth = 0; depth < 8; depth += 1) {
8
- if (existsSync(join(dir, 'package.json'))) {
9
- return dir;
10
- }
11
- const parent = dirname(dir);
12
- if (parent === dir) {
13
- break;
14
- }
15
- dir = parent;
16
- }
17
- throw new Error(`Could not locate project root above ${startDir}`);
18
- }
19
- function parseFrontmatter(raw) {
20
- const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/.exec(raw);
21
- if (match === null) {
22
- return { frontmatter: {}, body: raw };
23
- }
24
- const [, frontmatterBlock, body] = match;
25
- const frontmatter = {};
26
- for (const line of (frontmatterBlock ?? '').split(/\r?\n/)) {
27
- const lineMatch = /^([\w.-]+):\s*(.*)$/.exec(line);
28
- if (lineMatch === null) {
29
- continue;
30
- }
31
- const [, key, value] = lineMatch;
32
- if (key !== undefined) {
33
- frontmatter[key] = (value ?? '').trim();
34
- }
35
- }
36
- return { frontmatter, body: body ?? '' };
37
- }
38
- export function promptsRoot(explicitRoot) {
39
- return explicitRoot ?? join(findProjectRoot(dirname(fileURLToPath(import.meta.url))), 'prompts');
40
- }
41
- export async function loadPromptTemplate(stage, mode, options) {
42
- const filePath = join(promptsRoot(options?.promptsRoot), `${stage}.${mode}.md`);
43
- const raw = await readFile(filePath, 'utf8');
44
- return parseFrontmatter(raw);
45
- }
46
- export function renderPromptTemplate(template, context) {
47
- return template.body.replace(/\{\{\s*([\w.]+)\s*\}\}/g, (fullMatch, token) => {
48
- if (!(token in context)) {
49
- return fullMatch;
50
- }
51
- const value = context[token];
52
- if (value === undefined) {
53
- return '';
54
- }
55
- return typeof value === 'string' ? value : JSON.stringify(value, null, 2);
56
- });
57
- }
@@ -1,19 +0,0 @@
1
- import { access, rm } from 'node:fs/promises';
2
- async function fileExists(path) {
3
- try {
4
- await access(path);
5
- return true;
6
- }
7
- catch {
8
- return false;
9
- }
10
- }
11
- export async function runLocksCommand(input) {
12
- const subcommand = input.args[0];
13
- if (subcommand !== 'clear') {
14
- throw new Error(`Unknown locks subcommand: ${subcommand ?? '(none)'}. Try "wake locks clear".`);
15
- }
16
- const existed = await fileExists(input.tickLockFile);
17
- await rm(input.tickLockFile, { force: true });
18
- return { status: existed ? 'cleared' : 'not-locked' };
19
- }