@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/LICENSE +201 -201
- package/README.md +140 -140
- package/dist/src/adapters/http/ui-assets.js +300 -300
- package/dist/src/version.js +1 -1
- package/docker/Dockerfile +54 -54
- package/docker/setup.sh +0 -0
- package/package.json +56 -52
- package/prompts/implement.md +49 -49
- package/prompts/refine.md +44 -44
- package/dist/src/adapters/claude/prompt-templates.js +0 -57
- package/dist/src/cli/locks-command.js +0 -19
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.
|
|
4
|
-
"description": "Local autonomous agent control plane for software development",
|
|
5
|
-
"license": "Apache-2.0",
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
},
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
|
|
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
|
+
}
|
package/prompts/implement.md
CHANGED
|
@@ -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
|
-
}
|