ace-pack 0.1.0 → 0.1.2
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/README.md +49 -14
- package/install-ace-pack.mjs +265 -11
- package/install-agent-memory-pack.mjs +8 -4
- package/package.json +2 -1
- package/scripts/agent-memory-templates.mjs +7 -0
package/README.md
CHANGED
|
@@ -40,8 +40,8 @@ ACE turns those soft expectations into local project structure:
|
|
|
40
40
|
- `AGENTS.md` keeps stack, architecture, and workflow rules close to the code.
|
|
41
41
|
- `.ai/memory-config.json` marks high-risk paths and keywords for the current
|
|
42
42
|
repository.
|
|
43
|
-
- `ace:validate`
|
|
44
|
-
mechanical quality gate.
|
|
43
|
+
- `ace:validate` starts as an ACE memory check and can be replaced by each
|
|
44
|
+
repo with its real mechanical quality gate.
|
|
45
45
|
|
|
46
46
|
## ACE vs. Just Chatting With AI
|
|
47
47
|
|
|
@@ -100,33 +100,62 @@ applied.
|
|
|
100
100
|
|
|
101
101
|
## Quick Start
|
|
102
102
|
|
|
103
|
-
Install ACE into the current repository
|
|
103
|
+
Install ACE into the current repository. Use `init`; do not use
|
|
104
|
+
`npm install ace-pack` for project setup.
|
|
104
105
|
|
|
105
106
|
```bash
|
|
106
|
-
|
|
107
|
+
npx ace-pack@latest init
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Then profile the project:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npm run ace:onboard -- --apply
|
|
114
|
+
npm run ace:check
|
|
107
115
|
```
|
|
108
116
|
|
|
109
|
-
|
|
117
|
+
Prefer pnpm? Use the same flow through `pnpm dlx`:
|
|
110
118
|
|
|
111
119
|
```bash
|
|
112
|
-
|
|
120
|
+
pnpm dlx ace-pack init
|
|
121
|
+
pnpm ace:onboard -- --apply
|
|
122
|
+
pnpm ace:check
|
|
113
123
|
```
|
|
114
124
|
|
|
115
125
|
Install into another repository:
|
|
116
126
|
|
|
117
127
|
```bash
|
|
118
|
-
|
|
128
|
+
npx ace-pack@latest init ./my-project
|
|
119
129
|
```
|
|
120
130
|
|
|
121
|
-
|
|
131
|
+
Install and apply onboarding in one command:
|
|
122
132
|
|
|
123
133
|
```bash
|
|
124
|
-
|
|
125
|
-
pnpm ace:onboard -- --apply
|
|
134
|
+
npx ace-pack@latest init --apply
|
|
126
135
|
```
|
|
127
136
|
|
|
137
|
+
Need help?
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npx ace-pack@latest --help
|
|
141
|
+
npx ace-pack@latest init --help
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## What Init Does
|
|
145
|
+
|
|
146
|
+
`ace-pack init` adds or updates local project files:
|
|
147
|
+
|
|
148
|
+
- `AGENTS.md` and `CLAUDE.md`
|
|
149
|
+
- `.ai/*` memory, task, handoff, decisions, and profile files
|
|
150
|
+
- `scripts/*` ACE automation copied into the project
|
|
151
|
+
- `package.json` commands such as `ace:onboard`, `ace:classify`,
|
|
152
|
+
`ace:validate`, `ace:finish`, and `ace:hub`
|
|
153
|
+
|
|
154
|
+
ACE does not need to remain installed as a runtime dependency. The npm package
|
|
155
|
+
acts as a scaffold CLI, then the project owns the copied scripts.
|
|
156
|
+
|
|
128
157
|
For Python, Go, Rust, .NET, or any repo without `package.json`, ACE creates a
|
|
129
|
-
lightweight private runner package:
|
|
158
|
+
lightweight private runner package so the same commands are available:
|
|
130
159
|
|
|
131
160
|
```json
|
|
132
161
|
{
|
|
@@ -134,8 +163,14 @@ lightweight private runner package:
|
|
|
134
163
|
}
|
|
135
164
|
```
|
|
136
165
|
|
|
137
|
-
|
|
138
|
-
|
|
166
|
+
On Windows PowerShell, use `pnpm.cmd` if script execution policy blocks the
|
|
167
|
+
regular `pnpm` shim:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
pnpm.cmd dlx ace-pack init
|
|
171
|
+
pnpm.cmd ace:onboard -- --apply
|
|
172
|
+
pnpm.cmd ace:check
|
|
173
|
+
```
|
|
139
174
|
|
|
140
175
|
Known SaaS monorepo? Apply the built-in preset:
|
|
141
176
|
|
|
@@ -199,7 +234,7 @@ pnpm ace:classify
|
|
|
199
234
|
| `ace:onboard -- --preset next-trpc-drizzle-saas --apply` | Applies the built-in Next.js + tRPC + Drizzle SaaS profile. |
|
|
200
235
|
| `ace:onboard -- --check` | Fails if the repository is still unprofiled. |
|
|
201
236
|
| `ace:classify` | Git diff risk analysis for small, standard, and large tasks. |
|
|
202
|
-
| `ace:validate` |
|
|
237
|
+
| `ace:validate` | Default mechanical quality gate alias for `ace:check`. Projects may replace it with a stricter local gate. |
|
|
203
238
|
| `ace:finish` | Adaptive closeout, memory documentation, reports, and reflection. |
|
|
204
239
|
| `ace:hub` | Interactive context generator for copying focused project context into AI tools. |
|
|
205
240
|
|
package/install-ace-pack.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
2
|
+
import { access, copyFile, mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
3
3
|
import path from 'node:path'
|
|
4
4
|
import { fileURLToPath } from 'node:url'
|
|
5
5
|
|
|
6
|
+
import { onboardRepository } from './scripts/ace-onboard.mjs'
|
|
6
7
|
import { ensureAgentMemory } from './scripts/agent-memory-lib.mjs'
|
|
7
8
|
|
|
8
9
|
const REQUIRED_PACKAGE_SCRIPTS = {
|
|
@@ -29,6 +30,10 @@ const REQUIRED_PACKAGE_SCRIPTS = {
|
|
|
29
30
|
'ai:update:changed': 'node ./scripts/ai-update.mjs changed',
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
const DEFAULT_PACKAGE_SCRIPTS = {
|
|
34
|
+
'ace:validate': 'node ./scripts/check-agent-memory.mjs',
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
const MANAGED_SCRIPT_FILES = [
|
|
33
38
|
'ace-hub.mjs',
|
|
34
39
|
'ace-onboard.mjs',
|
|
@@ -61,6 +66,7 @@ const currentFilePath = fileURLToPath(import.meta.url)
|
|
|
61
66
|
const currentScriptDir = path.join(path.dirname(currentFilePath), 'scripts')
|
|
62
67
|
const RUNNER_PACKAGE_DESCRIPTION =
|
|
63
68
|
'Auto-generated lightweight runner for ACE (Agentic Context Engine) scripts. No node_modules required.'
|
|
69
|
+
const KNOWN_PACKAGE_MANAGERS = new Set(['npm', 'pnpm', 'yarn', 'bun'])
|
|
64
70
|
|
|
65
71
|
function normalizeTrailingNewline(content) {
|
|
66
72
|
return content.endsWith('\n') ? content : `${content}\n`
|
|
@@ -78,6 +84,19 @@ async function readTextIfExists(filePath) {
|
|
|
78
84
|
}
|
|
79
85
|
}
|
|
80
86
|
|
|
87
|
+
async function fileExists(filePath) {
|
|
88
|
+
try {
|
|
89
|
+
await access(filePath)
|
|
90
|
+
return true
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {
|
|
93
|
+
return false
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
throw error
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
81
100
|
async function ensureDefaultAgentsFile(rootDir) {
|
|
82
101
|
const agentsPath = path.join(rootDir, 'AGENTS.md')
|
|
83
102
|
const existingContent = await readTextIfExists(agentsPath)
|
|
@@ -135,6 +154,15 @@ async function ensurePackageScripts(rootDir) {
|
|
|
135
154
|
changed = true
|
|
136
155
|
}
|
|
137
156
|
|
|
157
|
+
for (const [scriptName, scriptValue] of Object.entries(DEFAULT_PACKAGE_SCRIPTS)) {
|
|
158
|
+
if (scriptName in nextScripts) {
|
|
159
|
+
continue
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
nextScripts[scriptName] = scriptValue
|
|
163
|
+
changed = true
|
|
164
|
+
}
|
|
165
|
+
|
|
138
166
|
if (!changed) {
|
|
139
167
|
return false
|
|
140
168
|
}
|
|
@@ -218,24 +246,202 @@ export async function installAcePack(targetDir) {
|
|
|
218
246
|
createdFiles.push(...memoryResult.createdFiles)
|
|
219
247
|
updatedFiles.push(...memoryResult.updatedFiles)
|
|
220
248
|
|
|
249
|
+
const createdFileSet = new Set(createdFiles)
|
|
250
|
+
|
|
221
251
|
return {
|
|
222
252
|
createdFiles,
|
|
223
253
|
targetDir: normalizedTargetDir,
|
|
224
|
-
updatedFiles,
|
|
254
|
+
updatedFiles: updatedFiles.filter((filePath) => !createdFileSet.has(filePath)),
|
|
225
255
|
}
|
|
226
256
|
}
|
|
227
257
|
|
|
228
258
|
export function resolveTargetDir(args, cwd = process.cwd()) {
|
|
229
|
-
|
|
259
|
+
return parseInstallArgs(args, cwd).targetDir
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function parseInstallArgs(args, cwd = process.cwd()) {
|
|
263
|
+
if (args.includes('--help') || args.includes('-h') || args[0] === 'help') {
|
|
264
|
+
return {
|
|
265
|
+
apply: false,
|
|
266
|
+
help: true,
|
|
267
|
+
preset: null,
|
|
268
|
+
targetDir: cwd,
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const remainingArgs = [...args]
|
|
273
|
+
|
|
274
|
+
if (remainingArgs[0] === 'init') {
|
|
275
|
+
remainingArgs.shift()
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
let apply = false
|
|
279
|
+
let preset = null
|
|
280
|
+
let target = null
|
|
281
|
+
|
|
282
|
+
for (let index = 0; index < remainingArgs.length; index += 1) {
|
|
283
|
+
const arg = remainingArgs[index]
|
|
230
284
|
|
|
231
|
-
|
|
232
|
-
|
|
285
|
+
if (arg === '--') {
|
|
286
|
+
continue
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (arg === '--apply') {
|
|
290
|
+
apply = true
|
|
291
|
+
continue
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (arg === '--no-apply') {
|
|
295
|
+
apply = false
|
|
296
|
+
continue
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (arg === '--preset') {
|
|
300
|
+
const nextArg = remainingArgs[index + 1]
|
|
301
|
+
|
|
302
|
+
if (!nextArg || nextArg.startsWith('-')) {
|
|
303
|
+
throw new Error('Missing value for --preset.')
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
preset = nextArg
|
|
307
|
+
index += 1
|
|
308
|
+
continue
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (arg.startsWith('--preset=')) {
|
|
312
|
+
preset = arg.slice('--preset='.length)
|
|
313
|
+
|
|
314
|
+
if (!preset) {
|
|
315
|
+
throw new Error('Missing value for --preset.')
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
continue
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (arg.startsWith('-')) {
|
|
322
|
+
throw new Error(`Unknown option: ${arg}`)
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (target !== null) {
|
|
326
|
+
throw new Error(`Unexpected extra argument: ${arg}`)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
target = arg
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (preset && !apply) {
|
|
333
|
+
throw new Error('Use --preset together with --apply.')
|
|
233
334
|
}
|
|
234
335
|
|
|
235
|
-
return
|
|
336
|
+
return {
|
|
337
|
+
apply,
|
|
338
|
+
help: false,
|
|
339
|
+
preset,
|
|
340
|
+
targetDir: path.resolve(cwd, target ?? '.'),
|
|
341
|
+
}
|
|
236
342
|
}
|
|
237
343
|
|
|
238
|
-
export function
|
|
344
|
+
export function getHelpText(commandName = 'ace-pack') {
|
|
345
|
+
return `ACE Pack - install AI project memory into a repository.
|
|
346
|
+
|
|
347
|
+
Usage:
|
|
348
|
+
${commandName} init [target] [--apply] [--preset <name>]
|
|
349
|
+
${commandName} [target]
|
|
350
|
+
|
|
351
|
+
Recommended:
|
|
352
|
+
npx ace-pack@latest init
|
|
353
|
+
pnpm dlx ace-pack init
|
|
354
|
+
|
|
355
|
+
Options:
|
|
356
|
+
--apply Run ace:onboard -- --apply after installation.
|
|
357
|
+
--preset <name> Apply a built-in project preset during onboarding.
|
|
358
|
+
-h, --help Show this help.
|
|
359
|
+
|
|
360
|
+
Examples:
|
|
361
|
+
npx ace-pack@latest init
|
|
362
|
+
npx ace-pack@latest init D:\\All\\alex-work\\my-project --apply
|
|
363
|
+
pnpm dlx ace-pack init . --apply
|
|
364
|
+
|
|
365
|
+
Do not use npm install ace-pack for setup. ACE is a scaffold CLI: run init so it
|
|
366
|
+
can add AGENTS.md, .ai/*, scripts/*, and package.json commands to the project.
|
|
367
|
+
`
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function getPackageManagerFromPackageJson(packageJson) {
|
|
371
|
+
if (typeof packageJson.packageManager !== 'string') {
|
|
372
|
+
return null
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const packageManagerName = packageJson.packageManager.split('@')[0]
|
|
376
|
+
|
|
377
|
+
return KNOWN_PACKAGE_MANAGERS.has(packageManagerName) ? packageManagerName : null
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function getPackageManagerFromUserAgent(userAgent = process.env.npm_config_user_agent) {
|
|
381
|
+
if (!userAgent) {
|
|
382
|
+
return null
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const packageManagerName = userAgent.split('/')[0]
|
|
386
|
+
|
|
387
|
+
return KNOWN_PACKAGE_MANAGERS.has(packageManagerName) ? packageManagerName : null
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export async function detectPackageManager(rootDir) {
|
|
391
|
+
const packageJsonContent = await readTextIfExists(path.join(rootDir, 'package.json'))
|
|
392
|
+
|
|
393
|
+
if (packageJsonContent !== null) {
|
|
394
|
+
const packageJson = JSON.parse(stripByteOrderMark(packageJsonContent))
|
|
395
|
+
const packageManager = getPackageManagerFromPackageJson(packageJson)
|
|
396
|
+
|
|
397
|
+
if (packageManager) {
|
|
398
|
+
return packageManager
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const lockFileChecks = [
|
|
403
|
+
['pnpm-lock.yaml', 'pnpm'],
|
|
404
|
+
['package-lock.json', 'npm'],
|
|
405
|
+
['npm-shrinkwrap.json', 'npm'],
|
|
406
|
+
['yarn.lock', 'yarn'],
|
|
407
|
+
['bun.lock', 'bun'],
|
|
408
|
+
['bun.lockb', 'bun'],
|
|
409
|
+
]
|
|
410
|
+
|
|
411
|
+
for (const [filename, packageManager] of lockFileChecks) {
|
|
412
|
+
if (await fileExists(path.join(rootDir, filename))) {
|
|
413
|
+
return packageManager
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return getPackageManagerFromUserAgent() ?? 'npm'
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export function formatScriptCommand(packageManager, scriptName, args = []) {
|
|
421
|
+
const extraArgs = args.length > 0 ? args.join(' ') : ''
|
|
422
|
+
|
|
423
|
+
if (packageManager === 'npm') {
|
|
424
|
+
return `npm run ${scriptName}${extraArgs ? ` -- ${extraArgs}` : ''}`
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (packageManager === 'yarn') {
|
|
428
|
+
return `yarn ${scriptName}${extraArgs ? ` ${extraArgs}` : ''}`
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
if (packageManager === 'bun') {
|
|
432
|
+
return `bun run ${scriptName}${extraArgs ? ` ${extraArgs}` : ''}`
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return `pnpm ${scriptName}${extraArgs ? ` -- ${extraArgs}` : ''}`
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
function formatPowerShellPnpmCommand(command) {
|
|
439
|
+
return command.replace(/^pnpm /u, 'pnpm.cmd ')
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export async function printInstallResult(result, options = {}) {
|
|
443
|
+
const packageManager = options.packageManager ?? (await detectPackageManager(result.targetDir))
|
|
444
|
+
|
|
239
445
|
if (result.updatedFiles.length === 0 && result.createdFiles.length === 0) {
|
|
240
446
|
process.stderr.write(`ACE pack is already up to date in ${result.targetDir}\n`)
|
|
241
447
|
}
|
|
@@ -248,14 +454,62 @@ export function printInstallResult(result) {
|
|
|
248
454
|
process.stderr.write(`Created: ${result.createdFiles.join(', ')}\n`)
|
|
249
455
|
}
|
|
250
456
|
|
|
251
|
-
|
|
457
|
+
if (result.onboarding?.applied) {
|
|
458
|
+
process.stderr.write(`Onboarded: ${result.onboarding.writtenFiles.join(', ')}\n`)
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const nextCommands = []
|
|
462
|
+
|
|
463
|
+
if (!result.onboarding?.applied) {
|
|
464
|
+
nextCommands.push(formatScriptCommand(packageManager, 'ace:onboard', ['--apply']))
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
nextCommands.push(formatScriptCommand(packageManager, 'ace:check'))
|
|
468
|
+
nextCommands.push(formatScriptCommand(packageManager, 'ace:hub'))
|
|
469
|
+
|
|
470
|
+
process.stderr.write('\nNext:\n')
|
|
471
|
+
|
|
472
|
+
for (const command of nextCommands) {
|
|
473
|
+
process.stderr.write(` ${command}\n`)
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
if (packageManager === 'pnpm' && process.platform === 'win32') {
|
|
477
|
+
process.stderr.write(
|
|
478
|
+
`\nWindows PowerShell note: if pnpm is blocked, use ${formatPowerShellPnpmCommand(
|
|
479
|
+
nextCommands[0],
|
|
480
|
+
)}\n`,
|
|
481
|
+
)
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export async function runInstallCli(args, options = {}) {
|
|
486
|
+
const commandName = options.commandName ?? 'ace-pack'
|
|
487
|
+
const parsedArgs = parseInstallArgs(args)
|
|
488
|
+
|
|
489
|
+
if (parsedArgs.help) {
|
|
490
|
+
process.stdout.write(getHelpText(commandName))
|
|
491
|
+
return
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const result = await installAcePack(parsedArgs.targetDir)
|
|
495
|
+
|
|
496
|
+
if (parsedArgs.apply) {
|
|
497
|
+
result.onboarding = await onboardRepository(parsedArgs.targetDir, {
|
|
498
|
+
apply: true,
|
|
499
|
+
preset: parsedArgs.preset ?? undefined,
|
|
500
|
+
})
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
await printInstallResult(result)
|
|
252
504
|
}
|
|
253
505
|
|
|
254
506
|
const isMainModule =
|
|
255
507
|
process.argv[1] !== undefined && path.resolve(process.argv[1]) === currentFilePath
|
|
256
508
|
|
|
257
509
|
if (isMainModule) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
510
|
+
await runInstallCli(process.argv.slice(2)).catch((error) => {
|
|
511
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
512
|
+
process.stderr.write(`${message}\n\nRun ace-pack --help for usage.\n`)
|
|
513
|
+
process.exit(1)
|
|
514
|
+
})
|
|
261
515
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { fileURLToPath } from 'node:url'
|
|
4
4
|
|
|
5
|
-
import { installAcePack,
|
|
5
|
+
import { installAcePack, runInstallCli } from './install-ace-pack.mjs'
|
|
6
6
|
|
|
7
7
|
export const installAgentMemoryPack = installAcePack
|
|
8
8
|
|
|
@@ -11,7 +11,11 @@ const isMainModule =
|
|
|
11
11
|
process.argv[1] !== undefined && path.resolve(process.argv[1]) === currentFilePath
|
|
12
12
|
|
|
13
13
|
if (isMainModule) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
await runInstallCli(process.argv.slice(2), { commandName: 'agent-memory-pack' }).catch(
|
|
15
|
+
(error) => {
|
|
16
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
17
|
+
process.stderr.write(`${message}\n\nRun agent-memory-pack --help for usage.\n`)
|
|
18
|
+
process.exit(1)
|
|
19
|
+
},
|
|
20
|
+
)
|
|
17
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ace-pack",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Zero-dependency cognitive architecture framework for AI-driven development.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"install:pack": "node ./install-ace-pack.mjs",
|
|
39
39
|
"install:legacy": "node ./install-agent-memory-pack.mjs",
|
|
40
40
|
"link:global": "pnpm link --global",
|
|
41
|
+
"ace:validate": "node ./scripts/check-agent-memory.mjs",
|
|
41
42
|
"test": "vitest run"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
@@ -177,6 +177,9 @@ task.
|
|
|
177
177
|
- Use \`pnpm ace:classify\` to select the adaptive task tier.
|
|
178
178
|
- Run \`pnpm ace:onboard\` after fresh installation in an unfamiliar project
|
|
179
179
|
before trusting project-specific risk rules.
|
|
180
|
+
- On Windows PowerShell, use \`pnpm.cmd ace:classify\`,
|
|
181
|
+
\`pnpm.cmd ace:validate\`, and similar commands if script execution policy
|
|
182
|
+
blocks the \`pnpm\` shim.
|
|
180
183
|
- For large or high-risk standard tasks, complete \`.ai/current-task.md\`
|
|
181
184
|
Business Value and Technical Approach before writing code.
|
|
182
185
|
- Treat \`.ai/*\` as the current source of task context and handoff state.
|
|
@@ -218,6 +221,10 @@ Before starting work:
|
|
|
218
221
|
7. Read \`.ai/work-log.md\` only when you need extra historical context.
|
|
219
222
|
8. If the memory files are missing, run \`pnpm ace:init\`.
|
|
220
223
|
|
|
224
|
+
Command note: examples use \`pnpm\`. On Windows PowerShell, use
|
|
225
|
+
\`pnpm.cmd ace:classify\`, \`pnpm.cmd ace:validate\`, and similar commands if
|
|
226
|
+
the \`pnpm\` shim is blocked by execution policy.
|
|
227
|
+
|
|
221
228
|
Legacy commands such as \`pnpm ai:task:classify\`, \`pnpm ai:task:finish\`,
|
|
222
229
|
and \`pnpm agent-memory:init\` remain supported for compatibility.
|
|
223
230
|
|