@acta-dev/cli 1.2.0 → 1.4.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/dist/index.js +325 -57
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { realpathSync } from "fs";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
|
-
import { defineCommand as
|
|
6
|
+
import { defineCommand as defineCommand11, runMain } from "citty";
|
|
7
7
|
|
|
8
8
|
// src/commands/build.ts
|
|
9
9
|
import { buildArtifacts } from "@acta-dev/core";
|
|
@@ -222,14 +222,17 @@ var graphCommand = defineCommand2({
|
|
|
222
222
|
});
|
|
223
223
|
|
|
224
224
|
// src/commands/init.ts
|
|
225
|
-
import { existsSync as
|
|
226
|
-
import { mkdir, writeFile } from "fs/promises";
|
|
227
|
-
import { join as
|
|
225
|
+
import { existsSync as existsSync3 } from "fs";
|
|
226
|
+
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
227
|
+
import { join as join3, resolve as resolve2 } from "path";
|
|
228
228
|
import { createInterface } from "readline";
|
|
229
229
|
import { resolveConfig as resolveConfig3 } from "@acta-dev/core";
|
|
230
230
|
import { defineCommand as defineCommand3 } from "citty";
|
|
231
231
|
|
|
232
232
|
// src/skill.ts
|
|
233
|
+
import { existsSync as existsSync2 } from "fs";
|
|
234
|
+
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
235
|
+
import { join as join2 } from "path";
|
|
233
236
|
import {
|
|
234
237
|
adrStatuses,
|
|
235
238
|
documentKinds,
|
|
@@ -239,6 +242,7 @@ import {
|
|
|
239
242
|
specStatuses
|
|
240
243
|
} from "@acta-dev/core";
|
|
241
244
|
var SKILL_NAME = "acta-document";
|
|
245
|
+
var skillFormats = ["codex", "claude", "both"];
|
|
242
246
|
var LINK_DESCRIPTIONS = {
|
|
243
247
|
related: "Loosely related documents.",
|
|
244
248
|
supersedes: "This document supersedes the target; mirror with `replacedBy`.",
|
|
@@ -388,6 +392,212 @@ ${block}
|
|
|
388
392
|
` : `${block}
|
|
389
393
|
`;
|
|
390
394
|
}
|
|
395
|
+
async function installAgentSkill(cwd, format) {
|
|
396
|
+
const skillPaths = [];
|
|
397
|
+
const skillContent = renderSkill();
|
|
398
|
+
if (format === "codex" || format === "both") {
|
|
399
|
+
const skillDir = join2(cwd, ".agents", "skills", SKILL_NAME);
|
|
400
|
+
await mkdir(skillDir, { recursive: true });
|
|
401
|
+
const skillPath = join2(skillDir, "SKILL.md");
|
|
402
|
+
await writeFile(skillPath, skillContent, "utf8");
|
|
403
|
+
skillPaths.push(skillPath);
|
|
404
|
+
const agentsPath = join2(cwd, "AGENTS.md");
|
|
405
|
+
const existing = existsSync2(agentsPath) ? await readFile(agentsPath, "utf8") : "";
|
|
406
|
+
await writeFile(agentsPath, upsertAgentsBlock(existing), "utf8");
|
|
407
|
+
if (format === "codex") {
|
|
408
|
+
return { skillPaths, agentsPath };
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (format === "claude" || format === "both") {
|
|
412
|
+
const skillDir = join2(cwd, ".claude", "skills", SKILL_NAME);
|
|
413
|
+
await mkdir(skillDir, { recursive: true });
|
|
414
|
+
const skillPath = join2(skillDir, "SKILL.md");
|
|
415
|
+
await writeFile(skillPath, skillContent, "utf8");
|
|
416
|
+
skillPaths.push(skillPath);
|
|
417
|
+
}
|
|
418
|
+
return format === "both" ? { skillPaths, agentsPath: join2(cwd, "AGENTS.md") } : { skillPaths };
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// src/commands/deploy-workflows.ts
|
|
422
|
+
var DEPLOY_PROVIDERS = ["pages", "cloudflare", "vercel", "netlify"];
|
|
423
|
+
var DEPLOY_WORKFLOW_TEMPLATES = {
|
|
424
|
+
pages: `name: Deploy Acta Pages
|
|
425
|
+
|
|
426
|
+
on:
|
|
427
|
+
push:
|
|
428
|
+
branches:
|
|
429
|
+
- main
|
|
430
|
+
workflow_dispatch:
|
|
431
|
+
|
|
432
|
+
permissions:
|
|
433
|
+
contents: read
|
|
434
|
+
pages: write
|
|
435
|
+
id-token: write
|
|
436
|
+
|
|
437
|
+
concurrency:
|
|
438
|
+
group: acta-pages
|
|
439
|
+
cancel-in-progress: false
|
|
440
|
+
|
|
441
|
+
jobs:
|
|
442
|
+
build:
|
|
443
|
+
name: Build Acta static viewer
|
|
444
|
+
runs-on: ubuntu-latest
|
|
445
|
+
steps:
|
|
446
|
+
- name: Checkout
|
|
447
|
+
uses: actions/checkout@v4
|
|
448
|
+
|
|
449
|
+
- name: Setup pnpm
|
|
450
|
+
uses: pnpm/action-setup@v4
|
|
451
|
+
with:
|
|
452
|
+
version: 11
|
|
453
|
+
|
|
454
|
+
- name: Setup Node
|
|
455
|
+
uses: actions/setup-node@v4
|
|
456
|
+
with:
|
|
457
|
+
node-version: 22
|
|
458
|
+
|
|
459
|
+
- name: Build Acta site
|
|
460
|
+
run: pnpm dlx @acta-dev/cli site --base "/\${{ github.event.repository.name }}"
|
|
461
|
+
|
|
462
|
+
- name: Configure Pages
|
|
463
|
+
uses: actions/configure-pages@v5
|
|
464
|
+
|
|
465
|
+
- name: Upload Pages artifact
|
|
466
|
+
uses: actions/upload-pages-artifact@v4
|
|
467
|
+
with:
|
|
468
|
+
path: .acta/site
|
|
469
|
+
|
|
470
|
+
deploy:
|
|
471
|
+
name: Deploy to GitHub Pages
|
|
472
|
+
needs: build
|
|
473
|
+
runs-on: ubuntu-latest
|
|
474
|
+
environment:
|
|
475
|
+
name: github-pages
|
|
476
|
+
url: \${{ steps.deployment.outputs.page_url }}
|
|
477
|
+
steps:
|
|
478
|
+
- name: Deploy Pages
|
|
479
|
+
id: deployment
|
|
480
|
+
uses: actions/deploy-pages@v4
|
|
481
|
+
`,
|
|
482
|
+
cloudflare: `name: Deploy Acta to Cloudflare Pages
|
|
483
|
+
|
|
484
|
+
on:
|
|
485
|
+
push:
|
|
486
|
+
branches:
|
|
487
|
+
- main
|
|
488
|
+
workflow_dispatch:
|
|
489
|
+
|
|
490
|
+
permissions:
|
|
491
|
+
contents: read
|
|
492
|
+
|
|
493
|
+
jobs:
|
|
494
|
+
deploy:
|
|
495
|
+
name: Deploy Acta static viewer
|
|
496
|
+
runs-on: ubuntu-latest
|
|
497
|
+
steps:
|
|
498
|
+
- name: Checkout
|
|
499
|
+
uses: actions/checkout@v4
|
|
500
|
+
|
|
501
|
+
- name: Setup pnpm
|
|
502
|
+
uses: pnpm/action-setup@v4
|
|
503
|
+
with:
|
|
504
|
+
version: 11
|
|
505
|
+
|
|
506
|
+
- name: Setup Node
|
|
507
|
+
uses: actions/setup-node@v4
|
|
508
|
+
with:
|
|
509
|
+
node-version: 22
|
|
510
|
+
|
|
511
|
+
- name: Build Acta site
|
|
512
|
+
run: pnpm dlx @acta-dev/cli site
|
|
513
|
+
|
|
514
|
+
- name: Deploy to Cloudflare Pages
|
|
515
|
+
uses: cloudflare/wrangler-action@v3
|
|
516
|
+
with:
|
|
517
|
+
apiToken: \${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
518
|
+
accountId: \${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
519
|
+
command: pages deploy .acta/site --project-name="\${{ vars.CLOUDFLARE_PROJECT_NAME }}"
|
|
520
|
+
`,
|
|
521
|
+
vercel: `name: Deploy Acta to Vercel
|
|
522
|
+
|
|
523
|
+
on:
|
|
524
|
+
push:
|
|
525
|
+
branches:
|
|
526
|
+
- main
|
|
527
|
+
workflow_dispatch:
|
|
528
|
+
|
|
529
|
+
permissions:
|
|
530
|
+
contents: read
|
|
531
|
+
|
|
532
|
+
jobs:
|
|
533
|
+
deploy:
|
|
534
|
+
name: Deploy Acta static viewer
|
|
535
|
+
runs-on: ubuntu-latest
|
|
536
|
+
steps:
|
|
537
|
+
- name: Checkout
|
|
538
|
+
uses: actions/checkout@v4
|
|
539
|
+
|
|
540
|
+
- name: Setup pnpm
|
|
541
|
+
uses: pnpm/action-setup@v4
|
|
542
|
+
with:
|
|
543
|
+
version: 11
|
|
544
|
+
|
|
545
|
+
- name: Setup Node
|
|
546
|
+
uses: actions/setup-node@v4
|
|
547
|
+
with:
|
|
548
|
+
node-version: 22
|
|
549
|
+
|
|
550
|
+
- name: Build Acta site
|
|
551
|
+
run: pnpm dlx @acta-dev/cli site
|
|
552
|
+
|
|
553
|
+
- name: Deploy to Vercel
|
|
554
|
+
run: pnpm dlx vercel .acta/site --prod --yes --token="\${{ secrets.VERCEL_TOKEN }}"
|
|
555
|
+
env:
|
|
556
|
+
VERCEL_ORG_ID: \${{ secrets.VERCEL_ORG_ID }}
|
|
557
|
+
VERCEL_PROJECT_ID: \${{ secrets.VERCEL_PROJECT_ID }}
|
|
558
|
+
`,
|
|
559
|
+
netlify: `name: Deploy Acta to Netlify
|
|
560
|
+
|
|
561
|
+
on:
|
|
562
|
+
push:
|
|
563
|
+
branches:
|
|
564
|
+
- main
|
|
565
|
+
workflow_dispatch:
|
|
566
|
+
|
|
567
|
+
permissions:
|
|
568
|
+
contents: read
|
|
569
|
+
|
|
570
|
+
jobs:
|
|
571
|
+
deploy:
|
|
572
|
+
name: Deploy Acta static viewer
|
|
573
|
+
runs-on: ubuntu-latest
|
|
574
|
+
steps:
|
|
575
|
+
- name: Checkout
|
|
576
|
+
uses: actions/checkout@v4
|
|
577
|
+
|
|
578
|
+
- name: Setup pnpm
|
|
579
|
+
uses: pnpm/action-setup@v4
|
|
580
|
+
with:
|
|
581
|
+
version: 11
|
|
582
|
+
|
|
583
|
+
- name: Setup Node
|
|
584
|
+
uses: actions/setup-node@v4
|
|
585
|
+
with:
|
|
586
|
+
node-version: 22
|
|
587
|
+
|
|
588
|
+
- name: Build Acta site
|
|
589
|
+
run: pnpm dlx @acta-dev/cli site
|
|
590
|
+
|
|
591
|
+
- name: Deploy to Netlify
|
|
592
|
+
run: pnpm dlx netlify-cli deploy --dir=.acta/site --prod
|
|
593
|
+
env:
|
|
594
|
+
NETLIFY_AUTH_TOKEN: \${{ secrets.NETLIFY_AUTH_TOKEN }}
|
|
595
|
+
NETLIFY_SITE_ID: \${{ secrets.NETLIFY_SITE_ID }}
|
|
596
|
+
`
|
|
597
|
+
};
|
|
598
|
+
function isDeployProvider(value) {
|
|
599
|
+
return DEPLOY_PROVIDERS.includes(value);
|
|
600
|
+
}
|
|
391
601
|
|
|
392
602
|
// src/commands/init.ts
|
|
393
603
|
var ADR_TEMPLATE = `---
|
|
@@ -566,7 +776,7 @@ async function confirm(message) {
|
|
|
566
776
|
});
|
|
567
777
|
}
|
|
568
778
|
async function safeWriteFile(filePath, content, yes) {
|
|
569
|
-
if (
|
|
779
|
+
if (existsSync3(filePath)) {
|
|
570
780
|
if (!yes) {
|
|
571
781
|
const ok = await confirm(` Overwrite ${filePath}?`);
|
|
572
782
|
if (!ok) {
|
|
@@ -577,7 +787,7 @@ async function safeWriteFile(filePath, content, yes) {
|
|
|
577
787
|
printWarn(`Overwriting ${filePath}`);
|
|
578
788
|
}
|
|
579
789
|
}
|
|
580
|
-
await
|
|
790
|
+
await writeFile2(filePath, content, "utf8");
|
|
581
791
|
return true;
|
|
582
792
|
}
|
|
583
793
|
var initCommand = defineCommand3({
|
|
@@ -602,9 +812,13 @@ var initCommand = defineCommand3({
|
|
|
602
812
|
description: "Install GitHub Actions workflow template",
|
|
603
813
|
default: false
|
|
604
814
|
},
|
|
815
|
+
deploy: {
|
|
816
|
+
type: "string",
|
|
817
|
+
description: "Install a deploy workflow template: pages, cloudflare, vercel or netlify"
|
|
818
|
+
},
|
|
605
819
|
skill: {
|
|
606
820
|
type: "boolean",
|
|
607
|
-
description: "
|
|
821
|
+
description: "Compatibility alias for `acta skill --init` after scaffolding",
|
|
608
822
|
default: false
|
|
609
823
|
},
|
|
610
824
|
config: {
|
|
@@ -616,10 +830,14 @@ var initCommand = defineCommand3({
|
|
|
616
830
|
async run({ args }) {
|
|
617
831
|
const cwd = resolve2(process.cwd());
|
|
618
832
|
const yes = args.yes;
|
|
833
|
+
const deploy = args.deploy;
|
|
834
|
+
if (deploy !== void 0 && !isDeployProvider(deploy)) {
|
|
835
|
+
return exitUsage(`Expected --deploy to be one of: ${DEPLOY_PROVIDERS.join(", ")}.`);
|
|
836
|
+
}
|
|
619
837
|
const config = resolveConfig3({}, { rootDir: cwd });
|
|
620
838
|
printLine("Initializing Acta docs structure...");
|
|
621
839
|
printLine();
|
|
622
|
-
const configPath =
|
|
840
|
+
const configPath = join3(cwd, "acta.config.ts");
|
|
623
841
|
const configWritten = await safeWriteFile(configPath, CONFIG_TEMPLATE, yes);
|
|
624
842
|
if (configWritten) printSuccess(`Created ${configPath}`);
|
|
625
843
|
const dirs = [
|
|
@@ -628,47 +846,55 @@ var initCommand = defineCommand3({
|
|
|
628
846
|
config.resolvedDocs.templatesDir
|
|
629
847
|
];
|
|
630
848
|
for (const dir of dirs) {
|
|
631
|
-
await
|
|
849
|
+
await mkdir2(dir, { recursive: true });
|
|
632
850
|
printSuccess(`Created dir ${dir}`);
|
|
633
851
|
}
|
|
634
|
-
const adrTplPath =
|
|
635
|
-
const specTplPath =
|
|
852
|
+
const adrTplPath = join3(config.resolvedDocs.templatesDir, "adr.md");
|
|
853
|
+
const specTplPath = join3(config.resolvedDocs.templatesDir, "spec.md");
|
|
636
854
|
const adrWritten = await safeWriteFile(adrTplPath, ADR_TEMPLATE, yes);
|
|
637
855
|
if (adrWritten) printSuccess(`Created ${adrTplPath}`);
|
|
638
856
|
const specWritten = await safeWriteFile(specTplPath, SPEC_TEMPLATE, yes);
|
|
639
857
|
if (specWritten) printSuccess(`Created ${specTplPath}`);
|
|
640
|
-
const gitignorePath =
|
|
641
|
-
if (
|
|
642
|
-
const { readFile:
|
|
643
|
-
const content = await
|
|
858
|
+
const gitignorePath = join3(cwd, ".gitignore");
|
|
859
|
+
if (existsSync3(gitignorePath)) {
|
|
860
|
+
const { readFile: readFile4, appendFile } = await import("fs/promises");
|
|
861
|
+
const content = await readFile4(gitignorePath, "utf8");
|
|
644
862
|
if (!content.includes(".acta/")) {
|
|
645
863
|
await appendFile(gitignorePath, "\n# Acta build artifacts\n.acta/\n");
|
|
646
864
|
printSuccess(`Added .acta/ to .gitignore`);
|
|
647
865
|
}
|
|
648
866
|
}
|
|
649
867
|
if (args.hooks) {
|
|
650
|
-
const lefthookPath =
|
|
868
|
+
const lefthookPath = join3(cwd, "lefthook.yml");
|
|
651
869
|
const lefthookWritten = await safeWriteFile(lefthookPath, LEFTHOOK_TEMPLATE, yes);
|
|
652
870
|
if (lefthookWritten) printSuccess(`Created ${lefthookPath}`);
|
|
653
871
|
}
|
|
654
872
|
if (args["github-action"]) {
|
|
655
|
-
const workflowsDir =
|
|
656
|
-
await
|
|
657
|
-
const workflowPath =
|
|
873
|
+
const workflowsDir = join3(cwd, ".github", "workflows");
|
|
874
|
+
await mkdir2(workflowsDir, { recursive: true });
|
|
875
|
+
const workflowPath = join3(workflowsDir, "acta-ci.yml");
|
|
658
876
|
const workflowWritten = await safeWriteFile(workflowPath, GITHUB_ACTION_TEMPLATE, yes);
|
|
659
877
|
if (workflowWritten) printSuccess(`Created ${workflowPath}`);
|
|
660
878
|
}
|
|
879
|
+
if (deploy !== void 0) {
|
|
880
|
+
const workflowsDir = join3(cwd, ".github", "workflows");
|
|
881
|
+
await mkdir2(workflowsDir, { recursive: true });
|
|
882
|
+
const workflowPath = join3(workflowsDir, `acta-deploy-${deploy}.yml`);
|
|
883
|
+
const workflowWritten = await safeWriteFile(
|
|
884
|
+
workflowPath,
|
|
885
|
+
DEPLOY_WORKFLOW_TEMPLATES[deploy],
|
|
886
|
+
yes
|
|
887
|
+
);
|
|
888
|
+
if (workflowWritten) printSuccess(`Created ${workflowPath}`);
|
|
889
|
+
}
|
|
661
890
|
if (args.skill) {
|
|
662
|
-
const
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
if (
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
const existing = existsSync2(agentsPath) ? await readFile3(agentsPath, "utf8") : "";
|
|
670
|
-
await writeFile(agentsPath, upsertAgentsBlock(existing), "utf8");
|
|
671
|
-
printSuccess(`Updated ${agentsPath} with Acta agent guidance`);
|
|
891
|
+
const result = await installAgentSkill(cwd, "both");
|
|
892
|
+
for (const skillPath of result.skillPaths) {
|
|
893
|
+
printSuccess(`Installed ${skillPath}`);
|
|
894
|
+
}
|
|
895
|
+
if (result.agentsPath) {
|
|
896
|
+
printSuccess(`Updated ${result.agentsPath} with Acta agent guidance`);
|
|
897
|
+
}
|
|
672
898
|
}
|
|
673
899
|
printLine();
|
|
674
900
|
printSuccess("Acta initialized. Run `acta validate` to check your documents.");
|
|
@@ -782,9 +1008,9 @@ var listCommand = defineCommand4({
|
|
|
782
1008
|
});
|
|
783
1009
|
|
|
784
1010
|
// src/commands/new.ts
|
|
785
|
-
import { existsSync as
|
|
786
|
-
import { writeFile as
|
|
787
|
-
import { join as
|
|
1011
|
+
import { existsSync as existsSync4 } from "fs";
|
|
1012
|
+
import { writeFile as writeFile3 } from "fs/promises";
|
|
1013
|
+
import { join as join5, relative } from "path";
|
|
788
1014
|
import { adrStatuses as adrStatuses2, specStatuses as specStatuses2 } from "@acta-dev/core";
|
|
789
1015
|
import { defineCommand as defineCommand5 } from "citty";
|
|
790
1016
|
|
|
@@ -805,11 +1031,11 @@ function titleToSlug(title) {
|
|
|
805
1031
|
}
|
|
806
1032
|
|
|
807
1033
|
// src/template.ts
|
|
808
|
-
import { readFile } from "fs/promises";
|
|
809
|
-
import { join as
|
|
1034
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
1035
|
+
import { join as join4 } from "path";
|
|
810
1036
|
async function renderTemplate(kind, vars, config) {
|
|
811
|
-
const templateFile =
|
|
812
|
-
const raw = await
|
|
1037
|
+
const templateFile = join4(config.resolvedDocs.templatesDir, `${kind}.md`);
|
|
1038
|
+
const raw = await readFile2(templateFile, "utf8");
|
|
813
1039
|
return interpolate(raw, vars);
|
|
814
1040
|
}
|
|
815
1041
|
function interpolate(raw, vars) {
|
|
@@ -854,8 +1080,8 @@ async function createDocument(kind, title, opts) {
|
|
|
854
1080
|
const slug = titleToSlug(title.trim());
|
|
855
1081
|
const filename = `${id}-${slug}.md`;
|
|
856
1082
|
const dir = kind === "adr" ? config.resolvedDocs.adrDir : config.resolvedDocs.specDir;
|
|
857
|
-
const destPath =
|
|
858
|
-
if (
|
|
1083
|
+
const destPath = join5(dir, filename);
|
|
1084
|
+
if (existsSync4(destPath)) {
|
|
859
1085
|
exitFailure(`File already exists: ${destPath}`);
|
|
860
1086
|
}
|
|
861
1087
|
const content = await renderTemplate(
|
|
@@ -863,7 +1089,7 @@ async function createDocument(kind, title, opts) {
|
|
|
863
1089
|
{ id, title: title.trim(), date: nowIsoDateTime(), status, tags: parseTags(opts.tags) },
|
|
864
1090
|
config
|
|
865
1091
|
);
|
|
866
|
-
await
|
|
1092
|
+
await writeFile3(destPath, content, "utf8");
|
|
867
1093
|
if (opts.json) {
|
|
868
1094
|
printJson({
|
|
869
1095
|
id,
|
|
@@ -971,8 +1197,8 @@ function parseTags(value) {
|
|
|
971
1197
|
}
|
|
972
1198
|
|
|
973
1199
|
// src/commands/renumber.ts
|
|
974
|
-
import { readFile as
|
|
975
|
-
import { basename, dirname, join as
|
|
1200
|
+
import { readFile as readFile3, rename, writeFile as writeFile4 } from "fs/promises";
|
|
1201
|
+
import { basename, dirname, join as join6 } from "path";
|
|
976
1202
|
import { internalLinkKeys as internalLinkKeys2, loadProject as loadProject3 } from "@acta-dev/core";
|
|
977
1203
|
import { defineCommand as defineCommand6 } from "citty";
|
|
978
1204
|
import kleur4 from "kleur";
|
|
@@ -996,7 +1222,7 @@ function buildRenumberPlan(fromId, toId, project) {
|
|
|
996
1222
|
const oldFilename = basename(target.file.path);
|
|
997
1223
|
const oldSlug = oldFilename.replace(`${target.id}-`, "").replace(/\.md$/, "");
|
|
998
1224
|
const newFilename = `${toId}-${oldSlug}.md`;
|
|
999
|
-
const newPath =
|
|
1225
|
+
const newPath = join6(dirname(target.file.path), newFilename);
|
|
1000
1226
|
const affectedDocs = project.documents.filter((d) => d.id !== target.id).filter((d) => internalLinkKeys2.some((key) => d.links[key].includes(target.id))).map((d) => ({ doc: d, path: d.file.path }));
|
|
1001
1227
|
return {
|
|
1002
1228
|
target,
|
|
@@ -1007,7 +1233,7 @@ function buildRenumberPlan(fromId, toId, project) {
|
|
|
1007
1233
|
};
|
|
1008
1234
|
}
|
|
1009
1235
|
async function rewriteDocument(filePath, oldId, newId, isTarget) {
|
|
1010
|
-
const raw = await
|
|
1236
|
+
const raw = await readFile3(filePath, "utf8");
|
|
1011
1237
|
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
1012
1238
|
if (!match) {
|
|
1013
1239
|
throw new Error(`Cannot parse frontmatter in ${filePath}`);
|
|
@@ -1091,11 +1317,11 @@ var renumberCommand = defineCommand6({
|
|
|
1091
1317
|
printLine();
|
|
1092
1318
|
for (const { doc, path } of plan.affectedDocs) {
|
|
1093
1319
|
const rewritten = await rewriteDocument(path, fromId, toId, false);
|
|
1094
|
-
await
|
|
1320
|
+
await writeFile4(path, rewritten, "utf8");
|
|
1095
1321
|
printSuccess(`Updated links in ${doc.id}`);
|
|
1096
1322
|
}
|
|
1097
1323
|
const rewrittenTarget = await rewriteDocument(plan.oldPath, fromId, toId, true);
|
|
1098
|
-
await
|
|
1324
|
+
await writeFile4(plan.oldPath, rewrittenTarget, "utf8");
|
|
1099
1325
|
await rename(plan.oldPath, plan.newPath);
|
|
1100
1326
|
printSuccess(`Renamed ${basename(plan.oldPath)} \u2192 ${plan.newFilename}`);
|
|
1101
1327
|
printLine();
|
|
@@ -1221,7 +1447,7 @@ import { createReadStream } from "fs";
|
|
|
1221
1447
|
import { stat } from "fs/promises";
|
|
1222
1448
|
import { createServer } from "http";
|
|
1223
1449
|
import { createRequire } from "module";
|
|
1224
|
-
import { dirname as dirname2, extname, join as
|
|
1450
|
+
import { dirname as dirname2, extname, join as join7, relative as relative2, resolve as resolve3, sep } from "path";
|
|
1225
1451
|
import { buildArtifacts as buildArtifacts2 } from "@acta-dev/core";
|
|
1226
1452
|
import { defineCommand as defineCommand8 } from "citty";
|
|
1227
1453
|
import kleur6 from "kleur";
|
|
@@ -1388,13 +1614,13 @@ function resolveWebPackageDir() {
|
|
|
1388
1614
|
}
|
|
1389
1615
|
}
|
|
1390
1616
|
function resolveAstroBin(webDir) {
|
|
1391
|
-
const require2 = createRequire(
|
|
1617
|
+
const require2 = createRequire(join7(webDir, "package.json"));
|
|
1392
1618
|
try {
|
|
1393
1619
|
const astroPkgJsonPath = require2.resolve("astro/package.json");
|
|
1394
1620
|
const astroPkg = require2("astro/package.json");
|
|
1395
1621
|
const binRel = typeof astroPkg.bin === "string" ? astroPkg.bin : astroPkg.bin?.astro;
|
|
1396
1622
|
if (!binRel) return void 0;
|
|
1397
|
-
return
|
|
1623
|
+
return join7(dirname2(astroPkgJsonPath), binRel);
|
|
1398
1624
|
} catch {
|
|
1399
1625
|
return void 0;
|
|
1400
1626
|
}
|
|
@@ -1502,7 +1728,7 @@ async function resolveStaticSiteResponse(options) {
|
|
|
1502
1728
|
}
|
|
1503
1729
|
try {
|
|
1504
1730
|
const fileStat = await stat(filePath);
|
|
1505
|
-
const finalPath = fileStat.isDirectory() ?
|
|
1731
|
+
const finalPath = fileStat.isDirectory() ? join7(filePath, "index.html") : filePath;
|
|
1506
1732
|
const finalStat = fileStat.isDirectory() ? await stat(finalPath) : fileStat;
|
|
1507
1733
|
if (!finalStat.isFile()) {
|
|
1508
1734
|
return { status: 404, contentType: "text/plain; charset=utf-8", text: "Not Found" };
|
|
@@ -1567,13 +1793,54 @@ function isAddressInUse(error) {
|
|
|
1567
1793
|
return typeof error === "object" && error !== null && "code" in error && error.code === "EADDRINUSE";
|
|
1568
1794
|
}
|
|
1569
1795
|
|
|
1796
|
+
// src/commands/skill.ts
|
|
1797
|
+
import { resolve as resolve4 } from "path";
|
|
1798
|
+
import { defineCommand as defineCommand9 } from "citty";
|
|
1799
|
+
function parseSkillFormat(value) {
|
|
1800
|
+
const format = value ?? "both";
|
|
1801
|
+
if (!skillFormats.includes(format)) {
|
|
1802
|
+
exitUsage(`Unknown skill format "${format}". Use: codex, claude, both`);
|
|
1803
|
+
}
|
|
1804
|
+
return format;
|
|
1805
|
+
}
|
|
1806
|
+
var skillCommand = defineCommand9({
|
|
1807
|
+
meta: {
|
|
1808
|
+
name: "skill",
|
|
1809
|
+
description: "Install or refresh the bundled acta-document agent skill"
|
|
1810
|
+
},
|
|
1811
|
+
args: {
|
|
1812
|
+
init: {
|
|
1813
|
+
type: "boolean",
|
|
1814
|
+
description: "Install or overwrite the bundled acta-document skill",
|
|
1815
|
+
default: false
|
|
1816
|
+
},
|
|
1817
|
+
format: {
|
|
1818
|
+
type: "string",
|
|
1819
|
+
description: "Skill target format: codex | claude | both (default: both)"
|
|
1820
|
+
}
|
|
1821
|
+
},
|
|
1822
|
+
async run({ args }) {
|
|
1823
|
+
if (!args.init) {
|
|
1824
|
+
exitUsage("Usage: acta skill --init [--format codex|claude|both]");
|
|
1825
|
+
}
|
|
1826
|
+
const cwd = resolve4(process.cwd());
|
|
1827
|
+
const result = await installAgentSkill(cwd, parseSkillFormat(args.format));
|
|
1828
|
+
for (const skillPath of result.skillPaths) {
|
|
1829
|
+
printSuccess(`Installed ${skillPath}`);
|
|
1830
|
+
}
|
|
1831
|
+
if (result.agentsPath) {
|
|
1832
|
+
printSuccess(`Updated ${result.agentsPath} with Acta agent guidance`);
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
});
|
|
1836
|
+
|
|
1570
1837
|
// src/commands/validate.ts
|
|
1571
|
-
import { mkdir as
|
|
1572
|
-
import { join as
|
|
1838
|
+
import { mkdir as mkdir3, writeFile as writeFile5 } from "fs/promises";
|
|
1839
|
+
import { join as join8 } from "path";
|
|
1573
1840
|
import { validateLoadedProject } from "@acta-dev/core";
|
|
1574
|
-
import { defineCommand as
|
|
1841
|
+
import { defineCommand as defineCommand10 } from "citty";
|
|
1575
1842
|
import kleur7 from "kleur";
|
|
1576
|
-
var validateCommand =
|
|
1843
|
+
var validateCommand = defineCommand10({
|
|
1577
1844
|
meta: {
|
|
1578
1845
|
name: "validate",
|
|
1579
1846
|
description: "Validate frontmatter, IDs, links, sections and repository rules"
|
|
@@ -1604,9 +1871,9 @@ var validateCommand = defineCommand9({
|
|
|
1604
1871
|
return;
|
|
1605
1872
|
}
|
|
1606
1873
|
if (args.ci) {
|
|
1607
|
-
await
|
|
1608
|
-
const outPath =
|
|
1609
|
-
await
|
|
1874
|
+
await mkdir3(config.resolvedBuild.outDir, { recursive: true });
|
|
1875
|
+
const outPath = join8(config.resolvedBuild.outDir, "validation.json");
|
|
1876
|
+
await writeFile5(outPath, `${JSON.stringify(result, null, 2)}
|
|
1610
1877
|
`, "utf8");
|
|
1611
1878
|
if (result.errors.length > 0) {
|
|
1612
1879
|
for (const issue of result.errors) {
|
|
@@ -1643,7 +1910,7 @@ var validateCommand = defineCommand9({
|
|
|
1643
1910
|
});
|
|
1644
1911
|
|
|
1645
1912
|
// src/index.ts
|
|
1646
|
-
var main =
|
|
1913
|
+
var main = defineCommand11({
|
|
1647
1914
|
meta: {
|
|
1648
1915
|
name: "acta",
|
|
1649
1916
|
version: "0.0.0",
|
|
@@ -1658,6 +1925,7 @@ var main = defineCommand10({
|
|
|
1658
1925
|
graph: graphCommand,
|
|
1659
1926
|
build: buildCommand,
|
|
1660
1927
|
site: siteCommand,
|
|
1928
|
+
skill: skillCommand,
|
|
1661
1929
|
renumber: renumberCommand
|
|
1662
1930
|
}
|
|
1663
1931
|
});
|