ace-pack 0.1.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 +21 -0
- package/README.md +242 -0
- package/ace-pack.cmd +2 -0
- package/agent-memory-pack.cmd +2 -0
- package/install-ace-pack.cmd +2 -0
- package/install-ace-pack.mjs +261 -0
- package/install-agent-memory-pack.cmd +2 -0
- package/install-agent-memory-pack.mjs +17 -0
- package/logo.svg +25 -0
- package/package.json +49 -0
- package/scripts/ace-hub.mjs +137 -0
- package/scripts/ace-onboard.mjs +503 -0
- package/scripts/ace-project-presets.mjs +158 -0
- package/scripts/ace-universal-doc-templates.mjs +40 -0
- package/scripts/agent-memory-lib.mjs +141 -0
- package/scripts/agent-memory-templates.mjs +350 -0
- package/scripts/ai-memory-config.mjs +171 -0
- package/scripts/ai-memory-utils.mjs +372 -0
- package/scripts/ai-report-brief.mjs +131 -0
- package/scripts/ai-report-current-task-code.mjs +128 -0
- package/scripts/ai-report.mjs +185 -0
- package/scripts/ai-task-classify.mjs +236 -0
- package/scripts/ai-task-finish.mjs +206 -0
- package/scripts/ai-update.mjs +236 -0
- package/scripts/bootstrap-agent-memory.mjs +23 -0
- package/scripts/check-agent-memory.mjs +22 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alexandr Dudka
|
|
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/README.md
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="./logo.svg" alt="ACE Pack logo" width="72" height="72" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">ACE Pack</h1>
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/ace-pack)
|
|
8
|
+
[](#)
|
|
9
|
+
[](#)
|
|
10
|
+
|
|
11
|
+
**The zero-dependency cognitive architecture framework for AI-driven development.**
|
|
12
|
+
|
|
13
|
+
ACE (Agentic Context Engine) gives AI coding agents a deterministic memory
|
|
14
|
+
layer, repository-aware risk rules, and repeatable quality gates using plain
|
|
15
|
+
Markdown and native Node.js scripts.
|
|
16
|
+
|
|
17
|
+
AI agents are brilliant, but stateless by default. ACE gives them the project
|
|
18
|
+
memory, guardrails, and closeout discipline they need to behave like reliable
|
|
19
|
+
engineering teammates inside real repositories.
|
|
20
|
+
|
|
21
|
+
## Why ACE Exists
|
|
22
|
+
|
|
23
|
+
AI-assisted development has a new set of failure modes that ordinary chat does
|
|
24
|
+
not solve:
|
|
25
|
+
|
|
26
|
+
- **Context Amnesia** - the agent forgets last week's architecture decisions
|
|
27
|
+
and suggests reworking settled systems.
|
|
28
|
+
- **Architectural Drift** - the agent invents new patterns, libraries, or
|
|
29
|
+
boundaries because the project rules are not loaded every time.
|
|
30
|
+
- **Security Blind Spots** - auth, tokens, private data, migrations, and
|
|
31
|
+
environment isolation look like ordinary code unless they are marked as
|
|
32
|
+
high-risk.
|
|
33
|
+
- **Prompt Fatigue** - humans waste time collecting files, repeating rules, and
|
|
34
|
+
reminding the agent to validate, document, and hand off its work.
|
|
35
|
+
|
|
36
|
+
ACE turns those soft expectations into local project structure:
|
|
37
|
+
|
|
38
|
+
- `.ai/*` Markdown files keep task state, decisions, handoffs, and reflection
|
|
39
|
+
readable by any LLM.
|
|
40
|
+
- `AGENTS.md` keeps stack, architecture, and workflow rules close to the code.
|
|
41
|
+
- `.ai/memory-config.json` marks high-risk paths and keywords for the current
|
|
42
|
+
repository.
|
|
43
|
+
- `ace:validate` stays project-owned so every repo can define its real
|
|
44
|
+
mechanical quality gate.
|
|
45
|
+
|
|
46
|
+
## ACE vs. Just Chatting With AI
|
|
47
|
+
|
|
48
|
+
A chat session is a smart one-off conversation. ACE is a governed agent
|
|
49
|
+
workflow.
|
|
50
|
+
|
|
51
|
+
With ordinary chat, the developer carries the discipline: gather context, repeat
|
|
52
|
+
rules, ask for alternatives, remember security constraints, run checks, and
|
|
53
|
+
write handoff notes.
|
|
54
|
+
|
|
55
|
+
With ACE, the repository carries the discipline:
|
|
56
|
+
|
|
57
|
+
- `ace:classify` detects whether the change is small, standard, or large.
|
|
58
|
+
- Large and high-risk work starts with a shift-left design review before code.
|
|
59
|
+
- `ace:hub` generates focused context instead of manual copy/paste bundles.
|
|
60
|
+
- `ace:finish` commits decisions, changed files, validation notes, and
|
|
61
|
+
reflection back into project memory.
|
|
62
|
+
|
|
63
|
+
ACE is not a prompt library. It is cognitive architecture for managing AI
|
|
64
|
+
coding agents inside real repositories.
|
|
65
|
+
|
|
66
|
+
## What ACE Boosts
|
|
67
|
+
|
|
68
|
+
**For the AI agent**
|
|
69
|
+
|
|
70
|
+
- Context packing that points the model at the right files first.
|
|
71
|
+
- Strict guardrails for high-risk code paths and keywords.
|
|
72
|
+
- Stateful reflection so repeated mistakes become visible project memory.
|
|
73
|
+
- A universal Markdown format readable by GPT, Claude, Cursor, Aider, and other
|
|
74
|
+
coding agents.
|
|
75
|
+
|
|
76
|
+
**For the human developer**
|
|
77
|
+
|
|
78
|
+
- Automated review prompts and closeout discipline.
|
|
79
|
+
- Self-documenting architecture and decision history.
|
|
80
|
+
- Zero framework lock-in and no runtime dependencies.
|
|
81
|
+
- Less boilerplate in every agent session.
|
|
82
|
+
|
|
83
|
+
## How It Works
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
Classify Risk -> Shift-Left Design Review -> Write Code -> Validate -> Commit to Memory
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
ACE is intentionally boring technology: standard Markdown in `.ai/`, standard
|
|
90
|
+
`package.json` scripts, and native Node.js.
|
|
91
|
+
|
|
92
|
+
The key behavior is **Shift-Left Design Review**. For large or high-risk tasks,
|
|
93
|
+
the agent must stop before implementation, fill `.ai/current-task.md` with the
|
|
94
|
+
business value and technical approach, compare viable patterns, and choose one
|
|
95
|
+
explicitly. The code comes after the architectural decision, not before it.
|
|
96
|
+
|
|
97
|
+
Unknown repositories start with a neutral memory config. Then `ace:onboard`
|
|
98
|
+
profiles the repo and recommends project-specific risk rules before they are
|
|
99
|
+
applied.
|
|
100
|
+
|
|
101
|
+
## Quick Start
|
|
102
|
+
|
|
103
|
+
Install ACE into the current repository:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pnpm dlx ace-pack init
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Or with npm:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npx ace-pack init
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Install into another repository:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pnpm dlx ace-pack init ./my-project
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Profile the project:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
pnpm ace:onboard
|
|
125
|
+
pnpm ace:onboard -- --apply
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
For Python, Go, Rust, .NET, or any repo without `package.json`, ACE creates a
|
|
129
|
+
lightweight private runner package:
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"description": "Auto-generated lightweight runner for ACE (Agentic Context Engine) scripts. No node_modules required."
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
No dependency install is required for ACE itself. The runner only exposes
|
|
138
|
+
commands such as `ace:onboard`, `ace:hub`, `ace:classify`, and `ace:finish`.
|
|
139
|
+
|
|
140
|
+
Known SaaS monorepo? Apply the built-in preset:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pnpm ace:onboard -- --preset next-trpc-drizzle-saas --apply
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Legacy entry points remain available:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
pnpm dlx agent-memory-pack ./my-project
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Multi-Language Examples
|
|
153
|
+
|
|
154
|
+
### Next.js + tRPC + Drizzle
|
|
155
|
+
|
|
156
|
+
ACE detects signals such as `next.config.ts`, `@trpc/server`, `drizzle-orm`,
|
|
157
|
+
`middleware.ts`, `packages/api/src/routers/**`, and
|
|
158
|
+
`packages/db/src/schema/**`. These become high-risk rules so auth, middleware,
|
|
159
|
+
routers, and migrations get stricter review before code changes.
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
pnpm ace:onboard -- --preset next-trpc-drizzle-saas --apply
|
|
163
|
+
pnpm ace:classify
|
|
164
|
+
pnpm ace:validate
|
|
165
|
+
pnpm ace:finish
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Python FastAPI
|
|
169
|
+
|
|
170
|
+
ACE detects `requirements.txt`, `pyproject.toml`, `fastapi`,
|
|
171
|
+
`app/core/security.py`, `app/**/auth*.py`, `app/api/**`, and `alembic/**`. The
|
|
172
|
+
active project can keep using Poetry, uv, pytest, ruff, or any other Python
|
|
173
|
+
tooling; ACE only provides the agent memory and workflow layer.
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
pnpm dlx ace-pack init
|
|
177
|
+
pnpm ace:onboard -- --apply
|
|
178
|
+
pnpm ace:hub
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Go Microservice
|
|
182
|
+
|
|
183
|
+
ACE detects `go.mod`, `internal/auth/**`, `internal/middleware/**`,
|
|
184
|
+
`internal/handlers/**`, and `migrations/**`. It gives AI agents the same memory
|
|
185
|
+
and risk workflow without changing the Go build pipeline.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
pnpm dlx ace-pack init
|
|
189
|
+
pnpm ace:onboard -- --apply
|
|
190
|
+
pnpm ace:classify
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## CLI Reference
|
|
194
|
+
|
|
195
|
+
| Command | Purpose |
|
|
196
|
+
| --- | --- |
|
|
197
|
+
| `ace:onboard` | Smart repository profiling. Writes `.ai/project-profile.md` and `.ai/memory-config.recommended.json` without changing active config. |
|
|
198
|
+
| `ace:onboard -- --apply` | Merges recommendations into `.ai/memory-config.json` and marks the repo as profiled. |
|
|
199
|
+
| `ace:onboard -- --preset next-trpc-drizzle-saas --apply` | Applies the built-in Next.js + tRPC + Drizzle SaaS profile. |
|
|
200
|
+
| `ace:onboard -- --check` | Fails if the repository is still unprofiled. |
|
|
201
|
+
| `ace:classify` | Git diff risk analysis for small, standard, and large tasks. |
|
|
202
|
+
| `ace:validate` | Project-owned mechanical quality gate. ACE never overwrites this script. |
|
|
203
|
+
| `ace:finish` | Adaptive closeout, memory documentation, reports, and reflection. |
|
|
204
|
+
| `ace:hub` | Interactive context generator for copying focused project context into AI tools. |
|
|
205
|
+
|
|
206
|
+
## Installed Project Files
|
|
207
|
+
|
|
208
|
+
ACE installs or updates:
|
|
209
|
+
|
|
210
|
+
- `AGENTS.md` workflow section
|
|
211
|
+
- `CLAUDE.md`
|
|
212
|
+
- `.ai/current-task.md`
|
|
213
|
+
- `.ai/session-handoff.md`
|
|
214
|
+
- `.ai/decisions.md`
|
|
215
|
+
- `.ai/changed-files.md`
|
|
216
|
+
- `.ai/work-log.md`
|
|
217
|
+
- `.ai/reflection-log.md`
|
|
218
|
+
- `.ai/product-roadmap.md`
|
|
219
|
+
- `.ai/tech-docs.md`
|
|
220
|
+
- `.ai/memory-config.json`
|
|
221
|
+
- `.ai/archive/.gitkeep`
|
|
222
|
+
- `.ai/archive/tasks/.gitkeep`
|
|
223
|
+
- `scripts/*` managed ACE automation
|
|
224
|
+
|
|
225
|
+
Existing memory files are not overwritten. Existing `package.json` files are
|
|
226
|
+
preserved and updated idempotently.
|
|
227
|
+
|
|
228
|
+
## Development
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
git clone https://github.com/alex-boom/ace-pack.git
|
|
232
|
+
cd ace-pack
|
|
233
|
+
pnpm install
|
|
234
|
+
pnpm test
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Optional local link:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
pnpm link --global
|
|
241
|
+
ace-pack init ./target-project
|
|
242
|
+
```
|
package/ace-pack.cmd
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
|
|
6
|
+
import { ensureAgentMemory } from './scripts/agent-memory-lib.mjs'
|
|
7
|
+
|
|
8
|
+
const REQUIRED_PACKAGE_SCRIPTS = {
|
|
9
|
+
'ace:init': 'node ./scripts/bootstrap-agent-memory.mjs',
|
|
10
|
+
'ace:check': 'node ./scripts/check-agent-memory.mjs',
|
|
11
|
+
'ace:classify': 'node ./scripts/ai-task-classify.mjs',
|
|
12
|
+
'ace:finish': 'node ./scripts/ai-task-finish.mjs',
|
|
13
|
+
'ace:hub': 'node ./scripts/ace-hub.mjs',
|
|
14
|
+
'ace:onboard': 'node ./scripts/ace-onboard.mjs',
|
|
15
|
+
'ace:report': 'node ./scripts/ai-report.mjs',
|
|
16
|
+
'ace:report:brief': 'node ./scripts/ai-report-brief.mjs',
|
|
17
|
+
'agent-memory:init': 'node ./scripts/bootstrap-agent-memory.mjs',
|
|
18
|
+
'agent-memory:check': 'node ./scripts/check-agent-memory.mjs',
|
|
19
|
+
'ai:project:onboard': 'node ./scripts/ace-onboard.mjs',
|
|
20
|
+
'ai:report': 'node ./scripts/ai-report.mjs',
|
|
21
|
+
'ai:report:brief': 'node ./scripts/ai-report-brief.mjs',
|
|
22
|
+
'ai:report:currentTaskCode': 'node ./scripts/ai-report-current-task-code.mjs',
|
|
23
|
+
'ai:task:classify': 'node ./scripts/ai-task-classify.mjs',
|
|
24
|
+
'ai:task:finish': 'node ./scripts/ai-task-finish.mjs',
|
|
25
|
+
'ai:update:task': 'node ./scripts/ai-update.mjs task',
|
|
26
|
+
'ai:update:handoff': 'node ./scripts/ai-update.mjs handoff',
|
|
27
|
+
'ai:update:log': 'node ./scripts/ai-update.mjs log',
|
|
28
|
+
'ai:update:decision': 'node ./scripts/ai-update.mjs decision',
|
|
29
|
+
'ai:update:changed': 'node ./scripts/ai-update.mjs changed',
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const MANAGED_SCRIPT_FILES = [
|
|
33
|
+
'ace-hub.mjs',
|
|
34
|
+
'ace-onboard.mjs',
|
|
35
|
+
'ace-project-presets.mjs',
|
|
36
|
+
'ace-universal-doc-templates.mjs',
|
|
37
|
+
'agent-memory-lib.mjs',
|
|
38
|
+
'agent-memory-templates.mjs',
|
|
39
|
+
'ai-memory-config.mjs',
|
|
40
|
+
'ai-memory-utils.mjs',
|
|
41
|
+
'ai-report-brief.mjs',
|
|
42
|
+
'ai-report-current-task-code.mjs',
|
|
43
|
+
'ai-report.mjs',
|
|
44
|
+
'ai-task-classify.mjs',
|
|
45
|
+
'ai-task-finish.mjs',
|
|
46
|
+
'ai-update.mjs',
|
|
47
|
+
'bootstrap-agent-memory.mjs',
|
|
48
|
+
'check-agent-memory.mjs',
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
const defaultAgentsTemplate = `# AGENTS.md
|
|
52
|
+
|
|
53
|
+
Repository rules for AI coding agents working in this project.
|
|
54
|
+
|
|
55
|
+
## Project Rules
|
|
56
|
+
|
|
57
|
+
- Add project-specific stack, architecture, and workflow rules here.
|
|
58
|
+
`
|
|
59
|
+
|
|
60
|
+
const currentFilePath = fileURLToPath(import.meta.url)
|
|
61
|
+
const currentScriptDir = path.join(path.dirname(currentFilePath), 'scripts')
|
|
62
|
+
const RUNNER_PACKAGE_DESCRIPTION =
|
|
63
|
+
'Auto-generated lightweight runner for ACE (Agentic Context Engine) scripts. No node_modules required.'
|
|
64
|
+
|
|
65
|
+
function normalizeTrailingNewline(content) {
|
|
66
|
+
return content.endsWith('\n') ? content : `${content}\n`
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function readTextIfExists(filePath) {
|
|
70
|
+
try {
|
|
71
|
+
return await readFile(filePath, 'utf8')
|
|
72
|
+
} catch (error) {
|
|
73
|
+
if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {
|
|
74
|
+
return null
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
throw error
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function ensureDefaultAgentsFile(rootDir) {
|
|
82
|
+
const agentsPath = path.join(rootDir, 'AGENTS.md')
|
|
83
|
+
const existingContent = await readTextIfExists(agentsPath)
|
|
84
|
+
|
|
85
|
+
if (existingContent !== null) {
|
|
86
|
+
return { created: false, path: 'AGENTS.md' }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
await writeFile(agentsPath, normalizeTrailingNewline(defaultAgentsTemplate), 'utf8')
|
|
90
|
+
return { created: true, path: 'AGENTS.md' }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function syncManagedScripts(rootDir) {
|
|
94
|
+
const createdFiles = []
|
|
95
|
+
const updatedFiles = []
|
|
96
|
+
const targetScriptDir = path.join(rootDir, 'scripts')
|
|
97
|
+
|
|
98
|
+
await mkdir(targetScriptDir, { recursive: true })
|
|
99
|
+
|
|
100
|
+
for (const filename of MANAGED_SCRIPT_FILES) {
|
|
101
|
+
const sourcePath = path.join(currentScriptDir, filename)
|
|
102
|
+
const targetPath = path.join(targetScriptDir, filename)
|
|
103
|
+
const sourceContent = await readFile(sourcePath, 'utf8')
|
|
104
|
+
const targetContent = await readTextIfExists(targetPath)
|
|
105
|
+
|
|
106
|
+
if (targetContent === sourceContent) {
|
|
107
|
+
continue
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
await copyFile(sourcePath, targetPath)
|
|
111
|
+
|
|
112
|
+
if (targetContent === null) {
|
|
113
|
+
createdFiles.push(`scripts/${filename}`)
|
|
114
|
+
} else {
|
|
115
|
+
updatedFiles.push(`scripts/${filename}`)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return { createdFiles, updatedFiles }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function ensurePackageScripts(rootDir) {
|
|
123
|
+
const { packageJson, packageJsonPath } = await ensurePackageJson(rootDir)
|
|
124
|
+
const nextScripts = {
|
|
125
|
+
...(packageJson.scripts ?? {}),
|
|
126
|
+
}
|
|
127
|
+
let changed = false
|
|
128
|
+
|
|
129
|
+
for (const [scriptName, scriptValue] of Object.entries(REQUIRED_PACKAGE_SCRIPTS)) {
|
|
130
|
+
if (nextScripts[scriptName] === scriptValue) {
|
|
131
|
+
continue
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
nextScripts[scriptName] = scriptValue
|
|
135
|
+
changed = true
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!changed) {
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
await writeFile(
|
|
143
|
+
packageJsonPath,
|
|
144
|
+
`${JSON.stringify({ ...packageJson, scripts: nextScripts }, null, 2)}\n`,
|
|
145
|
+
'utf8',
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
return true
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function buildPackageName(rootDir) {
|
|
152
|
+
const folderName = path.basename(rootDir).toLowerCase()
|
|
153
|
+
const packageName = folderName
|
|
154
|
+
.replace(/[^a-z0-9._-]+/g, '-')
|
|
155
|
+
.replace(/^[._-]+|[._-]+$/g, '')
|
|
156
|
+
|
|
157
|
+
return packageName || 'ace-project'
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function ensurePackageJson(rootDir) {
|
|
161
|
+
const packageJsonPath = path.join(rootDir, 'package.json')
|
|
162
|
+
const packageJsonContent = await readTextIfExists(packageJsonPath)
|
|
163
|
+
|
|
164
|
+
if (packageJsonContent !== null) {
|
|
165
|
+
return {
|
|
166
|
+
created: false,
|
|
167
|
+
packageJson: JSON.parse(stripByteOrderMark(packageJsonContent)),
|
|
168
|
+
packageJsonPath,
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const packageJson = {
|
|
173
|
+
name: buildPackageName(rootDir),
|
|
174
|
+
private: true,
|
|
175
|
+
description: RUNNER_PACKAGE_DESCRIPTION,
|
|
176
|
+
scripts: {},
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
await writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, 'utf8')
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
created: true,
|
|
183
|
+
packageJson,
|
|
184
|
+
packageJsonPath,
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function stripByteOrderMark(content) {
|
|
189
|
+
return content.replace(/^\uFEFF/u, '')
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export async function installAcePack(targetDir) {
|
|
193
|
+
const normalizedTargetDir = path.resolve(targetDir)
|
|
194
|
+
const createdFiles = []
|
|
195
|
+
const updatedFiles = []
|
|
196
|
+
|
|
197
|
+
const packageResult = await ensurePackageJson(normalizedTargetDir)
|
|
198
|
+
|
|
199
|
+
if (packageResult.created) {
|
|
200
|
+
createdFiles.push('package.json')
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const agentsResult = await ensureDefaultAgentsFile(normalizedTargetDir)
|
|
204
|
+
|
|
205
|
+
if (agentsResult.created) {
|
|
206
|
+
createdFiles.push(agentsResult.path)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const scriptResult = await syncManagedScripts(normalizedTargetDir)
|
|
210
|
+
createdFiles.push(...scriptResult.createdFiles)
|
|
211
|
+
updatedFiles.push(...scriptResult.updatedFiles)
|
|
212
|
+
|
|
213
|
+
if (await ensurePackageScripts(normalizedTargetDir)) {
|
|
214
|
+
updatedFiles.push('package.json')
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const memoryResult = await ensureAgentMemory(normalizedTargetDir)
|
|
218
|
+
createdFiles.push(...memoryResult.createdFiles)
|
|
219
|
+
updatedFiles.push(...memoryResult.updatedFiles)
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
createdFiles,
|
|
223
|
+
targetDir: normalizedTargetDir,
|
|
224
|
+
updatedFiles,
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export function resolveTargetDir(args, cwd = process.cwd()) {
|
|
229
|
+
const [commandOrTarget, maybeTarget] = args
|
|
230
|
+
|
|
231
|
+
if (commandOrTarget === 'init') {
|
|
232
|
+
return maybeTarget ? path.resolve(cwd, maybeTarget) : cwd
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return commandOrTarget ? path.resolve(cwd, commandOrTarget) : cwd
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function printInstallResult(result) {
|
|
239
|
+
if (result.updatedFiles.length === 0 && result.createdFiles.length === 0) {
|
|
240
|
+
process.stderr.write(`ACE pack is already up to date in ${result.targetDir}\n`)
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (result.updatedFiles.length > 0) {
|
|
244
|
+
process.stderr.write(`Updated: ${result.updatedFiles.join(', ')}\n`)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (result.createdFiles.length > 0) {
|
|
248
|
+
process.stderr.write(`Created: ${result.createdFiles.join(', ')}\n`)
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
process.stderr.write('Next: run pnpm.cmd ace:onboard\n')
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const isMainModule =
|
|
255
|
+
process.argv[1] !== undefined && path.resolve(process.argv[1]) === currentFilePath
|
|
256
|
+
|
|
257
|
+
if (isMainModule) {
|
|
258
|
+
const targetDir = resolveTargetDir(process.argv.slice(2))
|
|
259
|
+
const result = await installAcePack(targetDir)
|
|
260
|
+
printInstallResult(result)
|
|
261
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
|
|
5
|
+
import { installAcePack, printInstallResult, resolveTargetDir } from './install-ace-pack.mjs'
|
|
6
|
+
|
|
7
|
+
export const installAgentMemoryPack = installAcePack
|
|
8
|
+
|
|
9
|
+
const currentFilePath = fileURLToPath(import.meta.url)
|
|
10
|
+
const isMainModule =
|
|
11
|
+
process.argv[1] !== undefined && path.resolve(process.argv[1]) === currentFilePath
|
|
12
|
+
|
|
13
|
+
if (isMainModule) {
|
|
14
|
+
const targetDir = resolveTargetDir(process.argv.slice(2))
|
|
15
|
+
const result = await installAcePack(targetDir)
|
|
16
|
+
printInstallResult(result)
|
|
17
|
+
}
|
package/logo.svg
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-labelledby="ace-pack-logo-title">
|
|
2
|
+
<title id="ace-pack-logo-title">ACE Pack</title>
|
|
3
|
+
<style>
|
|
4
|
+
.icon-dark-part {
|
|
5
|
+
fill: #0f172a;
|
|
6
|
+
}
|
|
7
|
+
.icon-pink-part {
|
|
8
|
+
fill: #db2777;
|
|
9
|
+
}
|
|
10
|
+
@media (prefers-color-scheme: dark) {
|
|
11
|
+
.icon-dark-part {
|
|
12
|
+
fill: #f8fafc;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
</style>
|
|
16
|
+
<rect class="icon-dark-part" x="15.2" y="7.3" width="1.6" height="5.3" rx="0.8" />
|
|
17
|
+
<rect class="icon-dark-part" x="15.2" y="19.4" width="1.6" height="5.3" rx="0.8" />
|
|
18
|
+
<rect class="icon-dark-part" x="7.3" y="15.2" width="5.3" height="1.6" rx="0.8" />
|
|
19
|
+
<rect class="icon-dark-part" x="19.4" y="15.2" width="5.3" height="1.6" rx="0.8" />
|
|
20
|
+
<rect class="icon-dark-part" x="12.4" y="1.6" width="7.2" height="7.2" rx="1.6" />
|
|
21
|
+
<rect class="icon-dark-part" x="12.4" y="23.2" width="7.2" height="7.2" rx="1.6" />
|
|
22
|
+
<rect class="icon-dark-part" x="1.6" y="12.4" width="7.2" height="7.2" rx="1.6" />
|
|
23
|
+
<rect class="icon-dark-part" x="23.2" y="12.4" width="7.2" height="7.2" rx="1.6" />
|
|
24
|
+
<circle class="icon-pink-part" cx="16" cy="16" r="4.45" />
|
|
25
|
+
</svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ace-pack",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Zero-dependency cognitive architecture framework for AI-driven development.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Alexandr Dudka <dudka.alexandr83@gmail.com>",
|
|
8
|
+
"homepage": "https://github.com/alex-boom/ace-pack#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/alex-boom/ace-pack.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/alex-boom/ace-pack/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"ai",
|
|
18
|
+
"agent",
|
|
19
|
+
"memory",
|
|
20
|
+
"llm",
|
|
21
|
+
"codex",
|
|
22
|
+
"agentic",
|
|
23
|
+
"workflow",
|
|
24
|
+
"development"
|
|
25
|
+
],
|
|
26
|
+
"files": [
|
|
27
|
+
"README.md",
|
|
28
|
+
"logo.svg",
|
|
29
|
+
"*.cmd",
|
|
30
|
+
"*.mjs",
|
|
31
|
+
"scripts/*.mjs"
|
|
32
|
+
],
|
|
33
|
+
"bin": {
|
|
34
|
+
"ace-pack": "install-ace-pack.mjs",
|
|
35
|
+
"agent-memory-pack": "install-agent-memory-pack.mjs"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"install:pack": "node ./install-ace-pack.mjs",
|
|
39
|
+
"install:legacy": "node ./install-agent-memory-pack.mjs",
|
|
40
|
+
"link:global": "pnpm link --global",
|
|
41
|
+
"test": "vitest run"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"vitest": "^4.1.4"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=20"
|
|
48
|
+
}
|
|
49
|
+
}
|