holycodex 0.11.2 → 0.11.3-dev.157.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
@@ -11,6 +11,8 @@ Use `holycodex --help` for commands, autonomy options, routing plans, and servic
11
11
 
12
12
  On a fresh installation, omitting autonomy flags seeds Codex Approve for me semantics: `approval_policy = "on-request"`, `approvals_reviewer = "auto_review"`, and `sandbox_mode = "workspace-write"`. On an existing installation, omitting autonomy flags preserves the complete current permission selection. `--no-codex-autonomous`, `--codex-autonomous`, and `--dangerous-codex-autonomous` explicitly replace that selection with their documented modes. HolyCodex never generates `default_permissions` or selects a named permission profile.
13
13
 
14
- Install also attempts to add or enable the official `codex-security@openai-curated` plugin through structured Codex CLI commands. If no global Codex CLI is available, HolyCodex can use the active Bun executable or a supported npm/pnpm package runner. External availability failures are non-fatal and reported in human and JSON results. Cleanup leaves this independent official plugin installed. Build Web Apps remains separately managed by Codex.
14
+ Install also attempts to add or enable the official `codex-security@openai-curated` and `computer-use@openai-bundled` plugins through structured Codex CLI commands. If no global Codex CLI is available, HolyCodex can use the active Bun executable or a supported npm/pnpm package runner. External availability failures are non-fatal and reported in human and JSON results. Cleanup leaves these independent official plugins installed. Build Web Apps remains separately managed by Codex.
15
+
16
+ Human-readable installs show each step as it completes. Use `-v` or `--verbose` for launcher, backup, plan, and plugin-state details; `--json` remains progress-free and machine-readable.
15
17
 
16
18
  Repository, documentation, license, and security notices: https://github.com/davidbasilefilho/holycodex
@@ -9,3 +9,5 @@ The caveman communication concept is adapted from [juliusbrussee/caveman](https:
9
9
  HolyCodex agent routing and orchestration instructions adapt bounded-role, task-ownership, non-overlapping-write, session-reuse, and verification-planning concepts from [alvinunreal/oh-my-opencode-slim](https://github.com/alvinunreal/oh-my-opencode-slim) at commit `7bc7b56856ee693812d87d68615757d4d1c2e218`, principally `src/agents/{orchestrator,explorer,librarian,fixer}.ts`, `src/skills/verification-planning/SKILL.md`, and `docs/background-orchestration.md`. OpenCode runtime APIs, hooks, council, ACP, companion, and background-session mechanics were not copied. Upstream material is MIT licensed; its license is preserved in `packages/plugin/plugin/LICENSE-OH-MY-OPENCODE-SLIM-MIT.txt`.
10
10
 
11
11
  The bundled LSP runtime at `packages/plugin/plugin/runtime/lsp.js` is derived from `code-yeongyu/oh-my-openagent`'s `lsp-tools-mcp`. Copyright (c) 2026 Yeongyu Kim; used under the MIT License preserved at `packages/plugin/plugin/runtime/LICENSE-LSP-MIT.txt`.
12
+
13
+ The isolated workflow runtime uses [quickjs-emscripten](https://github.com/justjake/quickjs-emscripten) and QuickJS compiled to WebAssembly. Both projects are distributed under the MIT License; the bundled license is preserved at `runtime/LICENSE-QUICKJS-EMSCRIPTEN-MIT.txt`.
package/dist/cli.js CHANGED
@@ -1906,6 +1906,207 @@ function handleIntersectionResults(result, left, right) {
1906
1906
  result.value = merged.data;
1907
1907
  return result;
1908
1908
  }
1909
+ var $ZodTuple = /*@__PURE__*/ $constructor("$ZodTuple", (inst, def) => {
1910
+ $ZodType.init(inst, def);
1911
+ const items = def.items;
1912
+ inst._zod.parse = (payload, ctx) => {
1913
+ const input = payload.value;
1914
+ if (!Array.isArray(input)) {
1915
+ payload.issues.push({
1916
+ input,
1917
+ inst,
1918
+ expected: "tuple",
1919
+ code: "invalid_type"
1920
+ });
1921
+ return payload;
1922
+ }
1923
+ payload.value = [];
1924
+ const proms = [];
1925
+ const optinStart = getTupleOptStart(items, "optin");
1926
+ const optoutStart = getTupleOptStart(items, "optout");
1927
+ if (!def.rest) {
1928
+ if (input.length < optinStart) {
1929
+ payload.issues.push({
1930
+ code: "too_small",
1931
+ minimum: optinStart,
1932
+ inclusive: true,
1933
+ input,
1934
+ inst,
1935
+ origin: "array"
1936
+ });
1937
+ return payload;
1938
+ }
1939
+ if (input.length > items.length) payload.issues.push({
1940
+ code: "too_big",
1941
+ maximum: items.length,
1942
+ inclusive: true,
1943
+ input,
1944
+ inst,
1945
+ origin: "array"
1946
+ });
1947
+ }
1948
+ const itemResults = new Array(items.length);
1949
+ for (let i = 0; i < items.length; i++) {
1950
+ const r = items[i]._zod.run({
1951
+ value: input[i],
1952
+ issues: []
1953
+ }, ctx);
1954
+ if (r instanceof Promise) proms.push(r.then((rr) => {
1955
+ itemResults[i] = rr;
1956
+ }));
1957
+ else itemResults[i] = r;
1958
+ }
1959
+ if (def.rest) {
1960
+ let i = items.length - 1;
1961
+ const rest = input.slice(items.length);
1962
+ for (const el of rest) {
1963
+ i++;
1964
+ const result = def.rest._zod.run({
1965
+ value: el,
1966
+ issues: []
1967
+ }, ctx);
1968
+ if (result instanceof Promise) proms.push(result.then((r) => handleTupleResult(r, payload, i)));
1969
+ else handleTupleResult(result, payload, i);
1970
+ }
1971
+ }
1972
+ if (proms.length) return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items, input, optoutStart));
1973
+ return handleTupleResults(itemResults, payload, items, input, optoutStart);
1974
+ };
1975
+ });
1976
+ function getTupleOptStart(items, key) {
1977
+ for (let i = items.length - 1; i >= 0; i--) if (items[i]._zod[key] !== "optional") return i + 1;
1978
+ return 0;
1979
+ }
1980
+ function handleTupleResult(result, final, index) {
1981
+ if (result.issues.length) final.issues.push(...prefixIssues(index, result.issues));
1982
+ final.value[index] = result.value;
1983
+ }
1984
+ function handleTupleResults(itemResults, final, items, input, optoutStart) {
1985
+ for (let i = 0; i < items.length; i++) {
1986
+ const r = itemResults[i];
1987
+ const isPresent = i < input.length;
1988
+ if (r.issues.length) {
1989
+ if (!isPresent && i >= optoutStart) {
1990
+ final.value.length = i;
1991
+ break;
1992
+ }
1993
+ final.issues.push(...prefixIssues(i, r.issues));
1994
+ }
1995
+ final.value[i] = r.value;
1996
+ }
1997
+ for (let i = final.value.length - 1; i >= input.length; i--) if (items[i]._zod.optout === "optional" && final.value[i] === void 0) final.value.length = i;
1998
+ else break;
1999
+ return final;
2000
+ }
2001
+ var $ZodRecord = /*@__PURE__*/ $constructor("$ZodRecord", (inst, def) => {
2002
+ $ZodType.init(inst, def);
2003
+ inst._zod.parse = (payload, ctx) => {
2004
+ const input = payload.value;
2005
+ if (!isPlainObject(input)) {
2006
+ payload.issues.push({
2007
+ expected: "record",
2008
+ code: "invalid_type",
2009
+ input,
2010
+ inst
2011
+ });
2012
+ return payload;
2013
+ }
2014
+ const proms = [];
2015
+ const values = def.keyType._zod.values;
2016
+ if (values) {
2017
+ payload.value = {};
2018
+ const recordKeys = /* @__PURE__ */ new Set();
2019
+ for (const key of values) if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
2020
+ recordKeys.add(typeof key === "number" ? key.toString() : key);
2021
+ const keyResult = def.keyType._zod.run({
2022
+ value: key,
2023
+ issues: []
2024
+ }, ctx);
2025
+ if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
2026
+ if (keyResult.issues.length) {
2027
+ payload.issues.push({
2028
+ code: "invalid_key",
2029
+ origin: "record",
2030
+ issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
2031
+ input: key,
2032
+ path: [key],
2033
+ inst
2034
+ });
2035
+ continue;
2036
+ }
2037
+ const outKey = keyResult.value;
2038
+ const result = def.valueType._zod.run({
2039
+ value: input[key],
2040
+ issues: []
2041
+ }, ctx);
2042
+ if (result instanceof Promise) proms.push(result.then((result) => {
2043
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
2044
+ payload.value[outKey] = result.value;
2045
+ }));
2046
+ else {
2047
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
2048
+ payload.value[outKey] = result.value;
2049
+ }
2050
+ }
2051
+ let unrecognized;
2052
+ for (const key in input) if (!recordKeys.has(key)) {
2053
+ unrecognized = unrecognized ?? [];
2054
+ unrecognized.push(key);
2055
+ }
2056
+ if (unrecognized && unrecognized.length > 0) payload.issues.push({
2057
+ code: "unrecognized_keys",
2058
+ input,
2059
+ inst,
2060
+ keys: unrecognized
2061
+ });
2062
+ } else {
2063
+ payload.value = {};
2064
+ for (const key of Reflect.ownKeys(input)) {
2065
+ if (key === "__proto__") continue;
2066
+ if (!Object.prototype.propertyIsEnumerable.call(input, key)) continue;
2067
+ let keyResult = def.keyType._zod.run({
2068
+ value: key,
2069
+ issues: []
2070
+ }, ctx);
2071
+ if (keyResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
2072
+ if (typeof key === "string" && number$1.test(key) && keyResult.issues.length) {
2073
+ const retryResult = def.keyType._zod.run({
2074
+ value: Number(key),
2075
+ issues: []
2076
+ }, ctx);
2077
+ if (retryResult instanceof Promise) throw new Error("Async schemas not supported in object keys currently");
2078
+ if (retryResult.issues.length === 0) keyResult = retryResult;
2079
+ }
2080
+ if (keyResult.issues.length) {
2081
+ if (def.mode === "loose") payload.value[key] = input[key];
2082
+ else payload.issues.push({
2083
+ code: "invalid_key",
2084
+ origin: "record",
2085
+ issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
2086
+ input: key,
2087
+ path: [key],
2088
+ inst
2089
+ });
2090
+ continue;
2091
+ }
2092
+ const result = def.valueType._zod.run({
2093
+ value: input[key],
2094
+ issues: []
2095
+ }, ctx);
2096
+ if (result instanceof Promise) proms.push(result.then((result) => {
2097
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
2098
+ payload.value[keyResult.value] = result.value;
2099
+ }));
2100
+ else {
2101
+ if (result.issues.length) payload.issues.push(...prefixIssues(key, result.issues));
2102
+ payload.value[keyResult.value] = result.value;
2103
+ }
2104
+ }
2105
+ }
2106
+ if (proms.length) return Promise.all(proms).then(() => payload);
2107
+ return payload;
2108
+ };
2109
+ });
1909
2110
  var $ZodEnum = /*@__PURE__*/ $constructor("$ZodEnum", (inst, def) => {
1910
2111
  $ZodType.init(inst, def);
1911
2112
  const values = getEnumValues(def.entries);
@@ -3171,6 +3372,77 @@ var intersectionProcessor = (schema, ctx, json, params) => {
3171
3372
  const isSimpleIntersection = (val) => "allOf" in val && Object.keys(val).length === 1;
3172
3373
  json.allOf = [...isSimpleIntersection(a) ? a.allOf : [a], ...isSimpleIntersection(b) ? b.allOf : [b]];
3173
3374
  };
3375
+ var tupleProcessor = (schema, ctx, _json, params) => {
3376
+ const json = _json;
3377
+ const def = schema._zod.def;
3378
+ json.type = "array";
3379
+ const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
3380
+ const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
3381
+ const prefixItems = def.items.map((x, i) => process$2(x, ctx, {
3382
+ ...params,
3383
+ path: [
3384
+ ...params.path,
3385
+ prefixPath,
3386
+ i
3387
+ ]
3388
+ }));
3389
+ const rest = def.rest ? process$2(def.rest, ctx, {
3390
+ ...params,
3391
+ path: [
3392
+ ...params.path,
3393
+ restPath,
3394
+ ...ctx.target === "openapi-3.0" ? [def.items.length] : []
3395
+ ]
3396
+ }) : null;
3397
+ if (ctx.target === "draft-2020-12") {
3398
+ json.prefixItems = prefixItems;
3399
+ if (rest) json.items = rest;
3400
+ } else if (ctx.target === "openapi-3.0") {
3401
+ json.items = { anyOf: prefixItems };
3402
+ if (rest) json.items.anyOf.push(rest);
3403
+ json.minItems = prefixItems.length;
3404
+ if (!rest) json.maxItems = prefixItems.length;
3405
+ } else {
3406
+ json.items = prefixItems;
3407
+ if (rest) json.additionalItems = rest;
3408
+ }
3409
+ const { minimum, maximum } = schema._zod.bag;
3410
+ if (typeof minimum === "number") json.minItems = minimum;
3411
+ if (typeof maximum === "number") json.maxItems = maximum;
3412
+ };
3413
+ var recordProcessor = (schema, ctx, _json, params) => {
3414
+ const json = _json;
3415
+ const def = schema._zod.def;
3416
+ json.type = "object";
3417
+ const keyType = def.keyType;
3418
+ const patterns = keyType._zod.bag?.patterns;
3419
+ if (def.mode === "loose" && patterns && patterns.size > 0) {
3420
+ const valueSchema = process$2(def.valueType, ctx, {
3421
+ ...params,
3422
+ path: [
3423
+ ...params.path,
3424
+ "patternProperties",
3425
+ "*"
3426
+ ]
3427
+ });
3428
+ json.patternProperties = {};
3429
+ for (const pattern of patterns) json.patternProperties[pattern.source] = valueSchema;
3430
+ } else {
3431
+ if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") json.propertyNames = process$2(def.keyType, ctx, {
3432
+ ...params,
3433
+ path: [...params.path, "propertyNames"]
3434
+ });
3435
+ json.additionalProperties = process$2(def.valueType, ctx, {
3436
+ ...params,
3437
+ path: [...params.path, "additionalProperties"]
3438
+ });
3439
+ }
3440
+ const keyValues = keyType._zod.values;
3441
+ if (keyValues) {
3442
+ const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
3443
+ if (validKeyValues.length > 0) json.required = validKeyValues;
3444
+ }
3445
+ };
3174
3446
  var nullableProcessor = (schema, ctx, json, params) => {
3175
3447
  const def = schema._zod.def;
3176
3448
  const inner = process$2(def.innerType, ctx, params);
@@ -3859,6 +4131,45 @@ function intersection(left, right) {
3859
4131
  right
3860
4132
  });
3861
4133
  }
4134
+ var ZodTuple = /*@__PURE__*/ $constructor("ZodTuple", (inst, def) => {
4135
+ $ZodTuple.init(inst, def);
4136
+ ZodType.init(inst, def);
4137
+ inst._zod.processJSONSchema = (ctx, json, params) => tupleProcessor(inst, ctx, json, params);
4138
+ inst.rest = (rest) => inst.clone({
4139
+ ...inst._zod.def,
4140
+ rest
4141
+ });
4142
+ });
4143
+ function tuple(items, _paramsOrRest, _params) {
4144
+ const hasRest = _paramsOrRest instanceof $ZodType;
4145
+ return new ZodTuple({
4146
+ type: "tuple",
4147
+ items,
4148
+ rest: hasRest ? _paramsOrRest : null,
4149
+ ...normalizeParams(hasRest ? _params : _paramsOrRest)
4150
+ });
4151
+ }
4152
+ var ZodRecord = /*@__PURE__*/ $constructor("ZodRecord", (inst, def) => {
4153
+ $ZodRecord.init(inst, def);
4154
+ ZodType.init(inst, def);
4155
+ inst._zod.processJSONSchema = (ctx, json, params) => recordProcessor(inst, ctx, json, params);
4156
+ inst.keyType = def.keyType;
4157
+ inst.valueType = def.valueType;
4158
+ });
4159
+ function record(keyType, valueType, params) {
4160
+ if (!valueType || !valueType._zod) return new ZodRecord({
4161
+ type: "record",
4162
+ keyType: string(),
4163
+ valueType: keyType,
4164
+ ...normalizeParams(valueType)
4165
+ });
4166
+ return new ZodRecord({
4167
+ type: "record",
4168
+ keyType,
4169
+ valueType,
4170
+ ...normalizeParams(params)
4171
+ });
4172
+ }
3862
4173
  var ZodEnum = /*@__PURE__*/ $constructor("ZodEnum", (inst, def) => {
3863
4174
  $ZodEnum.init(inst, def);
3864
4175
  ZodType.init(inst, def);
@@ -4080,7 +4391,7 @@ function superRefine(fn, params) {
4080
4391
  }
4081
4392
  //#endregion
4082
4393
  //#region packages/cli/src/catalog.ts
4083
- var VERSION = "0.11.2";
4394
+ var VERSION = "0.11.3-dev.157.1";
4084
4395
  var SKILLS = [
4085
4396
  "ast-grep",
4086
4397
  "babysit-ci",
@@ -4096,7 +4407,8 @@ var SKILLS = [
4096
4407
  "programming",
4097
4408
  "refactor",
4098
4409
  "remove-slop",
4099
- "rules"
4410
+ "rules",
4411
+ "workflows"
4100
4412
  ];
4101
4413
  var AGENTS = _enum([
4102
4414
  "explorer",
@@ -4138,6 +4450,46 @@ var ModelRouteSchema = discriminatedUnion("model", [
4138
4450
  reasoningEffort: ReasoningEffortSchema
4139
4451
  })
4140
4452
  ]);
4453
+ var WORKFLOW_STAGES = [
4454
+ "analysis",
4455
+ "research",
4456
+ "implementation",
4457
+ "verification"
4458
+ ];
4459
+ var WorkflowStageSchema = _enum(WORKFLOW_STAGES);
4460
+ var WorkflowLimitsSchema = strictObject({
4461
+ concurrency: number().int().positive(),
4462
+ totalCalls: number().int().positive(),
4463
+ workflowDepth: number().int().positive(),
4464
+ retries: number().int().nonnegative(),
4465
+ loopIterations: number().int().positive(),
4466
+ fanOut: number().int().positive(),
4467
+ maxConcurrency: number().int().positive(),
4468
+ maxCalls: number().int().positive(),
4469
+ maxRetries: number().int().nonnegative()
4470
+ });
4471
+ var WorkflowPolicySchema = strictObject({
4472
+ permittedRoutes: strictObject({
4473
+ explorer: record(WorkflowStageSchema, array(ModelRouteSchema).min(1)),
4474
+ librarian: record(WorkflowStageSchema, array(ModelRouteSchema).min(1)),
4475
+ worker: record(WorkflowStageSchema, array(ModelRouteSchema).min(1))
4476
+ }),
4477
+ verbosity: literal("low"),
4478
+ serviceTiers: tuple([literal("default"), literal("fast")]),
4479
+ limits: WorkflowLimitsSchema,
4480
+ projectedUsage: strictObject({
4481
+ standard: number().positive(),
4482
+ fast: number().positive()
4483
+ }),
4484
+ runtime: strictObject({
4485
+ maxSeconds: number().int().positive(),
4486
+ maxRuntimeMs: number().int().positive()
4487
+ }),
4488
+ softSizeGuidance: strictObject({
4489
+ maxInputTokens: number().int().positive(),
4490
+ maxScriptBytes: number().int().positive()
4491
+ })
4492
+ });
4141
4493
  var RoutingPresetSchema = strictObject({
4142
4494
  root: ModelRouteSchema,
4143
4495
  agents: strictObject({
@@ -4145,10 +4497,7 @@ var RoutingPresetSchema = strictObject({
4145
4497
  librarian: ModelRouteSchema,
4146
4498
  worker: ModelRouteSchema
4147
4499
  }),
4148
- usage: strictObject({
4149
- maxSubagents: number().int().nonnegative(),
4150
- maxDepth: literal(1)
4151
- })
4500
+ workflow: WorkflowPolicySchema
4152
4501
  });
4153
4502
  var ModelRoutingPlansSchema = strictObject({
4154
4503
  go: RoutingPresetSchema,
@@ -4158,6 +4507,31 @@ var ModelRoutingPlansSchema = strictObject({
4158
4507
  "pro-5x": RoutingPresetSchema,
4159
4508
  "pro-20x": RoutingPresetSchema
4160
4509
  });
4510
+ function workflowFor(agents, limits, projectedUsage, maxSeconds, maxInputTokens) {
4511
+ return {
4512
+ permittedRoutes: Object.fromEntries(AGENTS.map((agent) => [agent, Object.fromEntries(WORKFLOW_STAGES.map((stage) => [stage, [agents[agent]]]))])),
4513
+ verbosity: "low",
4514
+ serviceTiers: ["default", "fast"],
4515
+ limits: {
4516
+ ...limits,
4517
+ maxConcurrency: limits.concurrency,
4518
+ maxCalls: limits.totalCalls,
4519
+ maxRetries: limits.retries
4520
+ },
4521
+ projectedUsage: {
4522
+ standard: projectedUsage,
4523
+ fast: projectedUsage * 2
4524
+ },
4525
+ runtime: {
4526
+ maxSeconds,
4527
+ maxRuntimeMs: maxSeconds * 1e3
4528
+ },
4529
+ softSizeGuidance: {
4530
+ maxInputTokens,
4531
+ maxScriptBytes: Math.min(maxInputTokens, 4 * 1024 * 1024)
4532
+ }
4533
+ };
4534
+ }
4161
4535
  var DEFAULT_PLAN = "plus";
4162
4536
  var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
4163
4537
  go: {
@@ -4179,10 +4553,27 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
4179
4553
  reasoningEffort: "high"
4180
4554
  }
4181
4555
  },
4182
- usage: {
4183
- maxSubagents: 0,
4184
- maxDepth: 1
4185
- }
4556
+ workflow: workflowFor({
4557
+ explorer: {
4558
+ model: "gpt-5.6-luna",
4559
+ reasoningEffort: "high"
4560
+ },
4561
+ librarian: {
4562
+ model: "gpt-5.6-luna",
4563
+ reasoningEffort: "high"
4564
+ },
4565
+ worker: {
4566
+ model: "gpt-5.6-luna",
4567
+ reasoningEffort: "high"
4568
+ }
4569
+ }, {
4570
+ concurrency: 1,
4571
+ totalCalls: 4,
4572
+ workflowDepth: 2,
4573
+ retries: 0,
4574
+ loopIterations: 1,
4575
+ fanOut: 1
4576
+ }, 4, 120, 2e4)
4186
4577
  },
4187
4578
  "plus-low": {
4188
4579
  root: {
@@ -4203,10 +4594,27 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
4203
4594
  reasoningEffort: "high"
4204
4595
  }
4205
4596
  },
4206
- usage: {
4207
- maxSubagents: 2,
4208
- maxDepth: 1
4209
- }
4597
+ workflow: workflowFor({
4598
+ explorer: {
4599
+ model: "gpt-5.6-luna",
4600
+ reasoningEffort: "high"
4601
+ },
4602
+ librarian: {
4603
+ model: "gpt-5.6-luna",
4604
+ reasoningEffort: "high"
4605
+ },
4606
+ worker: {
4607
+ model: "gpt-5.6-luna",
4608
+ reasoningEffort: "high"
4609
+ }
4610
+ }, {
4611
+ concurrency: 2,
4612
+ totalCalls: 8,
4613
+ workflowDepth: 3,
4614
+ retries: 1,
4615
+ loopIterations: 2,
4616
+ fanOut: 2
4617
+ }, 8, 300, 3e4)
4210
4618
  },
4211
4619
  plus: {
4212
4620
  root: {
@@ -4227,10 +4635,27 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
4227
4635
  reasoningEffort: "high"
4228
4636
  }
4229
4637
  },
4230
- usage: {
4231
- maxSubagents: 2,
4232
- maxDepth: 1
4233
- }
4638
+ workflow: workflowFor({
4639
+ explorer: {
4640
+ model: "gpt-5.6-luna",
4641
+ reasoningEffort: "high"
4642
+ },
4643
+ librarian: {
4644
+ model: "gpt-5.6-luna",
4645
+ reasoningEffort: "high"
4646
+ },
4647
+ worker: {
4648
+ model: "gpt-5.6-luna",
4649
+ reasoningEffort: "high"
4650
+ }
4651
+ }, {
4652
+ concurrency: 3,
4653
+ totalCalls: 16,
4654
+ workflowDepth: 4,
4655
+ retries: 2,
4656
+ loopIterations: 3,
4657
+ fanOut: 3
4658
+ }, 16, 600, 5e4)
4234
4659
  },
4235
4660
  "plus-high": {
4236
4661
  root: {
@@ -4251,10 +4676,27 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
4251
4676
  reasoningEffort: "xhigh"
4252
4677
  }
4253
4678
  },
4254
- usage: {
4255
- maxSubagents: 2,
4256
- maxDepth: 1
4257
- }
4679
+ workflow: workflowFor({
4680
+ explorer: {
4681
+ model: "gpt-5.6-luna",
4682
+ reasoningEffort: "high"
4683
+ },
4684
+ librarian: {
4685
+ model: "gpt-5.6-luna",
4686
+ reasoningEffort: "high"
4687
+ },
4688
+ worker: {
4689
+ model: "gpt-5.6-luna",
4690
+ reasoningEffort: "xhigh"
4691
+ }
4692
+ }, {
4693
+ concurrency: 4,
4694
+ totalCalls: 24,
4695
+ workflowDepth: 5,
4696
+ retries: 3,
4697
+ loopIterations: 4,
4698
+ fanOut: 4
4699
+ }, 24, 900, 7e4)
4258
4700
  },
4259
4701
  "pro-5x": {
4260
4702
  root: {
@@ -4275,10 +4717,27 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
4275
4717
  reasoningEffort: "xhigh"
4276
4718
  }
4277
4719
  },
4278
- usage: {
4279
- maxSubagents: 2,
4280
- maxDepth: 1
4281
- }
4720
+ workflow: workflowFor({
4721
+ explorer: {
4722
+ model: "gpt-5.6-luna",
4723
+ reasoningEffort: "high"
4724
+ },
4725
+ librarian: {
4726
+ model: "gpt-5.6-luna",
4727
+ reasoningEffort: "high"
4728
+ },
4729
+ worker: {
4730
+ model: "gpt-5.6-luna",
4731
+ reasoningEffort: "xhigh"
4732
+ }
4733
+ }, {
4734
+ concurrency: 6,
4735
+ totalCalls: 40,
4736
+ workflowDepth: 6,
4737
+ retries: 3,
4738
+ loopIterations: 5,
4739
+ fanOut: 5
4740
+ }, 40, 1200, 1e5)
4282
4741
  },
4283
4742
  "pro-20x": {
4284
4743
  root: {
@@ -4299,12 +4758,31 @@ var MODEL_ROUTING_PLANS = ModelRoutingPlansSchema.parse({
4299
4758
  reasoningEffort: "max"
4300
4759
  }
4301
4760
  },
4302
- usage: {
4303
- maxSubagents: 2,
4304
- maxDepth: 1
4305
- }
4761
+ workflow: workflowFor({
4762
+ explorer: {
4763
+ model: "gpt-5.6-luna",
4764
+ reasoningEffort: "high"
4765
+ },
4766
+ librarian: {
4767
+ model: "gpt-5.6-luna",
4768
+ reasoningEffort: "high"
4769
+ },
4770
+ worker: {
4771
+ model: "gpt-5.6-luna",
4772
+ reasoningEffort: "max"
4773
+ }
4774
+ }, {
4775
+ concurrency: 8,
4776
+ totalCalls: 80,
4777
+ workflowDepth: 8,
4778
+ retries: 4,
4779
+ loopIterations: 8,
4780
+ fanOut: 8
4781
+ }, 80, 2400, 15e4)
4306
4782
  }
4307
4783
  });
4784
+ Object.fromEntries(PLAN_NAMES.map((plan) => [plan, MODEL_ROUTING_PLANS[plan].workflow]));
4785
+ Object.fromEntries(PLAN_NAMES.map((plan) => [plan, MODEL_ROUTING_PLANS[plan].workflow.limits]));
4308
4786
  MODEL_ROUTING_PLANS[DEFAULT_PLAN].root;
4309
4787
  MODEL_ROUTING_PLANS[DEFAULT_PLAN].agents;
4310
4788
  var LEGACY_MANAGED_AGENT_MODEL_HISTORY = {
@@ -4567,8 +5045,11 @@ var GENERATED_RUNTIMES = [
4567
5045
  "git-bash.js",
4568
5046
  "git-bash-resolver.js",
4569
5047
  "LICENSE-LSP-MIT.txt",
5048
+ "LICENSE-QUICKJS-EMSCRIPTEN-MIT.txt",
4570
5049
  "lsp.js",
4571
- "rules.js"
5050
+ "rules.js",
5051
+ "workflow.js",
5052
+ "workflow-evaluator.js"
4572
5053
  ];
4573
5054
  var WINDOWS_SHELL_POLICY = "On native Windows, run every shell command through the bundled Git Bash launcher, including Git, package, build, test, script and POSIX commands. Never execute task commands through PowerShell or cmd. If Git Bash cannot be resolved, stop and report the blocker. On non-Windows, use the native shell normally.";
4574
5055
  var LITE_WRITING_POLICY = "Communicate grammatically and concisely. Omit filler, hedging, repetition, decoration, self-reference, style announcements and tool narration. Preserve exact technical terms, APIs, commands, paths, errors and commit keywords. Use fuller grammar for safety, ambiguity, clarification and ordered instructions. Apply this policy only to agent communication, never to literal authored or transformed content, UI or accessibility labels, help text, errors, logs, tests, fixtures, documentation, comments, commit or PR text, authored prompts, translations, quotations, generated content, public APIs, or existing repository and product voice.";
@@ -4588,7 +5069,8 @@ var INSTALL_FLAGS = /* @__PURE__ */ new Set([
4588
5069
  "--fast",
4589
5070
  "--fast-all",
4590
5071
  "--no-fast",
4591
- "--json"
5072
+ "--json",
5073
+ "--verbose"
4592
5074
  ]);
4593
5075
  var SHARED_FLAGS = /* @__PURE__ */ new Set(["--json"]);
4594
5076
  /** Strictly parses command-specific HolyCodex CLI arguments. */
@@ -4611,6 +5093,12 @@ function parseCliArguments(args) {
4611
5093
  const values = /* @__PURE__ */ new Map();
4612
5094
  for (let index = 1; index < args.length; index += 1) {
4613
5095
  const token = args[index];
5096
+ if (token === "-v") {
5097
+ if (!allowed.has("--verbose")) throw new Error(`Option -v is not valid for ${command}.`);
5098
+ if (values.has("--verbose")) throw new Error("Repeated option: --verbose");
5099
+ values.set("--verbose", true);
5100
+ continue;
5101
+ }
4614
5102
  if (token === void 0 || !token.startsWith("--")) throw new Error(`Unexpected positional argument: ${token ?? ""}`);
4615
5103
  const separator = token.indexOf("=");
4616
5104
  const name = separator < 0 ? token : token.slice(0, separator);
@@ -4660,7 +5148,8 @@ function parseCliArguments(args) {
4660
5148
  plan: plan.data,
4661
5149
  ...maxValue === void 0 ? {} : { maxSubagents: Number(maxValue) },
4662
5150
  autonomy,
4663
- fast
5151
+ fast,
5152
+ verbose: values.has("--verbose")
4664
5153
  };
4665
5154
  }
4666
5155
  function base(action) {
@@ -4669,7 +5158,8 @@ function base(action) {
4669
5158
  json: false,
4670
5159
  plan: DEFAULT_PLAN,
4671
5160
  autonomy: { requested: false },
4672
- fast: "standard"
5161
+ fast: "standard",
5162
+ verbose: false
4673
5163
  };
4674
5164
  }
4675
5165
  //#endregion
@@ -5134,7 +5624,7 @@ var ORIGINAL_ROOT = "# holycodex original root: ";
5134
5624
  var ORIGINAL_TABLE_KEY = "# holycodex original table key: ";
5135
5625
  var PLAN_PREFIX = "# holycodex plan: ";
5136
5626
  var FAST_MODE_PREFIX = "# holycodex fast: ";
5137
- var MAX_SUBAGENTS_PREFIX = "# holycodex max-subagents: ";
5627
+ var WORKFLOW_POLICY_PREFIX = "# holycodex workflow-policy: ";
5138
5628
  var OLD_NAMESPACES = [
5139
5629
  "marketplaces.sisyphuslabs",
5140
5630
  "plugins.\"omo@sisyphuslabs\"",
@@ -5253,15 +5743,30 @@ function readManagedFastMode(input) {
5253
5743
  const value = new RegExp(`^${FAST_MODE_PREFIX}(.+)$`, "m").exec(input)?.[1]?.trim();
5254
5744
  return FastModeSchema.safeParse(value).data;
5255
5745
  }
5256
- /** Reads an explicit managed direct-subagent override. */
5257
- function readManagedMaxSubagents(input) {
5258
- const raw = new RegExp(`^${MAX_SUBAGENTS_PREFIX}(.*)$`, "m").exec(input)?.[1]?.trim();
5259
- if (raw === void 0) return { configured: false };
5260
- if (!/^\d+$/.test(raw)) return { configured: true };
5261
- return {
5262
- configured: true,
5263
- value: Number(raw)
5264
- };
5746
+ /** Reads the plan-authoritative workflow policy metadata from managed configuration. */
5747
+ function readManagedWorkflowPolicy(input) {
5748
+ const raw = new RegExp(`^${WORKFLOW_POLICY_PREFIX.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(.+)$`, "m").exec(input)?.[1];
5749
+ if (raw === void 0) return void 0;
5750
+ try {
5751
+ const value = JSON.parse(raw);
5752
+ if (typeof value !== "object" || value === null) return void 0;
5753
+ const record = value;
5754
+ const plan = PLAN_NAMES.find((name) => name === record.plan);
5755
+ const limits = record.limits;
5756
+ const usage = record.projectedUsage;
5757
+ const runtime = record.runtime;
5758
+ const size = record.softSizeGuidance;
5759
+ if (plan === void 0 || typeof limits !== "object" || limits === null || typeof usage !== "object" || usage === null || typeof runtime !== "object" || runtime === null || typeof size !== "object" || size === null) return void 0;
5760
+ return {
5761
+ plan,
5762
+ limits,
5763
+ projectedUsage: usage,
5764
+ runtime,
5765
+ softSizeGuidance: size
5766
+ };
5767
+ } catch {
5768
+ return;
5769
+ }
5265
5770
  }
5266
5771
  /** Identifies explicit Root route overrides preserved from active managed configuration. */
5267
5772
  function readPreservedRootOverrides(input) {
@@ -5320,7 +5825,7 @@ function mergedStatusLine(original) {
5320
5825
  return `[${items.map((item) => JSON.stringify(item)).join(", ")}]`;
5321
5826
  }
5322
5827
  /** Installs config. */
5323
- function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents, fastMode = "standard") {
5828
+ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, _legacyMaxSubagents, fastMode = "standard") {
5324
5829
  const request = normalizeRequestedAutonomy(mode);
5325
5830
  const priorAutonomy = readAutonomyMetadata(input);
5326
5831
  const previousOriginalRoot = readOriginalRootMetadata(input);
@@ -5366,17 +5871,22 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents
5366
5871
  const hasModel = /^\s*model\s*=/m.test(preservedRoot);
5367
5872
  const hasEffort = /^\s*model_reasoning_effort\s*=/m.test(preservedRoot);
5368
5873
  const rootRoute = MODEL_ROUTING_PLANS[plan].root;
5369
- const effectiveMaxSubagents = maxSubagents ?? MODEL_ROUTING_PLANS[plan].usage.maxSubagents;
5370
5874
  const model = hasModel ? "" : `model = "${rootRoute.model}"\n`;
5371
5875
  const effort = hasEffort ? "" : `model_reasoning_effort = "${rootRoute.reasoningEffort}"\n`;
5372
5876
  const originalSource = previousOriginalRoot === void 0 ? priorAutonomy === void 0 && legacyGeneratedRoot === void 0 ? originalControlled : "" : removePermissionLines(previousOriginalRoot);
5373
5877
  const original = originalSource ? `${ORIGINAL_ROOT}${Buffer.from(originalSource).toString("base64")}\n` : "";
5374
- const maxSubagentsMetadata = maxSubagents === void 0 ? "" : `${MAX_SUBAGENTS_PREFIX}${maxSubagents}\n`;
5375
5878
  const rootServiceTier = fastMode === "fast-all" ? "fast" : "default";
5376
5879
  const priorManagedRoot = new RegExp(`^${START}\\r?\\n([\\s\\S]*?)^${END}\\r?$`, "m").exec(input)?.[1];
5377
5880
  const webSearch = readPreservedRootOverrides(input).webSearch ? rootTomlString(priorManagedRoot ?? "", "web_search") ?? "live" : "live";
5378
5881
  const statusLine = mergedStatusLine(rootValue(root, "status_line") ?? rootTomlStringArraySource(tableSource(base, "tui") ?? "", "status_line"));
5379
- const rootBlock = `${START}\n${PLAN_PREFIX}${plan}\n${FAST_MODE_PREFIX}${fastMode}\n${AUTONOMY_METADATA_PREFIX}${effectiveAutonomy}\n${maxSubagentsMetadata}${original}${originalPermissionMetadata(permissionLines)}${model}${effort}web_search = ${JSON.stringify(webSearch)}\nmodel_verbosity = "low"\nservice_tier = "${rootServiceTier}"\n${rootPermissionLines.join("\n")}\n${END}`;
5882
+ const workflow = MODEL_ROUTING_PLANS[plan].workflow;
5883
+ const rootBlock = `${START}\n${PLAN_PREFIX}${plan}\n${FAST_MODE_PREFIX}${fastMode}\n${WORKFLOW_POLICY_PREFIX}${JSON.stringify({
5884
+ plan,
5885
+ limits: workflow.limits,
5886
+ projectedUsage: workflow.projectedUsage,
5887
+ runtime: workflow.runtime,
5888
+ softSizeGuidance: workflow.softSizeGuidance
5889
+ })}\n${AUTONOMY_METADATA_PREFIX}${effectiveAutonomy}\n${original}${originalPermissionMetadata(permissionLines)}${model}${effort}web_search = ${JSON.stringify(webSearch)}\nmodel_verbosity = "low"\nservice_tier = "${rootServiceTier}"\n${rootPermissionLines.join("\n")}\n${END}`;
5380
5890
  let configured = `${preservedRoot ? `${preservedRoot}\n` : ""}${rootBlock}${tables ? `\n\n${tables}` : ""}`;
5381
5891
  const legacyMultiAgentV2 = /\bmulti_agent_v2\s*=\s*(true|false)/.exec(configured)?.[1];
5382
5892
  configured = injectTableKeys(configured, "features", [
@@ -5384,8 +5894,7 @@ function installConfig(input, mode, _platform, plan = DEFAULT_PLAN, maxSubagents
5384
5894
  ["multi_agent", "true"],
5385
5895
  ...legacyMultiAgentV2 === void 0 ? [] : [["multi_agent_v2", legacyMultiAgentV2]]
5386
5896
  ]);
5387
- const usage = MODEL_ROUTING_PLANS[plan].usage;
5388
- configured = injectTableKeys(configured, "agents", [["max_concurrent_threads_per_session", String(effectiveMaxSubagents + 1)], ["max_depth", String(usage.maxDepth)]]);
5897
+ configured = injectTableKeys(configured, "agents", [["max_concurrent_threads_per_session", String(workflow.limits.concurrency + 1)]]);
5389
5898
  configured = injectTableKeys(configured, "tui", [["status_line", statusLine]]);
5390
5899
  if (effectiveAutonomy !== "dangerous") configured = injectTableKeys(configured, "sandbox_workspace_write", [["network_access", "true"]]);
5391
5900
  configured = injectTableKeys(configured, "desktop", [["show-context-window-usage", "true"]]);
@@ -5479,6 +5988,7 @@ function executableOnPath(name) {
5479
5988
  }
5480
5989
  //#endregion
5481
5990
  //#region packages/cli/src/doctor.ts
5991
+ var DOCTOR_LSP_IDLE_SHUTDOWN_MS = 1e3;
5482
5992
  var COMPATIBILITY_KEYS = ["desktop.show-context-window-usage"];
5483
5993
  async function runCommand(name, args, env) {
5484
5994
  const result = await runManagedProcess({
@@ -5569,7 +6079,7 @@ async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")
5569
6079
  "--json"
5570
6080
  ], {
5571
6081
  ...process.env,
5572
- HOLYCODEX_LSP_IDLE_SHUTDOWN_MS: "0",
6082
+ HOLYCODEX_LSP_IDLE_SHUTDOWN_MS: String(DOCTOR_LSP_IDLE_SHUTDOWN_MS),
5573
6083
  HOLYCODEX_LSP_IDLE_CHECK_INTERVAL_MS: "50"
5574
6084
  });
5575
6085
  checks.push(lsp.ok ? check("lsp", "ok", "lsp-cli-ready", "The LSP CLI and daemon are reachable.") : check("lsp", "error", "lsp-cli-failed", lsp.output || "LSP CLI failed.", "Reinstall HolyCodex and inspect the reported daemon log."));
@@ -5580,8 +6090,19 @@ async function doctor(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")
5580
6090
  const plan = readManagedPlan(config);
5581
6091
  const overrides = readPreservedRootOverrides(config);
5582
6092
  const fast = readManagedFastMode(config);
5583
- const max = readManagedMaxSubagents(config);
5584
- checks.push(plan === void 0 ? check("routes", "error", "route-plan-missing", "Managed route plan metadata is missing.", "Reinstall HolyCodex.") : check("routes", "ok", "routes-ready", `${plan} routes are active${max.configured ? ` with max-subagents=${max.value ?? "invalid"}` : ""}.`));
6093
+ const workflow = readManagedWorkflowPolicy(config);
6094
+ checks.push(plan === void 0 ? check("routes", "error", "route-plan-missing", "Managed route plan metadata is missing.", "Reinstall HolyCodex.") : check("routes", "ok", "routes-ready", `${plan} workflow policy is active with permitted stage routes.`));
6095
+ checks.push(plan === void 0 || workflow === void 0 ? check("workflow", "error", "workflow-settings-missing", "Managed workflow settings are missing or invalid.", "Reinstall HolyCodex.") : JSON.stringify(workflow) === JSON.stringify({
6096
+ plan,
6097
+ limits: MODEL_ROUTING_PLANS[plan].workflow.limits,
6098
+ projectedUsage: MODEL_ROUTING_PLANS[plan].workflow.projectedUsage,
6099
+ runtime: MODEL_ROUTING_PLANS[plan].workflow.runtime,
6100
+ softSizeGuidance: MODEL_ROUTING_PLANS[plan].workflow.softSizeGuidance
6101
+ }) ? check("workflow", "ok", "workflow-settings-ready", `${plan} workflow limits, projected usage, runtime, and size guidance match the catalog.`) : check("workflow", "error", "workflow-settings-drift", `${plan} workflow settings do not match the authoritative catalog.`, "Reinstall HolyCodex."));
6102
+ checks.push(missing.includes("runtime/workflow.js") ? check("workflow-runtime", "error", "workflow-runtime-missing", "The isolated workflow runtime is missing.", "Reinstall HolyCodex.") : check("workflow-runtime", "ok", "workflow-runtime-ready", "The isolated workflow runtime is present."));
6103
+ const manifest = await readFile(join(pluginRoot, ".codex-plugin", "plugin.json"), "utf8").catch(() => "");
6104
+ const mcpManifest = await access(join(pluginRoot, ".mcp.json")).then(() => true).catch(() => false);
6105
+ checks.push(!mcpManifest && !manifest.includes("mcpServers") && !manifest.includes("MCP Tools") ? check("mcp", "ok", "mcp-free", "The installation does not declare MCP servers or tools.") : check("mcp", "error", "mcp-declared", "The installation declares MCP servers or tools.", "Reinstall HolyCodex from a MCP-free package."));
5585
6106
  checks.push(overrides.model || overrides.reasoningEffort ? check("root-overrides", "ok", "root-overrides-preserved", "Intentional Root model or reasoning overrides are preserved and healthy.") : check("root-overrides", "ok", "root-managed-defaults", "Root uses managed route defaults."));
5586
6107
  if (plan !== void 0 && fast === void 0) checks.push(check("fast", "warning", "fast-metadata-missing", "Fast metadata is missing; doctor will not guess a service tier.", "Reinstall with an explicit Fast mode."));
5587
6108
  if (plan !== void 0) for (const agent of AGENTS) {
@@ -5743,8 +6264,14 @@ function deduplicate(candidates) {
5743
6264
  }
5744
6265
  //#endregion
5745
6266
  //#region packages/cli/src/codex-security.ts
5746
- var CODEX_SECURITY_PLUGIN = "codex-security@openai-curated";
5747
- var CODEX_SECURITY_MARKETPLACE = "openai-curated";
6267
+ var CODEX_SECURITY_PLUGIN = {
6268
+ id: "codex-security@openai-curated",
6269
+ marketplace: "openai-curated"
6270
+ };
6271
+ var COMPUTER_USE_PLUGIN = {
6272
+ id: "computer-use@openai-bundled",
6273
+ marketplace: "openai-bundled"
6274
+ };
5748
6275
  var CODEX_PLUGIN_OPERATIONAL_TIMEOUT_MS = 15e3;
5749
6276
  var CODEX_PACKAGE_BOOTSTRAP_TIMEOUT_MS = 12e4;
5750
6277
  var MAX_CODEX_CATALOG_DIAGNOSTIC_CHARS = 256 * 1024;
@@ -5785,6 +6312,14 @@ var FATAL_POLICY_CODES = /* @__PURE__ */ new Set([
5785
6312
  ]);
5786
6313
  /** Installs or enables the official Codex Security plugin without failing HolyCodex installation. */
5787
6314
  async function installCodexSecurity(runProcess = runManagedProcess, platform = process.platform, env = process.env, options = {}) {
6315
+ return installOfficialPlugin(CODEX_SECURITY_PLUGIN, runProcess, platform, env, options);
6316
+ }
6317
+ /** Installs or enables the official Computer Use plugin without failing HolyCodex installation. */
6318
+ async function installComputerUse(runProcess = runManagedProcess, platform = process.platform, env = process.env, options = {}) {
6319
+ return installOfficialPlugin(COMPUTER_USE_PLUGIN, runProcess, platform, env, options);
6320
+ }
6321
+ /** Installs or enables one official Codex plugin through a verified catalog entry. */
6322
+ async function installOfficialPlugin(plugin, runProcess = runManagedProcess, platform = process.platform, env = process.env, options = {}) {
5788
6323
  const runtimeFacts = options.runtimeFacts ?? (runProcess === runManagedProcess ? defaultCodexLauncherRuntimeFacts(platform) : void 0);
5789
6324
  const candidates = createCodexLauncherCandidates({
5790
6325
  ...options.injected === void 0 ? {} : { injected: options.injected },
@@ -5804,7 +6339,7 @@ async function installCodexSecurity(runProcess = runManagedProcess, platform = p
5804
6339
  continue;
5805
6340
  }
5806
6341
  if (installedOutcome.kind === "fatal") return skipped(installedOutcome.reason, attemptedLaunchers);
5807
- const installedPlugin = findPlugin(installedOutcome.catalog);
6342
+ const installedPlugin = findPlugin(installedOutcome.catalog, plugin.id);
5808
6343
  if (installedPlugin?.installed === true && installedPlugin.enabled === true) return {
5809
6344
  status: "already-installed",
5810
6345
  launcherSource: launcher.source
@@ -5822,7 +6357,7 @@ async function installCodexSecurity(runProcess = runManagedProcess, platform = p
5822
6357
  continue;
5823
6358
  }
5824
6359
  if (catalogOutcome.kind === "fatal") return skipped(catalogOutcome.reason, attemptedLaunchers);
5825
- if (findPlugin(catalogOutcome.catalog) === void 0) {
6360
+ if (findPlugin(catalogOutcome.catalog, plugin.id) === void 0) {
5826
6361
  const marketplaceOutcome = inspectMarketplaceResult(await runCodexPlugin(runProcess, launcher, [
5827
6362
  "plugin",
5828
6363
  "marketplace",
@@ -5834,14 +6369,14 @@ async function installCodexSecurity(runProcess = runManagedProcess, platform = p
5834
6369
  continue;
5835
6370
  }
5836
6371
  if (marketplaceOutcome.kind === "fatal") return skipped(marketplaceOutcome.reason, attemptedLaunchers);
5837
- fallbackReasons.push(marketplaceOutcome.marketplaces.includes(CODEX_SECURITY_MARKETPLACE) ? "plugin-not-offered" : "marketplace-unavailable");
6372
+ fallbackReasons.push(marketplaceOutcome.marketplaces.includes(plugin.marketplace) ? "plugin-not-offered" : "marketplace-unavailable");
5838
6373
  continue;
5839
6374
  }
5840
6375
  }
5841
6376
  const addOutcome = inspectAddResult(await runCodexPlugin(runProcess, launcher, [
5842
6377
  "plugin",
5843
6378
  "add",
5844
- CODEX_SECURITY_PLUGIN,
6379
+ plugin.id,
5845
6380
  "--json"
5846
6381
  ], platform, env, "add"), launcher);
5847
6382
  if (addOutcome.kind === "fallback") {
@@ -5859,7 +6394,7 @@ async function installCodexSecurity(runProcess = runManagedProcess, platform = p
5859
6394
  continue;
5860
6395
  }
5861
6396
  if (verification.kind === "fatal") return skipped(verification.reason, attemptedLaunchers);
5862
- const verifiedPlugin = findPlugin(verification.catalog);
6397
+ const verifiedPlugin = findPlugin(verification.catalog, plugin.id);
5863
6398
  if (verifiedPlugin?.installed !== true || verifiedPlugin.enabled !== true) {
5864
6399
  fallbackReasons.push("verification-failed");
5865
6400
  continue;
@@ -5946,8 +6481,8 @@ function inspectMarketplaceResult(result, launcher) {
5946
6481
  marketplaces
5947
6482
  };
5948
6483
  }
5949
- function findPlugin(catalog) {
5950
- return catalog.plugins.find(({ id }) => id === CODEX_SECURITY_PLUGIN);
6484
+ function findPlugin(catalog, pluginId) {
6485
+ return catalog.plugins.find(({ id }) => id === pluginId);
5951
6486
  }
5952
6487
  function classifyFailure(result, launcher) {
5953
6488
  if (result.error !== void 0) {
@@ -6313,10 +6848,13 @@ function assertGitBashReady(platform, resolution) {
6313
6848
  }
6314
6849
  /** Provides install. */
6315
6850
  async function install(options, runtime = defaultRuntime) {
6851
+ notify(options, "prerequisites", "Checking prerequisites", "running");
6316
6852
  assertGitBashReady(runtime.platform, runtime.gitBash());
6853
+ notify(options, "prerequisites", "Checking prerequisites", "complete");
6317
6854
  const plan = options.plan ?? "plus";
6318
6855
  const target = paths();
6319
6856
  const root = backupRoot();
6857
+ notify(options, "backup", "Backing up existing installation", "running");
6320
6858
  const configBackup = await backup(target.config, root);
6321
6859
  const cacheBackup = await backup(target.marketplaceCache, root);
6322
6860
  const agentsBackup = await backup(target.agents, root);
@@ -6326,10 +6864,14 @@ async function install(options, runtime = defaultRuntime) {
6326
6864
  agentsBackup,
6327
6865
  ...await Promise.all(target.legacy.map((path) => backup(path, root)))
6328
6866
  ].filter((path) => path !== void 0);
6867
+ notify(options, "backup", "Backing up existing installation", "complete", `${backups.length} saved`);
6868
+ notify(options, "configuration", "Preparing configuration", "running");
6329
6869
  const existingConfig = await readText(target.config);
6330
6870
  const previousPlan = readManagedPlan(existingConfig);
6331
6871
  const fastMode = options.fast ?? "standard";
6332
6872
  const config = installConfig(existingConfig, options.autonomy, runtime.platform, plan, options.maxSubagents, fastMode);
6873
+ notify(options, "configuration", "Preparing configuration", "complete", plan);
6874
+ notify(options, "staging", "Staging plugin and agent files", "running");
6333
6875
  const existingAgentPreferences = await readAgentPreferences(target.agents, previousPlan);
6334
6876
  const staging = await mkdtemp(join(tmpdir(), "holycodex-stage-"));
6335
6877
  const stagedCache = join(staging, "cache");
@@ -6339,10 +6881,15 @@ async function install(options, runtime = defaultRuntime) {
6339
6881
  await cp(join(pluginRoot, "agents"), stagedAgents, { recursive: true });
6340
6882
  await writeInstalledAgents(stagedAgents, runtime.platform, plan, fastMode);
6341
6883
  await preserveAgentPreferences(stagedAgents, existingAgentPreferences, plan, fastMode);
6884
+ notify(options, "staging", "Staging plugin and agent files", "complete");
6885
+ notify(options, "validation", "Validating staged installation", "running");
6342
6886
  await validateStaging(stagedCache, stagedAgents);
6887
+ notify(options, "validation", "Validating staged installation", "complete");
6343
6888
  const removedLegacy = [];
6344
6889
  let codexSecurity;
6890
+ let computerUse;
6345
6891
  try {
6892
+ notify(options, "managed-files", "Installing managed files", "running");
6346
6893
  await atomicWrite(target.config, config);
6347
6894
  await rm(target.cache, {
6348
6895
  recursive: true,
@@ -6360,8 +6907,16 @@ async function install(options, runtime = defaultRuntime) {
6360
6907
  await rm(path, { recursive: true });
6361
6908
  removedLegacy.push(path);
6362
6909
  }
6910
+ notify(options, "managed-files", "Installing managed files", "complete");
6911
+ notify(options, "codex-security", "Installing Codex Security", "running");
6363
6912
  codexSecurity = await installCodexSecurity(runtime.runProcess, runtime.platform, process.env);
6913
+ notify(options, "codex-security", "Installing Codex Security", "complete", pluginProgressDetail(codexSecurity));
6914
+ notify(options, "computer-use", "Installing Computer Use", "running");
6915
+ computerUse = await installComputerUse(runtime.runProcess, runtime.platform, process.env);
6916
+ notify(options, "computer-use", "Installing Computer Use", "complete", pluginProgressDetail(computerUse));
6917
+ notify(options, "cleanup", "Removing obsolete caches", "running");
6364
6918
  await removeObsoleteVersionCaches(target.cacheRoot);
6919
+ notify(options, "cleanup", "Removing obsolete caches", "complete");
6365
6920
  } catch (error) {
6366
6921
  await restoreTarget(target.config, configBackup);
6367
6922
  await restoreTarget(target.marketplaceCache, cacheBackup);
@@ -6385,9 +6940,21 @@ async function install(options, runtime = defaultRuntime) {
6385
6940
  backups,
6386
6941
  plan,
6387
6942
  codexSecurity,
6388
- ...options.maxSubagents === void 0 ? {} : { maxSubagents: options.maxSubagents }
6943
+ computerUse
6389
6944
  };
6390
6945
  }
6946
+ function notify(options, step, label, status, detail) {
6947
+ options.onProgress?.({
6948
+ step,
6949
+ label,
6950
+ status,
6951
+ ...detail === void 0 ? {} : { detail }
6952
+ });
6953
+ }
6954
+ function pluginProgressDetail(result) {
6955
+ if (result.status === "skipped") return `skipped: ${result.reason}`;
6956
+ return result.launcherSource === void 0 ? result.status : `${result.status} via ${result.launcherSource}`;
6957
+ }
6391
6958
  async function validateStaging(cache, agents) {
6392
6959
  const required = [
6393
6960
  join(cache, ".codex-plugin", "plugin.json"),
@@ -6408,7 +6975,7 @@ async function restoreTarget(target, source) {
6408
6975
  }
6409
6976
  async function removeObsoleteVersionCaches(cacheRoot) {
6410
6977
  if (!await exists(cacheRoot)) return;
6411
- for (const entry of await readdir(cacheRoot)) if (entry !== "0.11.2") await rm(join(cacheRoot, entry), {
6978
+ for (const entry of await readdir(cacheRoot)) if (entry !== "0.11.3-dev.157.1") await rm(join(cacheRoot, entry), {
6412
6979
  recursive: true,
6413
6980
  force: true
6414
6981
  });
@@ -6577,17 +7144,21 @@ function renderHelp(version, color) {
6577
7144
  const title = paint(color, `${BOLD}${CYAN}`, `HolyCodex ${version}`);
6578
7145
  const section = (text) => paint(color, BOLD, text);
6579
7146
  const muted = (text) => paint(color, DIM, text);
6580
- return `${title}\n${muted("Lean Codex toolkit installer and doctor")}\n\n${section("USAGE")}\n holycodex <command> [options]\n\n${section("COMMANDS")}\n install Install or update HolyCodex\n cleanup Remove HolyCodex-owned state\n doctor Diagnose installation and runtime\n\n${section("OPTIONS")}\n --plan <plan> Model routing plan for install: ${PLAN_HELP}\n Default: ${DEFAULT_PLAN}\n --max-subagents <count> Override concurrent direct subagents for install\n --fast Use Fast for generated subagents only\n --fast-all Use Fast for Root and generated subagents\n --no-fast Use Standard for Root and generated subagents\n -h, --help Show help\n -v, --version Show version\n --no-tui Accepted; commands remain noninteractive\n --codex-autonomous Never ask; keep workspace sandbox\n --no-codex-autonomous Safe interactive defaults\n --dangerous-codex-autonomous Never ask; disable filesystem sandbox\n --json Print machine-readable output\n`;
7147
+ return `${title}\n${muted("Lean Codex toolkit installer and doctor")}\n\n${section("USAGE")}\n holycodex <command> [options]\n\n${section("COMMANDS")}\n install Install or update HolyCodex\n cleanup Remove HolyCodex-owned state\n doctor Diagnose installation and runtime\n\n${section("OPTIONS")}\n --plan <plan> Model routing plan for install: ${PLAN_HELP}\n Default: ${DEFAULT_PLAN}\n --max-subagents <count> Override concurrent direct subagents for install\n --fast Use Fast for generated subagents only\n --fast-all Use Fast for Root and generated subagents\n --no-fast Use Standard for Root and generated subagents\n -h, --help Show help\n -v, --version Show version\n --no-tui Accepted; commands remain noninteractive\n --codex-autonomous Never ask; keep workspace sandbox\n --no-codex-autonomous Safe interactive defaults\n --dangerous-codex-autonomous Never ask; disable filesystem sandbox\n install --verbose Show detailed install steps
7148
+ --json Print machine-readable output\n`;
6581
7149
  }
6582
7150
  /** Renders install-specific model plan and option help. */
6583
7151
  function renderInstallHelp(version, color) {
6584
7152
  const title = paint(color, `${BOLD}${CYAN}`, `HolyCodex ${version}`);
6585
7153
  const section = (text) => paint(color, BOLD, text);
6586
- return `${title}\n\n${section("Usage:")}\n holycodex install [options]\n\n${section("Options:")}\n --plan <plan> Model routing plan: ${PLAN_HELP}\n Default: ${DEFAULT_PLAN}\n --max-subagents <count> Override concurrent direct subagents\n --fast Use Fast for generated subagents only\n --fast-all Use Fast for Root and generated subagents\n --no-fast Use Standard for Root and generated subagents\n --json Print machine-readable output\n --no-tui Accepted; install remains noninteractive\n --codex-autonomous Never ask; keep workspace sandbox\n --no-codex-autonomous Safe interactive defaults\n --dangerous-codex-autonomous Never ask; disable filesystem sandbox\n -h, --help Show help\n\nPlans provide increasing expected model usage and capability. Fast flags are mutually exclusive.\n\n${section("Examples:")}\n bunx holycodex install\n bunx holycodex install --plan go\n bunx holycodex install --plan plus-low --fast\n bunx holycodex install --plan plus-high\n bunx holycodex install --plan pro-5x --fast-all\n bunx holycodex install --plan pro-20x --no-fast\n`;
7154
+ return `${title}\n\n${section("Usage:")}\n holycodex install [options]\n\n${section("Options:")}\n --plan <plan> Model routing plan: ${PLAN_HELP}\n Default: ${DEFAULT_PLAN}\n --max-subagents <count> Override concurrent direct subagents\n --fast Use Fast for generated subagents only\n --fast-all Use Fast for Root and generated subagents\n --no-fast Use Standard for Root and generated subagents\n -v, --verbose Show detailed install steps
7155
+ --json Print machine-readable output\n --no-tui Accepted; install remains noninteractive\n --codex-autonomous Never ask; keep workspace sandbox\n --no-codex-autonomous Safe interactive defaults\n --dangerous-codex-autonomous Never ask; disable filesystem sandbox\n -h, --help Show help\n\nPlans provide increasing expected model usage and capability. Fast flags are mutually exclusive.\n\n${section("Examples:")}\n bunx holycodex install\n bunx holycodex install --plan go\n bunx holycodex install --plan plus-low --fast\n bunx holycodex install --plan plus-high\n bunx holycodex install --plan pro-5x --fast-all\n bunx holycodex install --plan pro-20x --no-fast\n`;
6587
7156
  }
6588
7157
  /** Renders error. */
6589
7158
  function renderError(message, color) {
6590
- return `${paint(color, `${BOLD}${RED}`, "✗ ERROR")} ${message}\n ${paint(color, DIM, "Run holycodex --help for usage.")}\n`;
7159
+ const label = paint(color, `${BOLD}${RED}`, "✗ ERROR");
7160
+ const hint = paint(color, DIM, "Run holycodex --help for usage.");
7161
+ return `${color ? "\r\x1B[2K" : ""}${label} ${message}\n ${hint}\n`;
6591
7162
  }
6592
7163
  /** Renders doctor. */
6593
7164
  function renderDoctor(result, color) {
@@ -6603,14 +7174,17 @@ function renderRunResult(result, color) {
6603
7174
  const action = result.action === "install" ? "Updated" : "Removed";
6604
7175
  const empty = result.action === "install" ? "changes" : "removal";
6605
7176
  const backup = result.backups.length === 0 ? "" : `\n Existing HolyCodex files were backed up before ${result.action === "install" ? "replacement" : "cleanup"}.`;
6606
- return `${title}\n ${result.changed.length === 0 ? `No HolyCodex-managed files needed ${empty}.` : `${action} HolyCodex configuration, plugin files, and agent profiles.`}${backup}${renderCodexSecurity(result)}\n`;
7177
+ return `${title}\n ${result.changed.length === 0 ? `No HolyCodex-managed files needed ${empty}.` : `${action} HolyCodex configuration, plugin files, and agent profiles.`}${backup}${renderOfficialPlugins(result)}\n`;
7178
+ }
7179
+ function renderOfficialPlugins(result) {
7180
+ return [renderOfficialPlugin("Codex Security", result.codexSecurity), renderOfficialPlugin("Computer Use", result.computerUse)].join("");
6607
7181
  }
6608
- function renderCodexSecurity(result) {
6609
- if (result.codexSecurity === void 0) return "";
6610
- if (result.codexSecurity.status === "installed") return "\n Installed official Codex Security plugin.";
6611
- if (result.codexSecurity.status === "enabled") return "\n Enabled existing official Codex Security plugin.";
6612
- if (result.codexSecurity.status === "already-installed") return "\n Official Codex Security plugin is already installed and enabled.";
6613
- return `\n Skipped official Codex Security plugin: ${CODEX_SECURITY_SKIP_MESSAGES[result.codexSecurity.reason]}`;
7182
+ function renderOfficialPlugin(name, plugin) {
7183
+ if (plugin === void 0) return "";
7184
+ if (plugin.status === "installed") return `\n Installed official ${name} plugin.`;
7185
+ if (plugin.status === "enabled") return `\n Enabled existing official ${name} plugin.`;
7186
+ if (plugin.status === "already-installed") return `\n Official ${name} plugin is already installed and enabled.`;
7187
+ return `\n Skipped official ${name} plugin: ${CODEX_SECURITY_SKIP_MESSAGES[plugin.reason]}`;
6614
7188
  }
6615
7189
  var CODEX_SECURITY_SKIP_MESSAGES = {
6616
7190
  "codex-unavailable": "no usable Codex launcher was found.",
@@ -6626,6 +7200,13 @@ var CODEX_SECURITY_SKIP_MESSAGES = {
6626
7200
  unsupported: "the available Codex launchers do not support plugin installation.",
6627
7201
  "download-failed": "the latest Codex package could not be downloaded."
6628
7202
  };
7203
+ /** Renders one concise installation progress transition. */
7204
+ function renderInstallProgress(event, color, isTTY, verbose) {
7205
+ const detail = verbose && event.detail !== void 0 ? ` ${paint(color, DIM, event.detail)}` : "";
7206
+ if (event.status === "running") return isTTY ? `\r${paint(color, CYAN, "●")} ${event.label}` : "";
7207
+ const line = `${paint(color, GREEN, "✓")} ${event.label}${detail}`;
7208
+ return isTTY ? `\r\u001B[2K${line}\n` : ` ${line}\n`;
7209
+ }
6629
7210
  /** Renders notice. */
6630
7211
  function renderNotice(kind, message, color) {
6631
7212
  return `${paint(color, kind === "warning" ? RED : YELLOW, `! ${kind === "warning" ? "WARNING" : "NOTICE"}`)} ${message}\n`;
@@ -6649,6 +7230,8 @@ async function main() {
6649
7230
  fast: parsed.fast,
6650
7231
  json: parsed.json,
6651
7232
  plan: parsed.plan,
7233
+ verbose: parsed.verbose,
7234
+ ...parsed.command === "install" && !parsed.json ? { onProgress: (event) => process$1.stdout.write(renderInstallProgress(event, stdoutColor, process$1.stdout.isTTY === true, parsed.verbose)) } : {},
6652
7235
  ...parsed.maxSubagents === void 0 ? {} : { maxSubagents: parsed.maxSubagents }
6653
7236
  };
6654
7237
  if (parsed.command === "doctor") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "holycodex",
3
- "version": "0.11.2",
3
+ "version": "0.11.3-dev.157.1",
4
4
  "description": "Lean Codex-only agent toolkit installer and doctor",
5
5
  "keywords": [
6
6
  "agents",
@@ -39,9 +39,13 @@
39
39
  "prepack": "vp run --workspace-root build"
40
40
  },
41
41
  "dependencies": {
42
- "@holycodex/plugin": "0.11.2",
42
+ "@holycodex/plugin": "0.11.3-dev.157.1",
43
43
  "zod": "^4.4.3"
44
44
  },
45
+ "devDependencies": {
46
+ "@holycodex/workflow-host": "workspace:*",
47
+ "@holycodex/workflow-runtime": "workspace:*"
48
+ },
45
49
  "engines": {
46
50
  "node": ">=26 <27"
47
51
  }