argos-harness 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 +21 -0
- package/assets/agents/auditor.md +140 -0
- package/assets/agents/commit-pr-pilot.md +154 -0
- package/assets/agents/explorer.md +93 -0
- package/assets/agents/implementer.md +117 -0
- package/assets/agents/leader.md +149 -0
- package/assets/agents/researcher.md +89 -0
- package/assets/agents/review-readability.md +87 -0
- package/assets/agents/review-reliability.md +100 -0
- package/assets/agents/review-resilience.md +87 -0
- package/assets/agents/review-risk.md +87 -0
- package/assets/agents/reviewer.md +167 -0
- package/assets/agents/ticket-audit.md +129 -0
- package/assets/hooks/argos-guard-destructive.sh +127 -0
- package/assets/hooks/argos-quality-gate.sh +129 -0
- package/assets/managed/aterrizaje.md +24 -0
- package/assets/managed/formato-respuesta.md +21 -0
- package/assets/managed/identidad.md +48 -0
- package/assets/managed/operaciones-seguras.md +14 -0
- package/assets/managed/orquestacion.md +169 -0
- package/assets/output-styles/argos.md +71 -0
- package/assets/skills/ai-sdk-5/SKILL.md +230 -0
- package/assets/skills/angular/SKILL.md +19 -0
- package/assets/skills/angular/references/architecture.md +137 -0
- package/assets/skills/angular/references/core.md +197 -0
- package/assets/skills/angular/references/forms.md +115 -0
- package/assets/skills/angular/references/performance.md +124 -0
- package/assets/skills/apollo-client/SKILL.md +61 -0
- package/assets/skills/app-blueprint/SKILL.md +45 -0
- package/assets/skills/app-blueprint/assets/module-template.md +48 -0
- package/assets/skills/app-blueprint/assets/system-template.md +38 -0
- package/assets/skills/app-blueprint/references/workflow.md +101 -0
- package/assets/skills/app-builder/SKILL.md +43 -0
- package/assets/skills/app-builder/phases/0-product.md +58 -0
- package/assets/skills/app-builder/phases/1-scaffold.md +33 -0
- package/assets/skills/app-builder/phases/10-store.md +40 -0
- package/assets/skills/app-builder/phases/2-data.md +34 -0
- package/assets/skills/app-builder/phases/3-domain.md +33 -0
- package/assets/skills/app-builder/phases/4-ui-nav.md +32 -0
- package/assets/skills/app-builder/phases/5-identity.md +30 -0
- package/assets/skills/app-builder/phases/6-polish.md +34 -0
- package/assets/skills/app-builder/phases/7-brand.md +31 -0
- package/assets/skills/app-builder/phases/8-web.md +30 -0
- package/assets/skills/app-builder/phases/9-docs.md +31 -0
- package/assets/skills/app-ia/SKILL.md +54 -0
- package/assets/skills/astro/SKILL.md +39 -0
- package/assets/skills/axios/SKILL.md +61 -0
- package/assets/skills/branch-pr/SKILL.md +200 -0
- package/assets/skills/bullmq/SKILL.md +55 -0
- package/assets/skills/chained-pr/SKILL.md +48 -0
- package/assets/skills/chained-pr/references/chaining-details.md +99 -0
- package/assets/skills/cognitive-doc-design/SKILL.md +81 -0
- package/assets/skills/comment-writer/SKILL.md +74 -0
- package/assets/skills/dashboard-ia/SKILL.md +54 -0
- package/assets/skills/django-drf/SKILL.md +180 -0
- package/assets/skills/go-testing/SKILL.md +47 -0
- package/assets/skills/go-testing/references/examples.md +89 -0
- package/assets/skills/issue-creation/SKILL.md +223 -0
- package/assets/skills/jira-epic/SKILL.md +306 -0
- package/assets/skills/jira-task/SKILL.md +382 -0
- package/assets/skills/judgment-day/SKILL.md +52 -0
- package/assets/skills/judgment-day/references/prompts-and-formats.md +98 -0
- package/assets/skills/lightsail-deploy/SKILL.md +44 -0
- package/assets/skills/lightsail-deploy/references/runbook.md +102 -0
- package/assets/skills/loop-back-debug/SKILL.md +102 -0
- package/assets/skills/mantine-form/SKILL.md +57 -0
- package/assets/skills/mongoose/SKILL.md +66 -0
- package/assets/skills/nextjs-15/SKILL.md +144 -0
- package/assets/skills/not-boring-mobile/SKILL.md +43 -0
- package/assets/skills/not-boring-mobile/references/not-boring-playbook.md +65 -0
- package/assets/skills/playwright/SKILL.md +315 -0
- package/assets/skills/pr-comments/SKILL.md +93 -0
- package/assets/skills/pr-create/SKILL.md +64 -0
- package/assets/skills/promo-video/SKILL.md +52 -0
- package/assets/skills/promo-video/assets/package.template.json +22 -0
- package/assets/skills/promo-video/assets/promo.template.tsx +469 -0
- package/assets/skills/promo-video/assets/theme.template.ts +27 -0
- package/assets/skills/promo-video/references/pipeline.md +119 -0
- package/assets/skills/promo-video-web/SKILL.md +51 -0
- package/assets/skills/promo-video-web/assets/browser-promo.template.tsx +385 -0
- package/assets/skills/promo-video-web/assets/capture.template.ts +70 -0
- package/assets/skills/promo-video-web/assets/package.template.json +26 -0
- package/assets/skills/promo-video-web/references/pipeline.md +84 -0
- package/assets/skills/pytest/SKILL.md +180 -0
- package/assets/skills/react-19/SKILL.md +118 -0
- package/assets/skills/react-hook-form/SKILL.md +59 -0
- package/assets/skills/react-router/SKILL.md +60 -0
- package/assets/skills/redux-toolkit/SKILL.md +60 -0
- package/assets/skills/review-diff/SKILL.md +101 -0
- package/assets/skills/ship-docs/SKILL.md +45 -0
- package/assets/skills/ship-docs/references/ship-docs-playbook.md +31 -0
- package/assets/skills/skill-creator/SKILL.md +97 -0
- package/assets/skills/skill-creator/assets/SKILL-TEMPLATE.md +68 -0
- package/assets/skills/skill-creator/references/skill-style-guide.md +79 -0
- package/assets/skills/skill-improver/SKILL.md +50 -0
- package/assets/skills/skill-improver/references/skill-style-guide.md +79 -0
- package/assets/skills/socketio/SKILL.md +58 -0
- package/assets/skills/spec-bootstrap/SKILL.md +62 -0
- package/assets/skills/store-ship/SKILL.md +52 -0
- package/assets/skills/store-ship/assets/android-supply.template.md +22 -0
- package/assets/skills/store-ship/assets/eas.template.json +32 -0
- package/assets/skills/store-ship/assets/maestro-flow.template.yaml +27 -0
- package/assets/skills/store-ship/assets/store.config.template.json +28 -0
- package/assets/skills/store-ship/references/pipeline.md +198 -0
- package/assets/skills/stripe/SKILL.md +83 -0
- package/assets/skills/tailwind-4/SKILL.md +193 -0
- package/assets/skills/tamagui/SKILL.md +60 -0
- package/assets/skills/tanstack-query/SKILL.md +58 -0
- package/assets/skills/ticket-intake/SKILL.md +55 -0
- package/assets/skills/typescript/SKILL.md +134 -0
- package/assets/skills/verify-before-done/SKILL.md +111 -0
- package/assets/skills/webapp-rebuilder/SKILL.md +48 -0
- package/assets/skills/webapp-rebuilder/assets/charter-template.md +46 -0
- package/assets/skills/webapp-rebuilder/references/workflow.md +47 -0
- package/assets/skills/winston-logging/SKILL.md +61 -0
- package/assets/skills/work-unit-commits/SKILL.md +84 -0
- package/assets/skills/zod-4/SKILL.md +210 -0
- package/assets/skills/zustand-5/SKILL.md +216 -0
- package/bin/argos.js +6 -0
- package/dist/commands/adopt.d.ts +35 -0
- package/dist/commands/adopt.d.ts.map +1 -0
- package/dist/commands/adopt.js +347 -0
- package/dist/commands/adopt.js.map +1 -0
- package/dist/commands/doctor.d.ts +20 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +478 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +32 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +358 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/remove.d.ts +62 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +487 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/workspace.d.ts +73 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/commands/workspace.js +354 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/assets.d.ts +29 -0
- package/dist/lib/assets.d.ts.map +1 -0
- package/dist/lib/assets.js +57 -0
- package/dist/lib/assets.js.map +1 -0
- package/dist/lib/atomic-write.d.ts +17 -0
- package/dist/lib/atomic-write.d.ts.map +1 -0
- package/dist/lib/atomic-write.js +41 -0
- package/dist/lib/atomic-write.js.map +1 -0
- package/dist/lib/backup.d.ts +11 -0
- package/dist/lib/backup.d.ts.map +1 -0
- package/dist/lib/backup.js +42 -0
- package/dist/lib/backup.js.map +1 -0
- package/dist/lib/config.d.ts +36 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +52 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/detect.d.ts +58 -0
- package/dist/lib/detect.d.ts.map +1 -0
- package/dist/lib/detect.js +330 -0
- package/dist/lib/detect.js.map +1 -0
- package/dist/lib/ficha.d.ts +10 -0
- package/dist/lib/ficha.d.ts.map +1 -0
- package/dist/lib/ficha.js +38 -0
- package/dist/lib/ficha.js.map +1 -0
- package/dist/lib/git.d.ts +27 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +79 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/managed-files.d.ts +35 -0
- package/dist/lib/managed-files.d.ts.map +1 -0
- package/dist/lib/managed-files.js +97 -0
- package/dist/lib/managed-files.js.map +1 -0
- package/dist/lib/markers.d.ts +64 -0
- package/dist/lib/markers.d.ts.map +1 -0
- package/dist/lib/markers.js +157 -0
- package/dist/lib/markers.js.map +1 -0
- package/dist/lib/navori-import.d.ts +42 -0
- package/dist/lib/navori-import.d.ts.map +1 -0
- package/dist/lib/navori-import.js +65 -0
- package/dist/lib/navori-import.js.map +1 -0
- package/dist/lib/openclaw-agents.d.ts +53 -0
- package/dist/lib/openclaw-agents.d.ts.map +1 -0
- package/dist/lib/openclaw-agents.js +118 -0
- package/dist/lib/openclaw-agents.js.map +1 -0
- package/dist/lib/package-root.d.ts +11 -0
- package/dist/lib/package-root.d.ts.map +1 -0
- package/dist/lib/package-root.js +23 -0
- package/dist/lib/package-root.js.map +1 -0
- package/dist/lib/paths.d.ts +11 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +16 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/settings-merge.d.ts +125 -0
- package/dist/lib/settings-merge.d.ts.map +1 -0
- package/dist/lib/settings-merge.js +373 -0
- package/dist/lib/settings-merge.js.map +1 -0
- package/dist/lib/version.d.ts +3 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +13 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/lib/which.d.ts +8 -0
- package/dist/lib/which.d.ts.map +1 -0
- package/dist/lib/which.js +30 -0
- package/dist/lib/which.js.map +1 -0
- package/dist/lib/workspaces.d.ts +133 -0
- package/dist/lib/workspaces.d.ts.map +1 -0
- package/dist/lib/workspaces.js +241 -0
- package/dist/lib/workspaces.js.map +1 -0
- package/dist/lib/zod-messages.d.ts +4 -0
- package/dist/lib/zod-messages.d.ts.map +1 -0
- package/dist/lib/zod-messages.js +28 -0
- package/dist/lib/zod-messages.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { cpSync, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { resolveArgosHome } from "./paths.js";
|
|
5
|
+
/**
|
|
6
|
+
* Copy `entries` (files or directories, relative to `claudeDir`) into a
|
|
7
|
+
* timestamped backup directory under `<argos home>/backups/` before a
|
|
8
|
+
* destructive write. Missing entries are skipped silently — there is
|
|
9
|
+
* nothing to protect. Returns the backup directory path.
|
|
10
|
+
*
|
|
11
|
+
* The directory name carries a short random suffix alongside the ISO
|
|
12
|
+
* timestamp so two backups taken within the same millisecond never collide.
|
|
13
|
+
*/ export function createBackup(claudeDir, entries) {
|
|
14
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
15
|
+
const suffix = randomBytes(3).toString("hex");
|
|
16
|
+
const backupDir = join(resolveArgosHome(), "backups", `${timestamp}-${suffix}`);
|
|
17
|
+
mkdirSync(backupDir, {
|
|
18
|
+
recursive: true
|
|
19
|
+
});
|
|
20
|
+
try {
|
|
21
|
+
for (const entry of entries){
|
|
22
|
+
const src = join(claudeDir, entry);
|
|
23
|
+
if (!existsSync(src)) continue;
|
|
24
|
+
const dest = join(backupDir, entry);
|
|
25
|
+
mkdirSync(dirname(dest), {
|
|
26
|
+
recursive: true
|
|
27
|
+
});
|
|
28
|
+
cpSync(src, dest, {
|
|
29
|
+
recursive: true
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
} catch (error) {
|
|
33
|
+
rmSync(backupDir, {
|
|
34
|
+
recursive: true,
|
|
35
|
+
force: true
|
|
36
|
+
});
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
return backupDir;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/backup.ts"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { cpSync, existsSync, mkdirSync, rmSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { resolveArgosHome } from \"./paths.js\";\n\n/**\n * Copy `entries` (files or directories, relative to `claudeDir`) into a\n * timestamped backup directory under `<argos home>/backups/` before a\n * destructive write. Missing entries are skipped silently — there is\n * nothing to protect. Returns the backup directory path.\n *\n * The directory name carries a short random suffix alongside the ISO\n * timestamp so two backups taken within the same millisecond never collide.\n */\nexport function createBackup(claudeDir: string, entries: string[]): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const suffix = randomBytes(3).toString(\"hex\");\n const backupDir = join(resolveArgosHome(), \"backups\", `${timestamp}-${suffix}`);\n mkdirSync(backupDir, { recursive: true });\n\n try {\n for (const entry of entries) {\n const src = join(claudeDir, entry);\n if (!existsSync(src)) continue;\n const dest = join(backupDir, entry);\n mkdirSync(dirname(dest), { recursive: true });\n cpSync(src, dest, { recursive: true });\n }\n } catch (error) {\n rmSync(backupDir, { recursive: true, force: true });\n throw error;\n }\n\n return backupDir;\n}\n"],"names":["randomBytes","cpSync","existsSync","mkdirSync","rmSync","dirname","join","resolveArgosHome","createBackup","claudeDir","entries","timestamp","Date","toISOString","replace","suffix","toString","backupDir","recursive","entry","src","dest","error","force"],"mappings":"AAAA,SAASA,WAAW,QAAQ,cAAc;AAC1C,SAASC,MAAM,EAAEC,UAAU,EAAEC,SAAS,EAAEC,MAAM,QAAQ,UAAU;AAChE,SAASC,OAAO,EAAEC,IAAI,QAAQ,YAAY;AAC1C,SAASC,gBAAgB,QAAQ,aAAa;AAE9C;;;;;;;;CAQC,GACD,OAAO,SAASC,aAAaC,SAAiB,EAAEC,OAAiB;IAC/D,MAAMC,YAAY,IAAIC,OAAOC,WAAW,GAAGC,OAAO,CAAC,SAAS;IAC5D,MAAMC,SAASf,YAAY,GAAGgB,QAAQ,CAAC;IACvC,MAAMC,YAAYX,KAAKC,oBAAoB,WAAW,GAAGI,UAAU,CAAC,EAAEI,QAAQ;IAC9EZ,UAAUc,WAAW;QAAEC,WAAW;IAAK;IAEvC,IAAI;QACF,KAAK,MAAMC,SAAST,QAAS;YAC3B,MAAMU,MAAMd,KAAKG,WAAWU;YAC5B,IAAI,CAACjB,WAAWkB,MAAM;YACtB,MAAMC,OAAOf,KAAKW,WAAWE;YAC7BhB,UAAUE,QAAQgB,OAAO;gBAAEH,WAAW;YAAK;YAC3CjB,OAAOmB,KAAKC,MAAM;gBAAEH,WAAW;YAAK;QACtC;IACF,EAAE,OAAOI,OAAO;QACdlB,OAAOa,WAAW;YAAEC,WAAW;YAAMK,OAAO;QAAK;QACjD,MAAMD;IACR;IAEA,OAAOL;AACT"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const CONFIG_FILENAME = "argos.config.json";
|
|
3
|
+
export declare const ArgosConfigSchema: z.ZodObject<{
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
language: z.ZodDefault<z.ZodEnum<{
|
|
6
|
+
es: "es";
|
|
7
|
+
en: "en";
|
|
8
|
+
}>>;
|
|
9
|
+
workspace: z.ZodOptional<z.ZodString>;
|
|
10
|
+
branchBase: z.ZodDefault<z.ZodString>;
|
|
11
|
+
prTarget: z.ZodOptional<z.ZodString>;
|
|
12
|
+
qualityGate: z.ZodObject<{
|
|
13
|
+
fast: z.ZodString;
|
|
14
|
+
full: z.ZodOptional<z.ZodString>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
project: z.ZodDefault<z.ZodObject<{
|
|
17
|
+
criticalAreas: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
18
|
+
legacyPaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
19
|
+
}, z.core.$strip>>;
|
|
20
|
+
identity: z.ZodOptional<z.ZodString>;
|
|
21
|
+
stack: z.ZodOptional<z.ZodObject<{
|
|
22
|
+
framework: z.ZodOptional<z.ZodString>;
|
|
23
|
+
packageManager: z.ZodOptional<z.ZodString>;
|
|
24
|
+
libs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
25
|
+
}, z.core.$strip>>;
|
|
26
|
+
skills: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
27
|
+
}, z.core.$strip>;
|
|
28
|
+
export type ArgosConfig = z.infer<typeof ArgosConfigSchema>;
|
|
29
|
+
export type ArgosConfigInput = z.input<typeof ArgosConfigSchema>;
|
|
30
|
+
/** Read and validate `argos.config.json` from a repo directory. */
|
|
31
|
+
export declare function readConfig(repoDir: string): ArgosConfig;
|
|
32
|
+
/** Write `argos.config.json` to a repo directory (pretty JSON, trailing newline). */
|
|
33
|
+
export declare function writeConfig(repoDir: string, config: ArgosConfigInput): void;
|
|
34
|
+
/** True when `argos.config.json` exists in a repo directory. */
|
|
35
|
+
export declare function hasConfig(repoDir: string): boolean;
|
|
36
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,eAAe,sBAAsB,CAAC;AAkBnD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;iBAW5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEjE,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAKvD;AAED,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAI3E;AAED,gEAAgE;AAChE,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAElD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { writeFileAtomic } from "./atomic-write.js";
|
|
5
|
+
export const CONFIG_FILENAME = "argos.config.json";
|
|
6
|
+
const QualityGateSchema = z.object({
|
|
7
|
+
fast: z.string().min(1),
|
|
8
|
+
full: z.string().optional()
|
|
9
|
+
});
|
|
10
|
+
const ProjectSchema = z.object({
|
|
11
|
+
criticalAreas: z.array(z.string()).default([]),
|
|
12
|
+
legacyPaths: z.array(z.string()).default([])
|
|
13
|
+
});
|
|
14
|
+
const StackSchema = z.object({
|
|
15
|
+
framework: z.string().optional(),
|
|
16
|
+
packageManager: z.string().optional(),
|
|
17
|
+
libs: z.array(z.string()).default([])
|
|
18
|
+
});
|
|
19
|
+
export const ArgosConfigSchema = z.object({
|
|
20
|
+
name: z.string().min(1),
|
|
21
|
+
language: z.enum([
|
|
22
|
+
"es",
|
|
23
|
+
"en"
|
|
24
|
+
]).default("es"),
|
|
25
|
+
workspace: z.string().optional(),
|
|
26
|
+
branchBase: z.string().default("main"),
|
|
27
|
+
prTarget: z.string().optional(),
|
|
28
|
+
qualityGate: QualityGateSchema,
|
|
29
|
+
project: ProjectSchema.default({
|
|
30
|
+
criticalAreas: [],
|
|
31
|
+
legacyPaths: []
|
|
32
|
+
}),
|
|
33
|
+
identity: z.string().optional(),
|
|
34
|
+
stack: StackSchema.optional(),
|
|
35
|
+
skills: z.array(z.string()).default([])
|
|
36
|
+
});
|
|
37
|
+
/** Read and validate `argos.config.json` from a repo directory. */ export function readConfig(repoDir) {
|
|
38
|
+
const configPath = join(repoDir, CONFIG_FILENAME);
|
|
39
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
40
|
+
const parsed = JSON.parse(raw);
|
|
41
|
+
return ArgosConfigSchema.parse(parsed);
|
|
42
|
+
}
|
|
43
|
+
/** Write `argos.config.json` to a repo directory (pretty JSON, trailing newline). */ export function writeConfig(repoDir, config) {
|
|
44
|
+
const validated = ArgosConfigSchema.parse(config);
|
|
45
|
+
const configPath = join(repoDir, CONFIG_FILENAME);
|
|
46
|
+
writeFileAtomic(configPath, `${JSON.stringify(validated, null, 2)}\n`);
|
|
47
|
+
}
|
|
48
|
+
/** True when `argos.config.json` exists in a repo directory. */ export function hasConfig(repoDir) {
|
|
49
|
+
return existsSync(join(repoDir, CONFIG_FILENAME));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/config.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport { writeFileAtomic } from \"./atomic-write.js\";\n\nexport const CONFIG_FILENAME = \"argos.config.json\";\n\nconst QualityGateSchema = z.object({\n fast: z.string().min(1),\n full: z.string().optional(),\n});\n\nconst ProjectSchema = z.object({\n criticalAreas: z.array(z.string()).default([]),\n legacyPaths: z.array(z.string()).default([]),\n});\n\nconst StackSchema = z.object({\n framework: z.string().optional(),\n packageManager: z.string().optional(),\n libs: z.array(z.string()).default([]),\n});\n\nexport const ArgosConfigSchema = z.object({\n name: z.string().min(1),\n language: z.enum([\"es\", \"en\"]).default(\"es\"),\n workspace: z.string().optional(),\n branchBase: z.string().default(\"main\"),\n prTarget: z.string().optional(),\n qualityGate: QualityGateSchema,\n project: ProjectSchema.default({ criticalAreas: [], legacyPaths: [] }),\n identity: z.string().optional(),\n stack: StackSchema.optional(),\n skills: z.array(z.string()).default([]),\n});\n\nexport type ArgosConfig = z.infer<typeof ArgosConfigSchema>;\nexport type ArgosConfigInput = z.input<typeof ArgosConfigSchema>;\n\n/** Read and validate `argos.config.json` from a repo directory. */\nexport function readConfig(repoDir: string): ArgosConfig {\n const configPath = join(repoDir, CONFIG_FILENAME);\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed: unknown = JSON.parse(raw);\n return ArgosConfigSchema.parse(parsed);\n}\n\n/** Write `argos.config.json` to a repo directory (pretty JSON, trailing newline). */\nexport function writeConfig(repoDir: string, config: ArgosConfigInput): void {\n const validated = ArgosConfigSchema.parse(config);\n const configPath = join(repoDir, CONFIG_FILENAME);\n writeFileAtomic(configPath, `${JSON.stringify(validated, null, 2)}\\n`);\n}\n\n/** True when `argos.config.json` exists in a repo directory. */\nexport function hasConfig(repoDir: string): boolean {\n return existsSync(join(repoDir, CONFIG_FILENAME));\n}\n"],"names":["existsSync","readFileSync","join","z","writeFileAtomic","CONFIG_FILENAME","QualityGateSchema","object","fast","string","min","full","optional","ProjectSchema","criticalAreas","array","default","legacyPaths","StackSchema","framework","packageManager","libs","ArgosConfigSchema","name","language","enum","workspace","branchBase","prTarget","qualityGate","project","identity","stack","skills","readConfig","repoDir","configPath","raw","parsed","JSON","parse","writeConfig","config","validated","stringify","hasConfig"],"mappings":"AAAA,SAASA,UAAU,EAAEC,YAAY,QAAQ,UAAU;AACnD,SAASC,IAAI,QAAQ,YAAY;AACjC,SAASC,CAAC,QAAQ,MAAM;AACxB,SAASC,eAAe,QAAQ,oBAAoB;AAEpD,OAAO,MAAMC,kBAAkB,oBAAoB;AAEnD,MAAMC,oBAAoBH,EAAEI,MAAM,CAAC;IACjCC,MAAML,EAAEM,MAAM,GAAGC,GAAG,CAAC;IACrBC,MAAMR,EAAEM,MAAM,GAAGG,QAAQ;AAC3B;AAEA,MAAMC,gBAAgBV,EAAEI,MAAM,CAAC;IAC7BO,eAAeX,EAAEY,KAAK,CAACZ,EAAEM,MAAM,IAAIO,OAAO,CAAC,EAAE;IAC7CC,aAAad,EAAEY,KAAK,CAACZ,EAAEM,MAAM,IAAIO,OAAO,CAAC,EAAE;AAC7C;AAEA,MAAME,cAAcf,EAAEI,MAAM,CAAC;IAC3BY,WAAWhB,EAAEM,MAAM,GAAGG,QAAQ;IAC9BQ,gBAAgBjB,EAAEM,MAAM,GAAGG,QAAQ;IACnCS,MAAMlB,EAAEY,KAAK,CAACZ,EAAEM,MAAM,IAAIO,OAAO,CAAC,EAAE;AACtC;AAEA,OAAO,MAAMM,oBAAoBnB,EAAEI,MAAM,CAAC;IACxCgB,MAAMpB,EAAEM,MAAM,GAAGC,GAAG,CAAC;IACrBc,UAAUrB,EAAEsB,IAAI,CAAC;QAAC;QAAM;KAAK,EAAET,OAAO,CAAC;IACvCU,WAAWvB,EAAEM,MAAM,GAAGG,QAAQ;IAC9Be,YAAYxB,EAAEM,MAAM,GAAGO,OAAO,CAAC;IAC/BY,UAAUzB,EAAEM,MAAM,GAAGG,QAAQ;IAC7BiB,aAAavB;IACbwB,SAASjB,cAAcG,OAAO,CAAC;QAAEF,eAAe,EAAE;QAAEG,aAAa,EAAE;IAAC;IACpEc,UAAU5B,EAAEM,MAAM,GAAGG,QAAQ;IAC7BoB,OAAOd,YAAYN,QAAQ;IAC3BqB,QAAQ9B,EAAEY,KAAK,CAACZ,EAAEM,MAAM,IAAIO,OAAO,CAAC,EAAE;AACxC,GAAG;AAKH,iEAAiE,GACjE,OAAO,SAASkB,WAAWC,OAAe;IACxC,MAAMC,aAAalC,KAAKiC,SAAS9B;IACjC,MAAMgC,MAAMpC,aAAamC,YAAY;IACrC,MAAME,SAAkBC,KAAKC,KAAK,CAACH;IACnC,OAAOf,kBAAkBkB,KAAK,CAACF;AACjC;AAEA,mFAAmF,GACnF,OAAO,SAASG,YAAYN,OAAe,EAAEO,MAAwB;IACnE,MAAMC,YAAYrB,kBAAkBkB,KAAK,CAACE;IAC1C,MAAMN,aAAalC,KAAKiC,SAAS9B;IACjCD,gBAAgBgC,YAAY,GAAGG,KAAKK,SAAS,CAACD,WAAW,MAAM,GAAG,EAAE,CAAC;AACvE;AAEA,8DAA8D,GAC9D,OAAO,SAASE,UAAUV,OAAe;IACvC,OAAOnC,WAAWE,KAAKiC,SAAS9B;AAClC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export interface PackageJsonShape {
|
|
2
|
+
name?: string;
|
|
3
|
+
scripts?: Record<string, string>;
|
|
4
|
+
dependencies?: Record<string, string>;
|
|
5
|
+
devDependencies?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
/** Read and JSON-parse `package.json` from `dir`, or null if absent/invalid. */
|
|
8
|
+
export declare function readPackageJson(dir: string): PackageJsonShape | null;
|
|
9
|
+
/** Detect the package manager from lockfile presence in `dir`. */
|
|
10
|
+
export declare function detectPackageManager(dir: string): string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Ordered framework detectors — first dependency match wins. Kept as a
|
|
13
|
+
* simple array so adding a new framework is a one-line change.
|
|
14
|
+
*/
|
|
15
|
+
export declare const FRAMEWORK_DETECTORS: ReadonlyArray<{
|
|
16
|
+
id: string;
|
|
17
|
+
deps: readonly string[];
|
|
18
|
+
}>;
|
|
19
|
+
/** Detect the framework from `package.json` deps, in FRAMEWORK_DETECTORS order. */
|
|
20
|
+
export declare function detectFramework(pkg: PackageJsonShape): string | undefined;
|
|
21
|
+
/** Small, extensible list of libs worth recording in `argos.config.json`. */
|
|
22
|
+
export declare const KNOWN_LIBS: readonly string[];
|
|
23
|
+
/** Intersection of `package.json` deps with KNOWN_LIBS. */
|
|
24
|
+
export declare function detectLibs(pkg: PackageJsonShape): string[];
|
|
25
|
+
/**
|
|
26
|
+
* Build the "fast" quality-gate command from whichever of lint/typecheck/test
|
|
27
|
+
* scripts actually exist in `package.json`. Returns "" when none exist —
|
|
28
|
+
* callers should surface a warning in that case.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildQualityGateFast(pkg: PackageJsonShape, packageManager: string): string;
|
|
31
|
+
/** The 4 motor skills every repo gets in F1 — hardcoded pending dynamic detection. */
|
|
32
|
+
export declare const MOTOR_SKILLS: readonly string[];
|
|
33
|
+
/**
|
|
34
|
+
* Ordered `package.json` dependency → motor skill id(s) map, checked in this
|
|
35
|
+
* order and evaluated against `deps ∪ devDeps`. Every entry is independent
|
|
36
|
+
* and additive except the `react` entry: it's skipped when `next` is also
|
|
37
|
+
* present, since `next`'s entry already includes `react-19` — this mirrors
|
|
38
|
+
* the same precedence `FRAMEWORK_DETECTORS` uses for next-over-react.
|
|
39
|
+
*
|
|
40
|
+
* Deliberately NOT mapped:
|
|
41
|
+
* - `expo` / `react-native` → `not-boring-mobile` is a visual/interaction
|
|
42
|
+
* style choice, not something to infer from a dependency being present.
|
|
43
|
+
* - Python stacks (Django REST Framework, pytest) and Go testing have no
|
|
44
|
+
* entry here — F-now detection is `package.json`-only, so those skills
|
|
45
|
+
* stay trigger-available (installed in the skill catalog) but are never
|
|
46
|
+
* auto-mapped from a repo's manifest.
|
|
47
|
+
*/
|
|
48
|
+
export declare const DEP_SKILL_MAP: ReadonlyArray<{
|
|
49
|
+
dep: string;
|
|
50
|
+
skills: readonly string[];
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Map `package.json` deps to motor skill ids via `DEP_SKILL_MAP`, deduped
|
|
54
|
+
* and in stable (map declaration) order. Used by `adopt` to extend the
|
|
55
|
+
* config's `skills` field beyond the always-on `MOTOR_SKILLS`.
|
|
56
|
+
*/
|
|
57
|
+
export declare function detectMappedSkills(pkg: PackageJsonShape): string[];
|
|
58
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/lib/detect.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAQpE;AAcD,kEAAkE;AAClE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKpE;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAOtF,CAAC;AAEF,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAMzE;AAED,6EAA6E;AAC7E,eAAO,MAAM,UAAU,EAAE,SAAS,MAAM,EASvC,CAAC;AAEF,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAG1D;AAmBD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAK1F;AAED,sFAAsF;AACtF,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAKzC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CA2BnF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAYlE"}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/** Read and JSON-parse `package.json` from `dir`, or null if absent/invalid. */ export function readPackageJson(dir) {
|
|
4
|
+
const path = join(dir, "package.json");
|
|
5
|
+
if (!existsSync(path)) return null;
|
|
6
|
+
try {
|
|
7
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
8
|
+
} catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function allDeps(pkg) {
|
|
13
|
+
return {
|
|
14
|
+
...pkg.dependencies,
|
|
15
|
+
...pkg.devDependencies
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Lockfile basename → packageManager id, checked in this preference order. */ const LOCKFILES = [
|
|
19
|
+
{
|
|
20
|
+
file: "pnpm-lock.yaml",
|
|
21
|
+
packageManager: "pnpm"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
file: "yarn.lock",
|
|
25
|
+
packageManager: "yarn"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
file: "package-lock.json",
|
|
29
|
+
packageManager: "npm"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
file: "bun.lockb",
|
|
33
|
+
packageManager: "bun"
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
/** Detect the package manager from lockfile presence in `dir`. */ export function detectPackageManager(dir) {
|
|
37
|
+
for (const { file, packageManager } of LOCKFILES){
|
|
38
|
+
if (existsSync(join(dir, file))) return packageManager;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Ordered framework detectors — first dependency match wins. Kept as a
|
|
44
|
+
* simple array so adding a new framework is a one-line change.
|
|
45
|
+
*/ export const FRAMEWORK_DETECTORS = [
|
|
46
|
+
{
|
|
47
|
+
id: "next",
|
|
48
|
+
deps: [
|
|
49
|
+
"next"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "react",
|
|
54
|
+
deps: [
|
|
55
|
+
"react"
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "react-native",
|
|
60
|
+
deps: [
|
|
61
|
+
"react-native",
|
|
62
|
+
"expo"
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "express",
|
|
67
|
+
deps: [
|
|
68
|
+
"express"
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: "nestjs",
|
|
73
|
+
deps: [
|
|
74
|
+
"@nestjs/core",
|
|
75
|
+
"nestjs"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "astro",
|
|
80
|
+
deps: [
|
|
81
|
+
"astro"
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
];
|
|
85
|
+
/** Detect the framework from `package.json` deps, in FRAMEWORK_DETECTORS order. */ export function detectFramework(pkg) {
|
|
86
|
+
const deps = allDeps(pkg);
|
|
87
|
+
for (const detector of FRAMEWORK_DETECTORS){
|
|
88
|
+
if (detector.deps.some((dep)=>dep in deps)) return detector.id;
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
/** Small, extensible list of libs worth recording in `argos.config.json`. */ export const KNOWN_LIBS = [
|
|
93
|
+
"axios",
|
|
94
|
+
"zod",
|
|
95
|
+
"react-hook-form",
|
|
96
|
+
"@tanstack/react-query",
|
|
97
|
+
"zustand",
|
|
98
|
+
"mongoose",
|
|
99
|
+
"socket.io",
|
|
100
|
+
"stripe"
|
|
101
|
+
];
|
|
102
|
+
/** Intersection of `package.json` deps with KNOWN_LIBS. */ export function detectLibs(pkg) {
|
|
103
|
+
const deps = allDeps(pkg);
|
|
104
|
+
return KNOWN_LIBS.filter((lib)=>lib in deps);
|
|
105
|
+
}
|
|
106
|
+
/** Candidate quality-gate scripts, checked/joined in this order when present. */ const GATE_SCRIPTS = [
|
|
107
|
+
"lint",
|
|
108
|
+
"typecheck",
|
|
109
|
+
"test"
|
|
110
|
+
];
|
|
111
|
+
/** Render `pm run script` in the idiom of each package manager. */ function runScript(packageManager, script) {
|
|
112
|
+
switch(packageManager){
|
|
113
|
+
case "pnpm":
|
|
114
|
+
return `pnpm ${script}`;
|
|
115
|
+
case "yarn":
|
|
116
|
+
return `yarn ${script}`;
|
|
117
|
+
case "bun":
|
|
118
|
+
return `bun run ${script}`;
|
|
119
|
+
default:
|
|
120
|
+
return `npm run ${script}`;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Build the "fast" quality-gate command from whichever of lint/typecheck/test
|
|
125
|
+
* scripts actually exist in `package.json`. Returns "" when none exist —
|
|
126
|
+
* callers should surface a warning in that case.
|
|
127
|
+
*/ export function buildQualityGateFast(pkg, packageManager) {
|
|
128
|
+
const scripts = pkg.scripts ?? {};
|
|
129
|
+
const present = GATE_SCRIPTS.filter((s)=>s in scripts);
|
|
130
|
+
if (present.length === 0) return "";
|
|
131
|
+
return present.map((s)=>runScript(packageManager, s)).join(" && ");
|
|
132
|
+
}
|
|
133
|
+
/** The 4 motor skills every repo gets in F1 — hardcoded pending dynamic detection. */ export const MOTOR_SKILLS = [
|
|
134
|
+
"verify-before-done",
|
|
135
|
+
"review-diff",
|
|
136
|
+
"pr-create",
|
|
137
|
+
"loop-back-debug"
|
|
138
|
+
];
|
|
139
|
+
/**
|
|
140
|
+
* Ordered `package.json` dependency → motor skill id(s) map, checked in this
|
|
141
|
+
* order and evaluated against `deps ∪ devDeps`. Every entry is independent
|
|
142
|
+
* and additive except the `react` entry: it's skipped when `next` is also
|
|
143
|
+
* present, since `next`'s entry already includes `react-19` — this mirrors
|
|
144
|
+
* the same precedence `FRAMEWORK_DETECTORS` uses for next-over-react.
|
|
145
|
+
*
|
|
146
|
+
* Deliberately NOT mapped:
|
|
147
|
+
* - `expo` / `react-native` → `not-boring-mobile` is a visual/interaction
|
|
148
|
+
* style choice, not something to infer from a dependency being present.
|
|
149
|
+
* - Python stacks (Django REST Framework, pytest) and Go testing have no
|
|
150
|
+
* entry here — F-now detection is `package.json`-only, so those skills
|
|
151
|
+
* stay trigger-available (installed in the skill catalog) but are never
|
|
152
|
+
* auto-mapped from a repo's manifest.
|
|
153
|
+
*/ export const DEP_SKILL_MAP = [
|
|
154
|
+
{
|
|
155
|
+
dep: "next",
|
|
156
|
+
skills: [
|
|
157
|
+
"nextjs-15",
|
|
158
|
+
"react-19"
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
dep: "react",
|
|
163
|
+
skills: [
|
|
164
|
+
"react-19"
|
|
165
|
+
]
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
dep: "typescript",
|
|
169
|
+
skills: [
|
|
170
|
+
"typescript"
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
dep: "tailwindcss",
|
|
175
|
+
skills: [
|
|
176
|
+
"tailwind-4"
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
dep: "zod",
|
|
181
|
+
skills: [
|
|
182
|
+
"zod-4"
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
dep: "zustand",
|
|
187
|
+
skills: [
|
|
188
|
+
"zustand-5"
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
dep: "axios",
|
|
193
|
+
skills: [
|
|
194
|
+
"axios"
|
|
195
|
+
]
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
dep: "@tanstack/react-query",
|
|
199
|
+
skills: [
|
|
200
|
+
"tanstack-query"
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
dep: "mongoose",
|
|
205
|
+
skills: [
|
|
206
|
+
"mongoose"
|
|
207
|
+
]
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
dep: "react-hook-form",
|
|
211
|
+
skills: [
|
|
212
|
+
"react-hook-form"
|
|
213
|
+
]
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
dep: "@apollo/client",
|
|
217
|
+
skills: [
|
|
218
|
+
"apollo-client"
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
dep: "bullmq",
|
|
223
|
+
skills: [
|
|
224
|
+
"bullmq"
|
|
225
|
+
]
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
dep: "@mantine/form",
|
|
229
|
+
skills: [
|
|
230
|
+
"mantine-form"
|
|
231
|
+
]
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
dep: "react-router",
|
|
235
|
+
skills: [
|
|
236
|
+
"react-router"
|
|
237
|
+
]
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
dep: "react-router-dom",
|
|
241
|
+
skills: [
|
|
242
|
+
"react-router"
|
|
243
|
+
]
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
dep: "@reduxjs/toolkit",
|
|
247
|
+
skills: [
|
|
248
|
+
"redux-toolkit"
|
|
249
|
+
]
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
dep: "socket.io",
|
|
253
|
+
skills: [
|
|
254
|
+
"socketio"
|
|
255
|
+
]
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
dep: "socket.io-client",
|
|
259
|
+
skills: [
|
|
260
|
+
"socketio"
|
|
261
|
+
]
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
dep: "stripe",
|
|
265
|
+
skills: [
|
|
266
|
+
"stripe"
|
|
267
|
+
]
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
dep: "tamagui",
|
|
271
|
+
skills: [
|
|
272
|
+
"tamagui"
|
|
273
|
+
]
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
dep: "@tamagui/core",
|
|
277
|
+
skills: [
|
|
278
|
+
"tamagui"
|
|
279
|
+
]
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
dep: "winston",
|
|
283
|
+
skills: [
|
|
284
|
+
"winston-logging"
|
|
285
|
+
]
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
dep: "@playwright/test",
|
|
289
|
+
skills: [
|
|
290
|
+
"playwright"
|
|
291
|
+
]
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
dep: "astro",
|
|
295
|
+
skills: [
|
|
296
|
+
"astro"
|
|
297
|
+
]
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
dep: "@angular/core",
|
|
301
|
+
skills: [
|
|
302
|
+
"angular"
|
|
303
|
+
]
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
dep: "ai",
|
|
307
|
+
skills: [
|
|
308
|
+
"ai-sdk-5"
|
|
309
|
+
]
|
|
310
|
+
}
|
|
311
|
+
];
|
|
312
|
+
/**
|
|
313
|
+
* Map `package.json` deps to motor skill ids via `DEP_SKILL_MAP`, deduped
|
|
314
|
+
* and in stable (map declaration) order. Used by `adopt` to extend the
|
|
315
|
+
* config's `skills` field beyond the always-on `MOTOR_SKILLS`.
|
|
316
|
+
*/ export function detectMappedSkills(pkg) {
|
|
317
|
+
const deps = allDeps(pkg);
|
|
318
|
+
const hasNext = "next" in deps;
|
|
319
|
+
const result = [];
|
|
320
|
+
for (const { dep, skills } of DEP_SKILL_MAP){
|
|
321
|
+
if (dep === "react" && hasNext) continue; // covered by the `next` entry already
|
|
322
|
+
if (!(dep in deps)) continue;
|
|
323
|
+
for (const id of skills){
|
|
324
|
+
if (!result.includes(id)) result.push(id);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return result;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/detect.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface PackageJsonShape {\n name?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n}\n\n/** Read and JSON-parse `package.json` from `dir`, or null if absent/invalid. */\nexport function readPackageJson(dir: string): PackageJsonShape | null {\n const path = join(dir, \"package.json\");\n if (!existsSync(path)) return null;\n try {\n return JSON.parse(readFileSync(path, \"utf-8\")) as PackageJsonShape;\n } catch {\n return null;\n }\n}\n\nfunction allDeps(pkg: PackageJsonShape): Record<string, string> {\n return { ...pkg.dependencies, ...pkg.devDependencies };\n}\n\n/** Lockfile basename → packageManager id, checked in this preference order. */\nconst LOCKFILES: Array<{ file: string; packageManager: string }> = [\n { file: \"pnpm-lock.yaml\", packageManager: \"pnpm\" },\n { file: \"yarn.lock\", packageManager: \"yarn\" },\n { file: \"package-lock.json\", packageManager: \"npm\" },\n { file: \"bun.lockb\", packageManager: \"bun\" },\n];\n\n/** Detect the package manager from lockfile presence in `dir`. */\nexport function detectPackageManager(dir: string): string | undefined {\n for (const { file, packageManager } of LOCKFILES) {\n if (existsSync(join(dir, file))) return packageManager;\n }\n return undefined;\n}\n\n/**\n * Ordered framework detectors — first dependency match wins. Kept as a\n * simple array so adding a new framework is a one-line change.\n */\nexport const FRAMEWORK_DETECTORS: ReadonlyArray<{ id: string; deps: readonly string[] }> = [\n { id: \"next\", deps: [\"next\"] },\n { id: \"react\", deps: [\"react\"] },\n { id: \"react-native\", deps: [\"react-native\", \"expo\"] },\n { id: \"express\", deps: [\"express\"] },\n { id: \"nestjs\", deps: [\"@nestjs/core\", \"nestjs\"] },\n { id: \"astro\", deps: [\"astro\"] },\n];\n\n/** Detect the framework from `package.json` deps, in FRAMEWORK_DETECTORS order. */\nexport function detectFramework(pkg: PackageJsonShape): string | undefined {\n const deps = allDeps(pkg);\n for (const detector of FRAMEWORK_DETECTORS) {\n if (detector.deps.some((dep) => dep in deps)) return detector.id;\n }\n return undefined;\n}\n\n/** Small, extensible list of libs worth recording in `argos.config.json`. */\nexport const KNOWN_LIBS: readonly string[] = [\n \"axios\",\n \"zod\",\n \"react-hook-form\",\n \"@tanstack/react-query\",\n \"zustand\",\n \"mongoose\",\n \"socket.io\",\n \"stripe\",\n];\n\n/** Intersection of `package.json` deps with KNOWN_LIBS. */\nexport function detectLibs(pkg: PackageJsonShape): string[] {\n const deps = allDeps(pkg);\n return KNOWN_LIBS.filter((lib) => lib in deps);\n}\n\n/** Candidate quality-gate scripts, checked/joined in this order when present. */\nconst GATE_SCRIPTS = [\"lint\", \"typecheck\", \"test\"] as const;\n\n/** Render `pm run script` in the idiom of each package manager. */\nfunction runScript(packageManager: string, script: string): string {\n switch (packageManager) {\n case \"pnpm\":\n return `pnpm ${script}`;\n case \"yarn\":\n return `yarn ${script}`;\n case \"bun\":\n return `bun run ${script}`;\n default:\n return `npm run ${script}`;\n }\n}\n\n/**\n * Build the \"fast\" quality-gate command from whichever of lint/typecheck/test\n * scripts actually exist in `package.json`. Returns \"\" when none exist —\n * callers should surface a warning in that case.\n */\nexport function buildQualityGateFast(pkg: PackageJsonShape, packageManager: string): string {\n const scripts = pkg.scripts ?? {};\n const present = GATE_SCRIPTS.filter((s) => s in scripts);\n if (present.length === 0) return \"\";\n return present.map((s) => runScript(packageManager, s)).join(\" && \");\n}\n\n/** The 4 motor skills every repo gets in F1 — hardcoded pending dynamic detection. */\nexport const MOTOR_SKILLS: readonly string[] = [\n \"verify-before-done\",\n \"review-diff\",\n \"pr-create\",\n \"loop-back-debug\",\n];\n\n/**\n * Ordered `package.json` dependency → motor skill id(s) map, checked in this\n * order and evaluated against `deps ∪ devDeps`. Every entry is independent\n * and additive except the `react` entry: it's skipped when `next` is also\n * present, since `next`'s entry already includes `react-19` — this mirrors\n * the same precedence `FRAMEWORK_DETECTORS` uses for next-over-react.\n *\n * Deliberately NOT mapped:\n * - `expo` / `react-native` → `not-boring-mobile` is a visual/interaction\n * style choice, not something to infer from a dependency being present.\n * - Python stacks (Django REST Framework, pytest) and Go testing have no\n * entry here — F-now detection is `package.json`-only, so those skills\n * stay trigger-available (installed in the skill catalog) but are never\n * auto-mapped from a repo's manifest.\n */\nexport const DEP_SKILL_MAP: ReadonlyArray<{ dep: string; skills: readonly string[] }> = [\n { dep: \"next\", skills: [\"nextjs-15\", \"react-19\"] },\n { dep: \"react\", skills: [\"react-19\"] },\n { dep: \"typescript\", skills: [\"typescript\"] },\n { dep: \"tailwindcss\", skills: [\"tailwind-4\"] },\n { dep: \"zod\", skills: [\"zod-4\"] },\n { dep: \"zustand\", skills: [\"zustand-5\"] },\n { dep: \"axios\", skills: [\"axios\"] },\n { dep: \"@tanstack/react-query\", skills: [\"tanstack-query\"] },\n { dep: \"mongoose\", skills: [\"mongoose\"] },\n { dep: \"react-hook-form\", skills: [\"react-hook-form\"] },\n { dep: \"@apollo/client\", skills: [\"apollo-client\"] },\n { dep: \"bullmq\", skills: [\"bullmq\"] },\n { dep: \"@mantine/form\", skills: [\"mantine-form\"] },\n { dep: \"react-router\", skills: [\"react-router\"] },\n { dep: \"react-router-dom\", skills: [\"react-router\"] },\n { dep: \"@reduxjs/toolkit\", skills: [\"redux-toolkit\"] },\n { dep: \"socket.io\", skills: [\"socketio\"] },\n { dep: \"socket.io-client\", skills: [\"socketio\"] },\n { dep: \"stripe\", skills: [\"stripe\"] },\n { dep: \"tamagui\", skills: [\"tamagui\"] },\n { dep: \"@tamagui/core\", skills: [\"tamagui\"] },\n { dep: \"winston\", skills: [\"winston-logging\"] },\n { dep: \"@playwright/test\", skills: [\"playwright\"] },\n { dep: \"astro\", skills: [\"astro\"] },\n { dep: \"@angular/core\", skills: [\"angular\"] },\n { dep: \"ai\", skills: [\"ai-sdk-5\"] },\n];\n\n/**\n * Map `package.json` deps to motor skill ids via `DEP_SKILL_MAP`, deduped\n * and in stable (map declaration) order. Used by `adopt` to extend the\n * config's `skills` field beyond the always-on `MOTOR_SKILLS`.\n */\nexport function detectMappedSkills(pkg: PackageJsonShape): string[] {\n const deps = allDeps(pkg);\n const hasNext = \"next\" in deps;\n const result: string[] = [];\n for (const { dep, skills } of DEP_SKILL_MAP) {\n if (dep === \"react\" && hasNext) continue; // covered by the `next` entry already\n if (!(dep in deps)) continue;\n for (const id of skills) {\n if (!result.includes(id)) result.push(id);\n }\n }\n return result;\n}\n"],"names":["existsSync","readFileSync","join","readPackageJson","dir","path","JSON","parse","allDeps","pkg","dependencies","devDependencies","LOCKFILES","file","packageManager","detectPackageManager","undefined","FRAMEWORK_DETECTORS","id","deps","detectFramework","detector","some","dep","KNOWN_LIBS","detectLibs","filter","lib","GATE_SCRIPTS","runScript","script","buildQualityGateFast","scripts","present","s","length","map","MOTOR_SKILLS","DEP_SKILL_MAP","skills","detectMappedSkills","hasNext","result","includes","push"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ArgosConfig } from "./config.js";
|
|
2
|
+
export declare const FICHA_BLOCK_ID = "ficha";
|
|
3
|
+
/**
|
|
4
|
+
* Render the repo ficha content (the ~10 lines injected into `./CLAUDE.md`
|
|
5
|
+
* under the `ficha` managed block) from the current `argos.config.json`.
|
|
6
|
+
* Shared by `adopt` (writes it) and `doctor` (checks it for drift) so both
|
|
7
|
+
* always agree on what "up to date" means.
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildFichaContent(config: ArgosConfig): string;
|
|
10
|
+
//# sourceMappingURL=ficha.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ficha.d.ts","sourceRoot":"","sources":["../../src/lib/ficha.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CA6B7D"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const FICHA_BLOCK_ID = "ficha";
|
|
2
|
+
/**
|
|
3
|
+
* Render the repo ficha content (the ~10 lines injected into `./CLAUDE.md`
|
|
4
|
+
* under the `ficha` managed block) from the current `argos.config.json`.
|
|
5
|
+
* Shared by `adopt` (writes it) and `doctor` (checks it for drift) so both
|
|
6
|
+
* always agree on what "up to date" means.
|
|
7
|
+
*/ export function buildFichaContent(config) {
|
|
8
|
+
const lines = [
|
|
9
|
+
`## Ficha del repo: ${config.name}`,
|
|
10
|
+
""
|
|
11
|
+
];
|
|
12
|
+
const gate = config.qualityGate.full ? `${config.qualityGate.fast} (full: ${config.qualityGate.full})` : config.qualityGate.fast;
|
|
13
|
+
lines.push(`- Quality gate fast: \`${gate}\``);
|
|
14
|
+
lines.push(`- Rama base: \`${config.branchBase}\``);
|
|
15
|
+
lines.push(`- Workspace: ${config.workspace ?? "sin asignar"}`);
|
|
16
|
+
const criticalAreas = config.project.criticalAreas;
|
|
17
|
+
const legacyPaths = config.project.legacyPaths;
|
|
18
|
+
if (criticalAreas.length > 0 || legacyPaths.length > 0) {
|
|
19
|
+
const areas = [
|
|
20
|
+
...criticalAreas,
|
|
21
|
+
...legacyPaths
|
|
22
|
+
];
|
|
23
|
+
lines.push(`- Áreas críticas: ${areas.join(", ")}`);
|
|
24
|
+
}
|
|
25
|
+
// Above ~6 skills a single comma-joined line gets unbounded (289 chars
|
|
26
|
+
// observed with 18 libs) — wrap as indented sub-lines instead.
|
|
27
|
+
if (config.skills.length > 6) {
|
|
28
|
+
lines.push("- Skills aplicables:");
|
|
29
|
+
for (const skill of config.skills)lines.push(` - ${skill}`);
|
|
30
|
+
} else {
|
|
31
|
+
lines.push(`- Skills aplicables: ${config.skills.join(", ")}`);
|
|
32
|
+
}
|
|
33
|
+
lines.push("");
|
|
34
|
+
lines.push("Datos de argos.config.json — regenerar con `argos adopt --refresh`.");
|
|
35
|
+
return lines.join("\n");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=ficha.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/ficha.ts"],"sourcesContent":["import type { ArgosConfig } from \"./config.js\";\n\nexport const FICHA_BLOCK_ID = \"ficha\";\n\n/**\n * Render the repo ficha content (the ~10 lines injected into `./CLAUDE.md`\n * under the `ficha` managed block) from the current `argos.config.json`.\n * Shared by `adopt` (writes it) and `doctor` (checks it for drift) so both\n * always agree on what \"up to date\" means.\n */\nexport function buildFichaContent(config: ArgosConfig): string {\n const lines: string[] = [`## Ficha del repo: ${config.name}`, \"\"];\n\n const gate = config.qualityGate.full\n ? `${config.qualityGate.fast} (full: ${config.qualityGate.full})`\n : config.qualityGate.fast;\n lines.push(`- Quality gate fast: \\`${gate}\\``);\n lines.push(`- Rama base: \\`${config.branchBase}\\``);\n lines.push(`- Workspace: ${config.workspace ?? \"sin asignar\"}`);\n\n const criticalAreas = config.project.criticalAreas;\n const legacyPaths = config.project.legacyPaths;\n if (criticalAreas.length > 0 || legacyPaths.length > 0) {\n const areas = [...criticalAreas, ...legacyPaths];\n lines.push(`- Áreas críticas: ${areas.join(\", \")}`);\n }\n\n // Above ~6 skills a single comma-joined line gets unbounded (289 chars\n // observed with 18 libs) — wrap as indented sub-lines instead.\n if (config.skills.length > 6) {\n lines.push(\"- Skills aplicables:\");\n for (const skill of config.skills) lines.push(` - ${skill}`);\n } else {\n lines.push(`- Skills aplicables: ${config.skills.join(\", \")}`);\n }\n lines.push(\"\");\n lines.push(\"Datos de argos.config.json — regenerar con `argos adopt --refresh`.\");\n\n return lines.join(\"\\n\");\n}\n"],"names":["FICHA_BLOCK_ID","buildFichaContent","config","lines","name","gate","qualityGate","full","fast","push","branchBase","workspace","criticalAreas","project","legacyPaths","length","areas","join","skills","skill"],"mappings":"AAEA,OAAO,MAAMA,iBAAiB,QAAQ;AAEtC;;;;;CAKC,GACD,OAAO,SAASC,kBAAkBC,MAAmB;IACnD,MAAMC,QAAkB;QAAC,CAAC,mBAAmB,EAAED,OAAOE,IAAI,EAAE;QAAE;KAAG;IAEjE,MAAMC,OAAOH,OAAOI,WAAW,CAACC,IAAI,GAChC,GAAGL,OAAOI,WAAW,CAACE,IAAI,CAAC,QAAQ,EAAEN,OAAOI,WAAW,CAACC,IAAI,CAAC,CAAC,CAAC,GAC/DL,OAAOI,WAAW,CAACE,IAAI;IAC3BL,MAAMM,IAAI,CAAC,CAAC,uBAAuB,EAAEJ,KAAK,EAAE,CAAC;IAC7CF,MAAMM,IAAI,CAAC,CAAC,eAAe,EAAEP,OAAOQ,UAAU,CAAC,EAAE,CAAC;IAClDP,MAAMM,IAAI,CAAC,CAAC,aAAa,EAAEP,OAAOS,SAAS,IAAI,eAAe;IAE9D,MAAMC,gBAAgBV,OAAOW,OAAO,CAACD,aAAa;IAClD,MAAME,cAAcZ,OAAOW,OAAO,CAACC,WAAW;IAC9C,IAAIF,cAAcG,MAAM,GAAG,KAAKD,YAAYC,MAAM,GAAG,GAAG;QACtD,MAAMC,QAAQ;eAAIJ;eAAkBE;SAAY;QAChDX,MAAMM,IAAI,CAAC,CAAC,kBAAkB,EAAEO,MAAMC,IAAI,CAAC,OAAO;IACpD;IAEA,uEAAuE;IACvE,+DAA+D;IAC/D,IAAIf,OAAOgB,MAAM,CAACH,MAAM,GAAG,GAAG;QAC5BZ,MAAMM,IAAI,CAAC;QACX,KAAK,MAAMU,SAASjB,OAAOgB,MAAM,CAAEf,MAAMM,IAAI,CAAC,CAAC,IAAI,EAAEU,OAAO;IAC9D,OAAO;QACLhB,MAAMM,IAAI,CAAC,CAAC,qBAAqB,EAAEP,OAAOgB,MAAM,CAACD,IAAI,CAAC,OAAO;IAC/D;IACAd,MAAMM,IAAI,CAAC;IACXN,MAAMM,IAAI,CAAC;IAEX,OAAON,MAAMc,IAAI,CAAC;AACpB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface GitCheckResult {
|
|
2
|
+
isRepo: boolean;
|
|
3
|
+
/** True when `git` itself could not be spawned (not installed / not on PATH). */
|
|
4
|
+
gitMissing: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Check whether `cwd` sits inside a git working tree, distinguishing a real
|
|
8
|
+
* infra problem (the `git` binary itself is missing) from the normal "not a
|
|
9
|
+
* repo" case — collapsing both into one message hides a broken environment
|
|
10
|
+
* behind what looks like an ordinary state.
|
|
11
|
+
*/
|
|
12
|
+
export declare function checkGitRepo(cwd: string): GitCheckResult;
|
|
13
|
+
/** True when `cwd` sits inside a git working tree. */
|
|
14
|
+
export declare function isGitRepo(cwd: string): boolean;
|
|
15
|
+
/** `git remote get-url origin`, or null when there is no such remote. */
|
|
16
|
+
export declare function getRemoteOriginUrl(cwd: string): string | null;
|
|
17
|
+
/**
|
|
18
|
+
* Derive a short identity token from a git remote URL, e.g.
|
|
19
|
+
* `https://github.com/bonum/repo.git` or `git@github.com:bonum/repo.git`
|
|
20
|
+
* both become `github.com-bonum` (host + first path segment, which is the
|
|
21
|
+
* org/user account on every common host — GitHub, GitLab, Bitbucket).
|
|
22
|
+
*
|
|
23
|
+
* Returns null when the URL doesn't match either the scp-like SSH form
|
|
24
|
+
* (`user@host:path`) or a URL form (`scheme://host/path`).
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseIdentityFromRemote(remoteUrl: string): string | null;
|
|
27
|
+
//# sourceMappingURL=git.d.ts.map
|