ultracode-for-codex 0.2.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.
@@ -0,0 +1,38 @@
1
+ import type { ReasoningEffort, Verbosity } from './runtime/types.js';
2
+ export type WorkflowExecutionMode = 'background' | 'attached';
3
+ export type WorkflowProgressMode = 'jsonl' | 'plain';
4
+ export type WorkflowPermissionPolicy = 'ask' | 'allow' | 'deny';
5
+ export interface UltracodeSettings {
6
+ readonly workflow: {
7
+ readonly executionMode: WorkflowExecutionMode;
8
+ readonly progress: WorkflowProgressMode;
9
+ readonly permission: WorkflowPermissionPolicy;
10
+ readonly retryLimit: number;
11
+ readonly timeoutMs: number;
12
+ readonly background: {
13
+ readonly runDir: string;
14
+ readonly resultFile: string;
15
+ readonly progressFile: string;
16
+ readonly metadataFile: string;
17
+ readonly pidFile: string;
18
+ };
19
+ };
20
+ readonly codex: {
21
+ readonly reasoningEffort: ReasoningEffort;
22
+ readonly verbosity: Verbosity;
23
+ };
24
+ }
25
+ export declare function loadSettings(): UltracodeSettings;
26
+ export declare function workflowDefaultExecutionMode(): WorkflowExecutionMode;
27
+ export declare function workflowDefaultProgressMode(): WorkflowProgressMode;
28
+ export declare function workflowDefaultPermissionPolicy(): WorkflowPermissionPolicy;
29
+ export declare function workflowDefaultRetryLimit(): number;
30
+ export declare function workflowDefaultTimeoutMs(): number;
31
+ export declare function workflowBackgroundDefaults(): UltracodeSettings['workflow']['background'];
32
+ export declare function codexDefaultReasoningEffort(): ReasoningEffort;
33
+ export declare function codexDefaultVerbosity(): Verbosity;
34
+ export declare function isReasoningEffort(value: unknown): value is ReasoningEffort;
35
+ export declare function isVerbosity(value: unknown): value is Verbosity;
36
+ export declare function isWorkflowExecutionMode(value: unknown): value is WorkflowExecutionMode;
37
+ export declare function isWorkflowProgressMode(value: unknown): value is WorkflowProgressMode;
38
+ export declare function isWorkflowPermissionPolicy(value: unknown): value is WorkflowPermissionPolicy;
@@ -0,0 +1,153 @@
1
+ import { readFileSync } from 'node:fs';
2
+ const SETTINGS_URL = new URL('../settings.json', import.meta.url);
3
+ const WORKFLOW_EXECUTION_MODES = ['background', 'attached'];
4
+ const WORKFLOW_PROGRESS_MODES = ['jsonl', 'plain'];
5
+ const WORKFLOW_PERMISSION_POLICIES = ['ask', 'allow', 'deny'];
6
+ const REASONING_EFFORTS = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh'];
7
+ const VERBOSITIES = ['low', 'medium', 'high'];
8
+ let cachedSettings = null;
9
+ export function loadSettings() {
10
+ if (cachedSettings)
11
+ return cachedSettings;
12
+ let parsed;
13
+ try {
14
+ parsed = JSON.parse(readFileSync(SETTINGS_URL, 'utf8'));
15
+ }
16
+ catch (err) {
17
+ throw new Error(`Unable to read settings.json: ${errorMessage(err)}`);
18
+ }
19
+ const root = asRecord(parsed);
20
+ if (!root)
21
+ throw new Error('settings.json must contain a JSON object.');
22
+ const workflow = asRecord(root?.workflow);
23
+ if (!workflow)
24
+ throw new Error('settings.json must define workflow.');
25
+ const background = asRecord(workflow?.background);
26
+ if (!background)
27
+ throw new Error('settings.json must define workflow.background.');
28
+ const codex = asRecord(root?.codex);
29
+ if (!codex)
30
+ throw new Error('settings.json must define codex.');
31
+ cachedSettings = {
32
+ workflow: {
33
+ executionMode: readWorkflowExecutionModeSetting(workflow?.executionMode, 'workflow.executionMode'),
34
+ progress: readWorkflowProgressModeSetting(workflow?.progress, 'workflow.progress'),
35
+ permission: readWorkflowPermissionPolicySetting(workflow?.permission, 'workflow.permission'),
36
+ retryLimit: readNonNegativeIntegerSetting(workflow?.retryLimit, 'workflow.retryLimit'),
37
+ timeoutMs: readPositiveIntegerSetting(workflow?.timeoutMs, 'workflow.timeoutMs'),
38
+ background: {
39
+ runDir: readTemplateSetting(background?.runDir, 'workflow.background.runDir', true),
40
+ resultFile: readRelativePathSetting(background?.resultFile, 'workflow.background.resultFile'),
41
+ progressFile: readRelativePathSetting(background?.progressFile, 'workflow.background.progressFile'),
42
+ metadataFile: readRelativePathSetting(background?.metadataFile, 'workflow.background.metadataFile'),
43
+ pidFile: readRelativePathSetting(background?.pidFile, 'workflow.background.pidFile'),
44
+ },
45
+ },
46
+ codex: {
47
+ reasoningEffort: readReasoningEffortSetting(codex?.reasoningEffort, 'codex.reasoningEffort'),
48
+ verbosity: readVerbositySetting(codex?.verbosity, 'codex.verbosity'),
49
+ },
50
+ };
51
+ return cachedSettings;
52
+ }
53
+ export function workflowDefaultExecutionMode() {
54
+ return loadSettings().workflow.executionMode;
55
+ }
56
+ export function workflowDefaultProgressMode() {
57
+ return loadSettings().workflow.progress;
58
+ }
59
+ export function workflowDefaultPermissionPolicy() {
60
+ return loadSettings().workflow.permission;
61
+ }
62
+ export function workflowDefaultRetryLimit() {
63
+ return loadSettings().workflow.retryLimit;
64
+ }
65
+ export function workflowDefaultTimeoutMs() {
66
+ return loadSettings().workflow.timeoutMs;
67
+ }
68
+ export function workflowBackgroundDefaults() {
69
+ return loadSettings().workflow.background;
70
+ }
71
+ export function codexDefaultReasoningEffort() {
72
+ return loadSettings().codex.reasoningEffort;
73
+ }
74
+ export function codexDefaultVerbosity() {
75
+ return loadSettings().codex.verbosity;
76
+ }
77
+ export function isReasoningEffort(value) {
78
+ return typeof value === 'string' && REASONING_EFFORTS.includes(value);
79
+ }
80
+ export function isVerbosity(value) {
81
+ return typeof value === 'string' && VERBOSITIES.includes(value);
82
+ }
83
+ export function isWorkflowExecutionMode(value) {
84
+ return typeof value === 'string' && WORKFLOW_EXECUTION_MODES.includes(value);
85
+ }
86
+ export function isWorkflowProgressMode(value) {
87
+ return typeof value === 'string' && WORKFLOW_PROGRESS_MODES.includes(value);
88
+ }
89
+ export function isWorkflowPermissionPolicy(value) {
90
+ return typeof value === 'string' && WORKFLOW_PERMISSION_POLICIES.includes(value);
91
+ }
92
+ function readWorkflowExecutionModeSetting(value, key) {
93
+ if (isWorkflowExecutionMode(value))
94
+ return value;
95
+ throw new Error(`${key} must be one of ${WORKFLOW_EXECUTION_MODES.join(', ')}.`);
96
+ }
97
+ function readWorkflowProgressModeSetting(value, key) {
98
+ if (isWorkflowProgressMode(value))
99
+ return value;
100
+ throw new Error(`${key} must be one of ${WORKFLOW_PROGRESS_MODES.join(', ')}.`);
101
+ }
102
+ function readWorkflowPermissionPolicySetting(value, key) {
103
+ if (isWorkflowPermissionPolicy(value))
104
+ return value;
105
+ throw new Error(`${key} must be one of ${WORKFLOW_PERMISSION_POLICIES.join(', ')}.`);
106
+ }
107
+ function readReasoningEffortSetting(value, key) {
108
+ if (isReasoningEffort(value))
109
+ return value;
110
+ throw new Error(`${key} must be one of ${REASONING_EFFORTS.join(', ')}.`);
111
+ }
112
+ function readVerbositySetting(value, key) {
113
+ if (isVerbosity(value))
114
+ return value;
115
+ throw new Error(`${key} must be one of ${VERBOSITIES.join(', ')}.`);
116
+ }
117
+ function readNonNegativeIntegerSetting(value, key) {
118
+ if (typeof value === 'number' && Number.isInteger(value) && value >= 0)
119
+ return value;
120
+ throw new Error(`${key} must be a non-negative integer.`);
121
+ }
122
+ function readPositiveIntegerSetting(value, key) {
123
+ if (typeof value === 'number' && Number.isInteger(value) && value > 0)
124
+ return value;
125
+ throw new Error(`${key} must be a positive integer.`);
126
+ }
127
+ function readTemplateSetting(value, key, requireJobId) {
128
+ const text = readNonEmptyStringSetting(value, key);
129
+ if (requireJobId && !text.includes('{jobId}')) {
130
+ throw new Error(`${key} must include {jobId}.`);
131
+ }
132
+ return text;
133
+ }
134
+ function readRelativePathSetting(value, key) {
135
+ const text = readNonEmptyStringSetting(value, key);
136
+ if (text.startsWith('/') || /^[A-Za-z]:[\\/]/.test(text) || text.split(/[\\/]+/).includes('..')) {
137
+ throw new Error(`${key} must be a relative path without parent traversal.`);
138
+ }
139
+ return text;
140
+ }
141
+ function readNonEmptyStringSetting(value, key) {
142
+ if (typeof value === 'string' && value.trim())
143
+ return value;
144
+ throw new Error(`${key} must be a non-empty string.`);
145
+ }
146
+ function asRecord(value) {
147
+ if (!value || typeof value !== 'object' || Array.isArray(value))
148
+ return null;
149
+ return value;
150
+ }
151
+ function errorMessage(err) {
152
+ return err instanceof Error ? err.message : String(err);
153
+ }
@@ -0,0 +1,4 @@
1
+ export declare const ULTRACODE_INSTALL_GUIDE_FILENAME = "ULTRACODE_INSTALL.md";
2
+ export declare function readUltracodeInstallGuide(): string;
3
+ export declare function ultracodeInstallGuidePath(): string;
4
+ export declare function renderUltracodeInstallGuideNotice(guide?: string): string;
@@ -0,0 +1,22 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ export const ULTRACODE_INSTALL_GUIDE_FILENAME = 'ULTRACODE_INSTALL.md';
5
+ export function readUltracodeInstallGuide() {
6
+ return readFileSync(ultracodeInstallGuidePath(), 'utf8');
7
+ }
8
+ export function ultracodeInstallGuidePath() {
9
+ const distDir = dirname(fileURLToPath(import.meta.url));
10
+ return join(distDir, '..', ULTRACODE_INSTALL_GUIDE_FILENAME);
11
+ }
12
+ export function renderUltracodeInstallGuideNotice(guide = readUltracodeInstallGuide()) {
13
+ return [
14
+ '',
15
+ '=== ultracode-for-codex ULTRACODE INSTALL GUIDE START ===',
16
+ guide.trimEnd(),
17
+ '=== ultracode-for-codex ULTRACODE INSTALL GUIDE END ===',
18
+ '',
19
+ `Re-read later with: ultracode-for-codex --llm-guide`,
20
+ '',
21
+ ].join('\n');
22
+ }
@@ -0,0 +1,78 @@
1
+ # Ultracode Journal Contract
2
+
3
+ This is the current journal contract for the local command-owned workflow runtime.
4
+ It is implemented in `src/runtime/workflow-journal.ts` and
5
+ `src/runtime/workflow-runtime.ts`.
6
+
7
+ ## Goal
8
+
9
+ Every launched workflow writes a durable
10
+ `<transcriptDir>/journal.jsonl` ledger. The journal is the canonical runtime
11
+ artifact for future replay/cache behavior; CLI progress is only a
12
+ projection.
13
+
14
+ P3-A is done when:
15
+
16
+ - `workflow.run.started` is durably written before `taskId` and `runId` are
17
+ acknowledged to the caller;
18
+ - agent started/completed/failed entries use deterministic start-order call
19
+ keys;
20
+ - exactly one terminal run entry is durable before terminal workflow events and
21
+ result projection;
22
+ - journal write failures fail closed with `workflow_journal_write_failed`;
23
+ - journal readers validate schema, ordering, sequence, hash chain, task/run
24
+ identity, agent pairing, terminal uniqueness, and trailing partial-line
25
+ recovery.
26
+
27
+ ## Authority Model
28
+
29
+ | Concept | Authority | Rule |
30
+ | --- | --- | --- |
31
+ | `journal.jsonl` | runtime canonical artifact | Future replay/cache reads this ledger. |
32
+ | `WorkflowEvent` | runtime projection | CLI progress consumes this stream. |
33
+ | `taskId`, `runId`, `seq`, `recordedAt` | runtime | Never accepted from workflow script or model output. |
34
+ | `journalPath` | runtime internal state | Never printed in CLI output. |
35
+ | `scriptPath`, `workflowSource`, `scriptHash` | runtime resolver | Captured in `workflow.run.started`. |
36
+ | agent return value | runtime executor | Raw text or validated structured output. |
37
+
38
+ The CLI defaults to OS background execution from `settings.json`, writing result
39
+ and progress files under the configured background run directory. Attached
40
+ execution prints progress to stderr as JSONL and final result JSON to stdout.
41
+ Journal contents and `journalPath` remain internal runtime state.
42
+
43
+ ## Ordering
44
+
45
+ Launch ordering:
46
+
47
+ 1. Normalize and validate workflow input.
48
+ 2. Resolve source, permission, script hash, and transcript directory.
49
+ 3. Create the transcript directory.
50
+ 4. Append and durably flush `workflow.run.started`.
51
+ 5. Register the task, emit `workflow.started`, and start execution.
52
+
53
+ Agent ordering:
54
+
55
+ 1. Reserve `agentIndex`, `agentId`, `previousAgentCallKey`, and `agentCallKey`
56
+ before the first await.
57
+ 2. Append and flush `workflow.agent.started`.
58
+ 3. Emit `workflow.agent.started`.
59
+ 4. Execute Codex subagent with stall retry and structured-output validation.
60
+ 5. Append and flush exactly one agent final entry.
61
+ 6. Emit the matching final event.
62
+
63
+ Terminal ordering:
64
+
65
+ 1. Create or reuse one terminal finalizer.
66
+ 2. Normalize result or failure payload.
67
+ 3. Append and flush terminal run entry.
68
+ 4. Emit `workflow.completed` or `workflow.failed`.
69
+ 5. Write/project the terminal result when successful.
70
+
71
+ ## Verification
72
+
73
+ - `test/workflow-journal.test.mjs` verifies stable JSON, writer durability, and
74
+ reader validation.
75
+ - `test/workflow-runtime.test.mjs` verifies direct runtime launch, failure,
76
+ retry, cancel, resume/cache, and worktree paths.
77
+ - `scripts/e2e-installed-ultracode-for-codex.mjs` verifies the packaged CLI
78
+ against a fake Codex app-server boundary.
@@ -0,0 +1,43 @@
1
+ # Ultracode Resume Cache Contract
2
+
3
+ This is the current same-session resume/cache contract. It builds on
4
+ `docs/ultracode-p3a-journal-design.md`.
5
+
6
+ ## Scope
7
+
8
+ Resume/cache is runtime-internal and same-session. User-facing recovery uses
9
+ same-run retry or explicit CLI reruns.
10
+
11
+ ## Rules
12
+
13
+ - `resumeFromRunId` accepts only workflow `runId` values already known by the
14
+ current `WorkflowTaskRegistry`.
15
+ - Running source runs fail with `workflow_resume_running`.
16
+ - Completed agent prefixes are reused only when the current `agentCallKey`
17
+ matches the source journal prefix.
18
+ - The first changed or new agent call and every suffix call reruns.
19
+ - Cache hits emit `workflow.agent.completed` with `cached: true` and zero usage
20
+ for the current run.
21
+ - Resumed runs write their own journal entries.
22
+
23
+ `agentCallKey` is derived from previous key, prompt, and stable semantic opts:
24
+
25
+ ```text
26
+ sha256(previousAgentCallKey + "\0" + prompt + "\0" + stableJson(opts))
27
+ ```
28
+
29
+ Semantic opts include schema, model, effort, isolation, and agent type. Display
30
+ values such as label and phase stay outside the cache identity.
31
+
32
+ ## Verification
33
+
34
+ - `test/workflow-runtime.test.mjs` covers exact cache hits and retry/cancel
35
+ interactions.
36
+ - `test/workflow-journal.test.mjs` validates the journal reader used to derive
37
+ cache entries.
38
+
39
+ Realization:
40
+
41
+ - `mock`: direct runtime tests use a fake subagent backend.
42
+ - `boundary_stub`: packaged CLI E2E uses a fake Codex app-server for CLI
43
+ execution paths.
@@ -0,0 +1,60 @@
1
+ # Ultracode Worktree Isolation Contract
2
+
3
+ This is the current contract for `agent(..., { isolation: "worktree" })`.
4
+
5
+ ## Goal
6
+
7
+ Worktree isolation is an opt-in local isolation mode for subagents that need
8
+ workspace writes while keeping the source checkout reviewable.
9
+
10
+ P3-C is done when:
11
+
12
+ - the runtime creates a detached git worktree before the backend call;
13
+ - the backend turn runs with that worktree as its workspace;
14
+ - unchanged isolated worktrees are removed after the agent finishes;
15
+ - changed or unsafe-to-clean worktrees are preserved for review;
16
+ - `semanticOpts.isolation` participates in the agent cache key.
17
+
18
+ ## Authority Model
19
+
20
+ | Concept | Authority | Rule |
21
+ | --- | --- | --- |
22
+ | isolation request | workflow script | Only `isolation: "worktree"` is accepted. |
23
+ | worktree path | runtime | Runtime creates paths outside the source repo working tree. |
24
+ | backend cwd | runtime request packet | Subagent backend executes the turn in `worktreePath`. |
25
+ | changed/unchanged decision | runtime git status | `git status --porcelain --untracked-files=all --ignored=matching` decides preserve vs cleanup. |
26
+ | preserved path projection | runtime event | Changed or unsafe-to-clean worktrees are surfaced on agent final events. |
27
+
28
+ The accepted isolation values are `"none"` and `"worktree"`; any other value
29
+ fails as invalid workflow input.
30
+
31
+ ## Worktree Location
32
+
33
+ Worktrees are created as siblings of the git root:
34
+
35
+ ```text
36
+ <parent-of-git-root>/.ultracode-for-codex-worktrees/<repo-slug>-<repo-hash>/<runId>/<agentId>
37
+ ```
38
+
39
+ The worktree is detached at `HEAD`; uncommitted source repo changes are not
40
+ copied into the isolated worktree.
41
+
42
+ ## Lifecycle
43
+
44
+ 1. Validate `agent()` options and include `isolation: "worktree"` in
45
+ `semanticOpts`.
46
+ 2. Append `workflow.agent.started`.
47
+ 3. Create a detached git worktree for the agent.
48
+ 4. Pass `worktreePath` to the subagent backend and append path-free worktree
49
+ context to the backend prompt.
50
+ 5. Inspect worktree status after the attempt settles.
51
+ 6. Remove clean worktrees.
52
+ 7. Preserve changed, stalled, aborted, status-unavailable, or cleanup-failed
53
+ worktrees and surface them on the agent final event.
54
+
55
+ ## Verification
56
+
57
+ - `test/codex-isolation.test.mjs` verifies Codex backend request projection.
58
+ - `test/workflow-runtime.test.mjs` verifies changed worktree preservation.
59
+ - `scripts/e2e-installed-ultracode-for-codex.mjs` verifies packaged CLI workflow
60
+ execution through the fake Codex app-server boundary.
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "ultracode-for-codex",
3
+ "version": "0.2.0",
4
+ "description": "Run local Codex-backed workflows from a command-owned CLI runtime.",
5
+ "keywords": [
6
+ "codex",
7
+ "workflow",
8
+ "cli",
9
+ "automation",
10
+ "subagents"
11
+ ],
12
+ "homepage": "https://github.com/kangminlee-maker/ultracode-for-codex#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/kangminlee-maker/ultracode-for-codex/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/kangminlee-maker/ultracode-for-codex.git"
19
+ },
20
+ "license": "UNLICENSED",
21
+ "type": "module",
22
+ "bin": {
23
+ "ultracode-for-codex": "dist/cli.js"
24
+ },
25
+ "exports": {
26
+ ".": "./dist/cli.js",
27
+ "./ultracode-install-guide": "./dist/ultracode-install-guide.js",
28
+ "./settings": "./dist/settings.js"
29
+ },
30
+ "files": [
31
+ "ULTRACODE_INSTALL.md",
32
+ "postinstall.mjs",
33
+ "dist/cli.js",
34
+ "dist/cli.d.ts",
35
+ "dist/ultracode-install-guide.js",
36
+ "dist/ultracode-install-guide.d.ts",
37
+ "dist/settings.js",
38
+ "dist/settings.d.ts",
39
+ "dist/codex/",
40
+ "dist/runtime/",
41
+ "skills/ultracode-for-codex/",
42
+ "settings.json",
43
+ "README.md",
44
+ "docs/ultracode-p3a-journal-design.md",
45
+ "docs/ultracode-p3b-resume-cache.md",
46
+ "docs/ultracode-p3c-worktree-isolation.md"
47
+ ],
48
+ "scripts": {
49
+ "build": "rm -rf dist && tsc -p tsconfig.json && chmod 755 dist/cli.js",
50
+ "verify:runtime-boundary": "node scripts/verify-runtime-boundary.mjs",
51
+ "prepack": "npm run build && npm run verify:runtime-boundary",
52
+ "postinstall": "node postinstall.mjs",
53
+ "prepublishOnly": "npm run test:all",
54
+ "pack:ultracode-for-codex": "node scripts/package-ultracode-for-codex.mjs",
55
+ "publish:dry-run": "npm publish --dry-run --access public",
56
+ "publish:npm": "npm publish --access public",
57
+ "publish:npm:provenance": "npm publish --access public --provenance",
58
+ "test:e2e:ultracode-for-codex": "node scripts/e2e-installed-ultracode-for-codex.mjs",
59
+ "test:all": "npm test && npm run test:e2e:ultracode-for-codex",
60
+ "test": "npm run build && npm run verify:runtime-boundary && node --test --test-concurrency=2 test/*.test.mjs",
61
+ "typecheck": "tsc --noEmit -p tsconfig.json",
62
+ "run": "npm run build && node dist/cli.js run --accept-llm-guide=v1"
63
+ },
64
+ "dependencies": {},
65
+ "devDependencies": {
66
+ "@types/node": "^22.0.0",
67
+ "typescript": "^5.9.3"
68
+ },
69
+ "engines": {
70
+ "node": ">=22.0.0"
71
+ },
72
+ "publishConfig": {
73
+ "access": "public",
74
+ "registry": "https://registry.npmjs.org/"
75
+ },
76
+ "packageManager": "npm@11.12.1"
77
+ }
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ try {
7
+ const packageRoot = dirname(fileURLToPath(import.meta.url));
8
+ const guide = readFileSync(join(packageRoot, 'ULTRACODE_INSTALL.md'), 'utf8');
9
+ process.stdout.write([
10
+ '',
11
+ '=== ultracode-for-codex ULTRACODE INSTALL GUIDE START ===',
12
+ guide.trimEnd(),
13
+ '=== ultracode-for-codex ULTRACODE INSTALL GUIDE END ===',
14
+ '',
15
+ 'Re-read later with: ultracode-for-codex --llm-guide',
16
+ '',
17
+ ].join('\n'));
18
+ } catch (err) {
19
+ process.stderr.write(
20
+ `ultracode-for-codex postinstall failed to read ULTRACODE_INSTALL.md: ${err instanceof Error ? err.message : String(err)}\n`,
21
+ );
22
+ process.exitCode = 1;
23
+ }
package/settings.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "workflow": {
3
+ "executionMode": "background",
4
+ "progress": "jsonl",
5
+ "permission": "ask",
6
+ "retryLimit": 0,
7
+ "timeoutMs": 180000,
8
+ "background": {
9
+ "runDir": ".ultracode-for-codex/background/{jobId}",
10
+ "resultFile": "result.json",
11
+ "progressFile": "progress.jsonl",
12
+ "metadataFile": "metadata.json",
13
+ "pidFile": "pid"
14
+ }
15
+ },
16
+ "codex": {
17
+ "reasoningEffort": "xhigh",
18
+ "verbosity": "medium"
19
+ }
20
+ }
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: ultracode-for-codex
3
+ description: Operate, package, validate, or update the Ultracode for Codex npm runtime. Use when installing or running local workflows, checking runtime boundaries, packaging release tarballs, updating docs, or maintaining the companion Codex skill.
4
+ ---
5
+
6
+ # Ultracode for Codex
7
+
8
+ ## Core Rule
9
+
10
+ Treat the npm package as the runtime artifact. This skill is only a companion
11
+ guide for Codex agents. Runtime authority remains in the `ultracode-for-codex`
12
+ binary, tests, package exports, journal layer, and workflow runtime code.
13
+
14
+ Workflow execution runs through the local CLI command. Progress,
15
+ cancellation, permission review, retry, and result projection stay in that
16
+ command process. `settings.json` defaults runs to OS background execution.
17
+ Attached runs stream stderr JSONL for Codex-readable status, while stdout
18
+ remains the final workflow result JSON.
19
+
20
+ ## Install And Run
21
+
22
+ Use the npm package for consumer installs.
23
+
24
+ ```bash
25
+ npm install --save-dev ultracode-for-codex
26
+ npm exec -- ultracode-for-codex --llm-guide
27
+ npm exec -- ultracode-for-codex run \
28
+ --accept-llm-guide=v1 \
29
+ --cwd /path/to/project \
30
+ --script-file .codex/workflows/review.js \
31
+ --args '{"prompt":"review the current change"}'
32
+ ```
33
+
34
+ For source-checkout validation before publish:
35
+
36
+ ```bash
37
+ npm run pack:ultracode-for-codex
38
+ npm install --save-dev ./artifacts/ultracode-for-codex-0.2.0.tgz
39
+ ```
40
+
41
+ CLI behavior:
42
+
43
+ - default execution is `background`; stdout contains a launch record with
44
+ `jobId`, `pid`, `resultPath`, `progressPath`, `metadataPath`, and `pidPath`;
45
+ - attached execution is available with `--execution attached`;
46
+ - attached progress prints to stderr as JSONL by default;
47
+ - attached final workflow result prints as JSON to stdout;
48
+ - JSONL records include `kind`, `version`, `event`, `status`, and `summary`,
49
+ with agent identity and label fields on agent records;
50
+ - `Ctrl-C` cancels the active attached workflow;
51
+ - `--retry-limit <n>` retries failed workflows inside the same process;
52
+ - `--permission ask|allow|deny` handles project/user/plugin/scriptPath reviews.
53
+ - `--progress plain` switches to human-readable progress lines.
54
+ - background file locations are controlled by `workflow.background` in
55
+ `settings.json`.
56
+
57
+ ## Runtime Boundaries
58
+
59
+ - Use Codex app-server over stdio as the production backend.
60
+ - Keep direct provider credentials out of Codex child process environments.
61
+ - Keep workflow execution local and command-owned; settings default to OS
62
+ background execution and `--execution attached` keeps the process connected
63
+ until completion.
64
+ - Keep `journalPath`, `journal.jsonl`, and journal contents out of CLI output.
65
+ - Treat `.ultracode-for-codex` workflow state as sensitive local data.
66
+ - Keep `resumeFromRunId` runtime-internal unless cross-process resume
67
+ gets an explicit durable design.
68
+ - Use `isolation: "worktree"` only inside a git repo with at least one commit;
69
+ changed or unsafe worktrees are intentionally preserved for review.
70
+
71
+ ## Packaging And Verification
72
+
73
+ For source checkout changes, run the narrowest relevant check first, then a
74
+ release-level check before handoff:
75
+
76
+ ```bash
77
+ npm test
78
+ npm run test:e2e:ultracode-for-codex
79
+ npm run test:all
80
+ ```
81
+
82
+ Build an installable artifact with:
83
+
84
+ ```bash
85
+ npm run pack:ultracode-for-codex
86
+ ```
87
+
88
+ Check the npm publish payload with:
89
+
90
+ ```bash
91
+ npm run publish:dry-run
92
+ ```
93
+
94
+ Publish after npm login with:
95
+
96
+ ```bash
97
+ npm run publish:npm
98
+ ```
99
+
100
+ When architecture, runtime boundaries, package exports, or release scope
101
+ changes, update active docs such as `README.md`, `ULTRACODE_INSTALL.md`, and
102
+ `IMPLEMENTATION_MAP.html`.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Ultracode for Codex"
3
+ short_description: "Operate the Ultracode for Codex npm runtime safely."
4
+ default_prompt: "Use the Ultracode for Codex npm package as the runtime and follow its local CLI boundaries."