create-absolutejs 0.13.11 → 0.14.1

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 CHANGED
@@ -51,6 +51,13 @@ Usage: create-absolute [project-name] [options]
51
51
  - `--angular`
52
52
  Include an Angular frontend.
53
53
 
54
+ - `--agentic`
55
+ Add the provider-neutral agent stack: Agency action enforcement and kill
56
+ switch, agent auth, MCP Tasks, credential operations, bounded wallet spend,
57
+ manifest contract 2, and the adversarial conformance harness. The scaffold
58
+ creates `src/backend/agent.ts` with a deny-by-default policy plus an
59
+ `AGENTS.md` execution contract.
60
+
54
61
  - `--angular-dir <directory>`
55
62
  Specify the directory for and use the Angular frontend.
56
63
 
@@ -1,8 +1,8 @@
1
1
  import type { CreateConfiguration } from '../../types';
2
- type CreatePackageJsonProps = Pick<CreateConfiguration, 'authOption' | 'useTailwind' | 'databaseEngine' | 'databaseHost' | 'plugins' | 'orm' | 'frontendDirectories' | 'codeQualityTool'> & {
2
+ type CreatePackageJsonProps = Pick<CreateConfiguration, 'authOption' | 'agentic' | 'useTailwind' | 'databaseEngine' | 'databaseHost' | 'plugins' | 'orm' | 'frontendDirectories' | 'codeQualityTool'> & {
3
3
  projectName: string;
4
4
  latest: boolean;
5
5
  repositoryUrl: string | undefined;
6
6
  };
7
- export declare const createPackageJson: ({ projectName, authOption, plugins, databaseEngine, orm, databaseHost, useTailwind, latest, frontendDirectories, codeQualityTool, repositoryUrl }: CreatePackageJsonProps) => Promise<void>;
7
+ export declare const createPackageJson: ({ agentic, projectName, authOption, plugins, databaseEngine, orm, databaseHost, useTailwind, latest, frontendDirectories, codeQualityTool, repositoryUrl }: CreatePackageJsonProps) => Promise<void>;
8
8
  export {};
@@ -16,7 +16,7 @@ const dbClientCommands = {
16
16
  postgresql: 'psql -h localhost -U user -d database',
17
17
  singlestore: 'singlestore -u root -ppassword -D database'
18
18
  };
19
- export const createPackageJson = async ({ projectName, authOption, plugins, databaseEngine, orm, databaseHost, useTailwind, latest, frontendDirectories, codeQualityTool, repositoryUrl }) => {
19
+ export const createPackageJson = async ({ agentic, projectName, authOption, plugins, databaseEngine, orm, databaseHost, useTailwind, latest, frontendDirectories, codeQualityTool, repositoryUrl }) => {
20
20
  const flags = computeFlags(frontendDirectories);
21
21
  const isLocal = !databaseHost || databaseHost === 'none';
22
22
  /* ── Collect all package names that need versions ─────────── */
@@ -28,6 +28,15 @@ export const createPackageJson = async ({ projectName, authOption, plugins, data
28
28
  packageNames.add(dep.value);
29
29
  if (authOption === 'abs')
30
30
  packageNames.add(absoluteAuthPlugin.value);
31
+ if (agentic) {
32
+ packageNames.add('@absolutejs/agency');
33
+ packageNames.add('@absolutejs/agent-conformance');
34
+ packageNames.add('@absolutejs/auth');
35
+ packageNames.add('@absolutejs/manifest');
36
+ packageNames.add('@absolutejs/mcp');
37
+ packageNames.add('@absolutejs/secrets');
38
+ packageNames.add('@absolutejs/wallet');
39
+ }
31
40
  for (const pluginValue of plugins) {
32
41
  const meta = availablePlugins.find((p) => p.value === pluginValue);
33
42
  if (meta)
@@ -122,6 +131,19 @@ export const createPackageJson = async ({ projectName, authOption, plugins, data
122
131
  if (authOption === 'abs') {
123
132
  dependencies[absoluteAuthPlugin.value] = resolveVersion(absoluteAuthPlugin.value, absoluteAuthPlugin.latestVersion);
124
133
  }
134
+ if (agentic) {
135
+ for (const name of [
136
+ '@absolutejs/agency',
137
+ '@absolutejs/auth',
138
+ '@absolutejs/manifest',
139
+ '@absolutejs/mcp',
140
+ '@absolutejs/secrets',
141
+ '@absolutejs/wallet'
142
+ ]) {
143
+ dependencies[name] = resolveVersion(name, versions[name]);
144
+ }
145
+ devDependencies['@absolutejs/agent-conformance'] = resolveVersion('@absolutejs/agent-conformance', versions['@absolutejs/agent-conformance']);
146
+ }
125
147
  for (const pluginValue of plugins) {
126
148
  const meta = availablePlugins.find((p) => p.value === pluginValue);
127
149
  if (!meta)
@@ -0,0 +1,6 @@
1
+ export declare const agentRuntimeSource = "import {\n\tcreateAgency,\n\tcreateAgentControlPlane,\n\tcreateMemoryAgencyStore,\n\tcreateMemoryAgentControlStore,\n\tdenyAllPolicy\n} from '@absolutejs/agency'\n\n// Memory stores are development defaults. Replace them with durable stores\n// before running more than one process or accepting production actions.\nexport const agentControl = createAgentControlPlane({\n\tsources: [],\n\tstore: createMemoryAgentControlStore()\n})\n\n// Intentionally deny-by-default. Replace denyAllPolicy() with your policy\n// decision point only after declaring each action's effects and scopes.\nexport const agency = createAgency({\n\tcontrol: agentControl,\n\tpolicy: denyAllPolicy(),\n\tstore: createMemoryAgencyStore()\n})\n";
2
+ export declare const agentsGuide = "# Agent execution contract\n\nThis project uses the AbsoluteJS provider-neutral agent stack.\n\n- Authenticate agents and bind every delegation to a user with\n `@absolutejs/auth`. Never treat model-provided identity as authenticated.\n- Route every effectful tool through `agency` in `src/backend/agent.ts`.\n Approval is exact-input-bound; execution requires a fresh single-use lease.\n- Declare tool effects, scopes, approval policy, idempotency keys,\n reversibility, destinations, and spend fields in manifest contract 2.\n- Keep raw credentials host-side with `@absolutejs/secrets` credential\n operations. Agents receive operation results, never secret values.\n- Give agents bounded wallet allowances and signed mandates. The host resolves\n ledger destinations; an agent never supplies the recipient account id.\n- Bind MCP task handles to the authenticated actor on get, update, and cancel.\n- Run `@absolutejs/agent-conformance` suites for every new action, capability,\n credential, wallet, and task adapter.\n- Use the control plane kill switch for incident response. It blocks new\n requests, lease issuance, and execution before downstream revocation fans out.\n\nMemory stores are for local development only. Production stores must be\ndurable and enforce lease/capability consumption atomically.\n";
3
+ export declare const scaffoldAgentic: ({ backendDirectory, projectName }: {
4
+ backendDirectory: string;
5
+ projectName: string;
6
+ }) => void;
@@ -0,0 +1,53 @@
1
+ import { mkdirSync, writeFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ export const agentRuntimeSource = `import {
4
+ createAgency,
5
+ createAgentControlPlane,
6
+ createMemoryAgencyStore,
7
+ createMemoryAgentControlStore,
8
+ denyAllPolicy
9
+ } from '@absolutejs/agency'
10
+
11
+ // Memory stores are development defaults. Replace them with durable stores
12
+ // before running more than one process or accepting production actions.
13
+ export const agentControl = createAgentControlPlane({
14
+ sources: [],
15
+ store: createMemoryAgentControlStore()
16
+ })
17
+
18
+ // Intentionally deny-by-default. Replace denyAllPolicy() with your policy
19
+ // decision point only after declaring each action's effects and scopes.
20
+ export const agency = createAgency({
21
+ control: agentControl,
22
+ policy: denyAllPolicy(),
23
+ store: createMemoryAgencyStore()
24
+ })
25
+ `;
26
+ export const agentsGuide = `# Agent execution contract
27
+
28
+ This project uses the AbsoluteJS provider-neutral agent stack.
29
+
30
+ - Authenticate agents and bind every delegation to a user with
31
+ \`@absolutejs/auth\`. Never treat model-provided identity as authenticated.
32
+ - Route every effectful tool through \`agency\` in \`src/backend/agent.ts\`.
33
+ Approval is exact-input-bound; execution requires a fresh single-use lease.
34
+ - Declare tool effects, scopes, approval policy, idempotency keys,
35
+ reversibility, destinations, and spend fields in manifest contract 2.
36
+ - Keep raw credentials host-side with \`@absolutejs/secrets\` credential
37
+ operations. Agents receive operation results, never secret values.
38
+ - Give agents bounded wallet allowances and signed mandates. The host resolves
39
+ ledger destinations; an agent never supplies the recipient account id.
40
+ - Bind MCP task handles to the authenticated actor on get, update, and cancel.
41
+ - Run \`@absolutejs/agent-conformance\` suites for every new action, capability,
42
+ credential, wallet, and task adapter.
43
+ - Use the control plane kill switch for incident response. It blocks new
44
+ requests, lease issuance, and execution before downstream revocation fans out.
45
+
46
+ Memory stores are for local development only. Production stores must be
47
+ durable and enforce lease/capability consumption atomically.
48
+ `;
49
+ export const scaffoldAgentic = ({ backendDirectory, projectName }) => {
50
+ mkdirSync(backendDirectory, { recursive: true });
51
+ writeFileSync(join(backendDirectory, 'agent.ts'), agentRuntimeSource);
52
+ writeFileSync(join(projectName, 'AGENTS.md'), agentsGuide);
53
+ };
@@ -10,5 +10,5 @@ type DebugMessageProps = {
10
10
  response: CreateConfiguration;
11
11
  packageManager: string;
12
12
  };
13
- export declare const getDebugMessage: ({ response: { projectName, codeQualityTool, directoryConfig, useTailwind, tailwind, frontends, includeExamples, useHTMLScripts, frontendDirectories, buildDirectory, assetsDirectory, databaseEngine, databaseHost, databaseDirectory, orm, authOption, plugins, initializeGitNow, installDependenciesNow }, packageManager }: DebugMessageProps) => string;
13
+ export declare const getDebugMessage: ({ response: { agentic, projectName, codeQualityTool, directoryConfig, useTailwind, tailwind, frontends, includeExamples, useHTMLScripts, frontendDirectories, buildDirectory, assetsDirectory, databaseEngine, databaseHost, databaseDirectory, orm, authOption, plugins, initializeGitNow, installDependenciesNow }, packageManager }: DebugMessageProps) => string;
14
14
  export {};
package/dist/messages.js CHANGED
@@ -12,6 +12,7 @@ Options:
12
12
  ${cyan('--debug, -d')} Display a summary of the project configuration after creation
13
13
 
14
14
  ${cyan('--abs-provider')} A provider for Absolute-Auth (eg. 'google', 'github', 'discord') the full list is available at https://absolutejs.com/documentation/absolute-auth
15
+ ${cyan('--agentic')} Add provider-neutral agent auth, actions, MCP, wallet, credential, and conformance scaffolding
15
16
  ${cyan('--angular')} Include an Angular frontend
16
17
  ${cyan('--angular-dir')} ${dim(cyan('<directory>'))} Specify the directory for and use the Angular frontend
17
18
  ${cyan('--assets')} ${dim(cyan('<directory>'))} Directory name for your static assets
@@ -49,7 +50,7 @@ export const getOutroMessage = ({ projectName, packageManager, installDependenci
49
50
  `${cyan('cd')} ${projectName}\n` +
50
51
  `${installDependenciesNow ? '' : `${cyan(`${packageManager} install`)}\n`}` +
51
52
  `${cyan(`${packageManager} dev`)}`; // TODO: Some package managers need run
52
- export const getDebugMessage = ({ response: { projectName, codeQualityTool, directoryConfig, useTailwind, tailwind, frontends, includeExamples, useHTMLScripts, frontendDirectories, buildDirectory, assetsDirectory, databaseEngine, databaseHost, databaseDirectory, orm, authOption, plugins, initializeGitNow, installDependenciesNow }, packageManager }) => {
53
+ export const getDebugMessage = ({ response: { agentic, projectName, codeQualityTool, directoryConfig, useTailwind, tailwind, frontends, includeExamples, useHTMLScripts, frontendDirectories, buildDirectory, assetsDirectory, databaseEngine, databaseHost, databaseDirectory, orm, authOption, plugins, initializeGitNow, installDependenciesNow }, packageManager }) => {
53
54
  const htmlScriptingValue = useHTMLScripts
54
55
  ? blueBright('TypeScript')
55
56
  : dim('None');
@@ -63,6 +64,7 @@ export const getDebugMessage = ({ response: { projectName, codeQualityTool, dire
63
64
  /* prettier-ignore */
64
65
  const lines = [
65
66
  ['Project Name', projectName],
67
+ ['Agent-first Stack', agentic ? green('Yes') : dim('No')],
66
68
  ['Package Manager', packageManager],
67
69
  ['Config Type', isCustomConfig ? green('Custom') : dim('Default')],
68
70
  ['Linting', codeQualityTool === 'eslint+prettier' ? 'ESLint + Prettier' : 'Biome'],
package/dist/prompt.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { getAuthOption } from './questions/authOption';
2
+ import { getAgentic } from './questions/agentic';
2
3
  import { getCodeQualityTool } from './questions/codeQualityTool';
3
4
  import { getConfigurationType } from './questions/configurationType';
4
5
  import { getDatabaseEngine } from './questions/databaseEngine';
@@ -57,6 +58,9 @@ export const prompt = async (argumentConfiguration) => {
57
58
  directoryConfig = 'custom';
58
59
  // 12. Auth provider
59
60
  const authOption = argumentConfiguration.authOption ?? (await orPrompt('--auth', getAuthOption));
61
+ // 12b. Agent-first action/auth/MCP/wallet/credential stack
62
+ const agentic = argumentConfiguration.agentic ??
63
+ (await orPrompt('--agentic/--no-agentic', getAgentic));
60
64
  // 13. Additional plugins
61
65
  const plugins = argumentConfiguration.plugins?.filter((plugin) => plugin !== undefined) ?? (await orPrompt('--plugin', getPlugins));
62
66
  // 14. Initialize Git repository
@@ -84,6 +88,7 @@ export const prompt = async (argumentConfiguration) => {
84
88
  const installDependenciesNow = argumentConfiguration.installDependenciesNow ??
85
89
  (await orPrompt('--install/--no-install', getInstallDependencies));
86
90
  const values = {
91
+ agentic,
87
92
  absProviders: argumentConfiguration.absProviders?.filter((provider) => provider !== undefined),
88
93
  assetsDirectory,
89
94
  authOption,
@@ -0,0 +1 @@
1
+ export declare const getAgentic: () => Promise<boolean>;
@@ -0,0 +1,11 @@
1
+ import { confirm, isCancel } from '@clack/prompts';
2
+ import { abort } from '../utils/abort';
3
+ export const getAgentic = async () => {
4
+ const agentic = await confirm({
5
+ initialValue: false,
6
+ message: 'Add the agent-first stack (auth, actions, MCP, wallet, credentials, and conformance)?'
7
+ });
8
+ if (isCancel(agentic))
9
+ abort();
10
+ return agentic;
11
+ };
@@ -5,7 +5,7 @@ type ScaffoldProps = {
5
5
  latest: boolean;
6
6
  envVariables: string[] | undefined;
7
7
  };
8
- export declare const scaffold: ({ response: { projectName, codeQualityTool, initializeGitNow, githubLink, githubRepoUrl, githubVisibility, databaseEngine, databaseHost, useHTMLScripts, useTailwind, databaseDirectory, absProviders, includeExamples, orm, frontends, plugins, authOption, buildDirectory, assetsDirectory, tailwind, installDependenciesNow, frontendDirectories }, latest, envVariables, packageManager }: ScaffoldProps) => Promise<{
8
+ export declare const scaffold: ({ response: { agentic, projectName, codeQualityTool, initializeGitNow, githubLink, githubRepoUrl, githubVisibility, databaseEngine, databaseHost, useHTMLScripts, useTailwind, databaseDirectory, absProviders, includeExamples, orm, frontends, plugins, authOption, buildDirectory, assetsDirectory, tailwind, installDependenciesNow, frontendDirectories }, latest, envVariables, packageManager }: ScaffoldProps) => Promise<{
9
9
  dockerFreshInstall: boolean;
10
10
  }>;
11
11
  export {};
package/dist/scaffold.js CHANGED
@@ -10,7 +10,8 @@ import { scaffoldConfigurationFiles } from './generators/configurations/scaffold
10
10
  import { scaffoldDatabase } from './generators/db/scaffoldDatabase';
11
11
  import { scaffoldBackend } from './generators/project/scaffoldBackend';
12
12
  import { scaffoldFrontends } from './generators/project/scaffoldFrontends';
13
- export const scaffold = async ({ response: { projectName, codeQualityTool, initializeGitNow, githubLink, githubRepoUrl, githubVisibility, databaseEngine, databaseHost, useHTMLScripts, useTailwind, databaseDirectory, absProviders, includeExamples, orm, frontends, plugins, authOption, buildDirectory, assetsDirectory, tailwind, installDependenciesNow, frontendDirectories }, latest, envVariables, packageManager }) => {
13
+ import { scaffoldAgentic } from './generators/project/scaffoldAgentic';
14
+ export const scaffold = async ({ response: { agentic, projectName, codeQualityTool, initializeGitNow, githubLink, githubRepoUrl, githubVisibility, databaseEngine, databaseHost, useHTMLScripts, useTailwind, databaseDirectory, absProviders, includeExamples, orm, frontends, plugins, authOption, buildDirectory, assetsDirectory, tailwind, installDependenciesNow, frontendDirectories }, latest, envVariables, packageManager }) => {
14
15
  const __dirname = dirname(fileURLToPath(import.meta.url));
15
16
  const templatesDirectory = join(__dirname, '/templates');
16
17
  const { frontendDirectory, backendDirectory, projectAssetsDirectory, typesDirectory } = initalizeRoot(projectName, templatesDirectory);
@@ -27,6 +28,7 @@ export const scaffold = async ({ response: { projectName, codeQualityTool, initi
27
28
  templatesDirectory
28
29
  });
29
30
  await createPackageJson({
31
+ agentic,
30
32
  authOption,
31
33
  codeQualityTool,
32
34
  databaseEngine,
@@ -53,6 +55,8 @@ export const scaffold = async ({ response: { projectName, codeQualityTool, initi
53
55
  publicDirectory: 'public',
54
56
  tailwind
55
57
  });
58
+ if (agentic)
59
+ scaffoldAgentic({ backendDirectory, projectName });
56
60
  let dockerFreshInstall = false;
57
61
  if (databaseDirectory !== undefined &&
58
62
  databaseEngine !== 'none' &&
package/dist/types.d.ts CHANGED
@@ -43,6 +43,7 @@ export type TailwindConfig = {
43
43
  } | undefined;
44
44
  export type GithubLinkOption = 'existing' | 'create' | 'skip';
45
45
  export type CreateConfiguration = {
46
+ agentic: boolean;
46
47
  absProviders: ProviderOption[] | undefined;
47
48
  assetsDirectory: string;
48
49
  authOption: AuthOption;
@@ -12,6 +12,7 @@ export const parseCommandLineOptions = () => {
12
12
  args: argv.slice(DEFAULT_ARG_LENGTH),
13
13
  options: {
14
14
  'abs-provider': { multiple: true, type: 'string' },
15
+ agentic: { type: 'boolean' },
15
16
  angular: { type: 'boolean' },
16
17
  'angular-dir': { type: 'string' },
17
18
  assets: { type: 'string' },
@@ -250,6 +251,7 @@ export const parseCommandLineOptions = () => {
250
251
  ? repoVisibility
251
252
  : undefined;
252
253
  const argumentConfiguration = {
254
+ agentic: values.agentic ?? (values.skip ? false : undefined),
253
255
  absProviders: absProviders.length ? absProviders : undefined,
254
256
  assetsDirectory: values.assets,
255
257
  authOption,
@@ -5,7 +5,13 @@
5
5
  */
6
6
  export declare const versions: {
7
7
  readonly '@absolutejs/absolute': "0.19.0-beta.1081";
8
- readonly '@absolutejs/auth': "0.22.7";
8
+ readonly '@absolutejs/agency': "0.2.0";
9
+ readonly '@absolutejs/agent-conformance': "0.1.0";
10
+ readonly '@absolutejs/auth': "0.54.6";
11
+ readonly '@absolutejs/manifest': "0.2.0";
12
+ readonly '@absolutejs/mcp': "0.5.1";
13
+ readonly '@absolutejs/secrets': "0.6.1";
14
+ readonly '@absolutejs/wallet': "0.2.1";
9
15
  readonly '@angular/common': "21.2.0";
10
16
  readonly '@angular/compiler': "21.2.0";
11
17
  readonly '@angular/compiler-cli': "21.2.0";
package/dist/versions.js CHANGED
@@ -6,7 +6,13 @@
6
6
  export const versions = {
7
7
  /* ── Core ─────────────────────────────────────────────── */
8
8
  '@absolutejs/absolute': '0.19.0-beta.1081',
9
- '@absolutejs/auth': '0.22.7',
9
+ '@absolutejs/agency': '0.2.0',
10
+ '@absolutejs/agent-conformance': '0.1.0',
11
+ '@absolutejs/auth': '0.54.6',
12
+ '@absolutejs/manifest': '0.2.0',
13
+ '@absolutejs/mcp': '0.5.1',
14
+ '@absolutejs/secrets': '0.6.1',
15
+ '@absolutejs/wallet': '0.2.1',
10
16
  /* ── Angular ─────────────────────────────────────────── */
11
17
  '@angular/common': '21.2.0',
12
18
  '@angular/compiler': '21.2.0',
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "create-absolutejs": "dist/index.js"
5
5
  },
6
6
  "dependencies": {
7
- "@absolutejs/auth": "0.22.0",
7
+ "@absolutejs/auth": "0.54.6",
8
8
  "@clack/prompts": "1.0.0",
9
9
  "picocolors": "1.1.1"
10
10
  },
@@ -47,10 +47,12 @@
47
47
  "dev": "bun scripts/dev.ts",
48
48
  "format": "absolute prettier --write",
49
49
  "lint": "absolute eslint --ignore-pattern 'absolutejs-project/**'",
50
- "release": "bun run format && bun run build && bun publish",
50
+ "release": "bun run format && bun run check:package && bun publish",
51
51
  "test": "cd absolutejs-project && bun dev",
52
+ "test:unit": "bun test tests/",
53
+ "check:package": "bun run typecheck && bun run test:unit && bun run build",
52
54
  "typecheck": "bun run tsc --noEmit"
53
55
  },
54
56
  "type": "module",
55
- "version": "0.13.11"
57
+ "version": "0.14.1"
56
58
  }