@xingular/harness 1.3.1-unstable.2 → 1.3.1-unstable.3

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.
Files changed (76) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +1 -1
  3. package/dist/cli.js +1217 -701
  4. package/dist/sdk/computer/screenshot.d.ts +32 -0
  5. package/dist/sdk/computer/screenshot.js +35 -0
  6. package/dist/sdk/context/attribution.d.ts +18 -0
  7. package/dist/sdk/context/attribution.js +295 -0
  8. package/dist/sdk/context/types.d.ts +94 -0
  9. package/dist/sdk/context/types.js +10 -0
  10. package/dist/sdk/index.d.ts +2 -1
  11. package/dist/sdk/index.js +2 -1
  12. package/dist/sdk/plugins/builtin.js +1 -0
  13. package/dist/sdk/prompt/compile.d.ts +42 -2
  14. package/dist/sdk/prompt/compile.js +87 -15
  15. package/dist/sdk/server/methods.js +3 -0
  16. package/dist/sdk/sessions/contracts.d.ts +4 -0
  17. package/dist/sdk/sessions/contracts.js +2 -0
  18. package/dist/sdk/sessions/runner.d.ts +10 -0
  19. package/dist/sdk/sessions/runner.js +17 -0
  20. package/dist/sdk/sessions/subagentService.d.ts +11 -1
  21. package/dist/sdk/sessions/subagentService.js +120 -38
  22. package/dist/sdk/sessions/subagents.d.ts +31 -0
  23. package/dist/sdk/sessions/subagents.js +45 -0
  24. package/dist/sdk/terminal/client.d.ts +1 -1
  25. package/dist/sdk/terminal/client.js +13 -6
  26. package/dist/sdk/terminal/control.d.ts +1 -1
  27. package/dist/sdk/terminal/control.js +2 -2
  28. package/dist/sdk/terminal/controller.d.ts +9 -0
  29. package/dist/sdk/terminal/controller.js +48 -11
  30. package/dist/sdk/terminal/piExtension.js +35 -1
  31. package/dist/sdk/terminal/terminals.d.ts +2 -0
  32. package/dist/sdk/terminal/terminals.js +11 -0
  33. package/dist/sdk/terminal/tui/commands.d.ts +1 -2
  34. package/dist/sdk/terminal/tui/commands.js +1 -4
  35. package/dist/sdk/terminal/tui/dialogs.d.ts +3 -2
  36. package/dist/sdk/terminal/tui/dialogs.js +4 -3
  37. package/dist/sdk/terminal/tui/keybindings.d.ts +1 -1
  38. package/dist/sdk/terminal/tui/keybindings.js +1 -1
  39. package/dist/sdk/terminal/tui/modeChoices.d.ts +3 -2
  40. package/dist/sdk/terminal/tui/modeChoices.js +4 -4
  41. package/dist/sdk/terminal/tui/mouseReport.d.ts +30 -0
  42. package/dist/sdk/terminal/tui/mouseReport.js +80 -0
  43. package/dist/sdk/terminal/tui/pages/annotatePage.js +3 -2
  44. package/dist/sdk/terminal/tui/pages/browserPage.d.ts +1 -1
  45. package/dist/sdk/terminal/tui/pages/contextPage.d.ts +54 -0
  46. package/dist/sdk/terminal/tui/pages/contextPage.js +393 -0
  47. package/dist/sdk/terminal/tui/pages/trajectoryPage.js +5 -4
  48. package/dist/sdk/terminal/tui/runtime.js +8 -2
  49. package/dist/sdk/terminal/tui/search.js +3 -2
  50. package/dist/sdk/terminal/tui/skillInvocation.d.ts +21 -2
  51. package/dist/sdk/terminal/tui/skillInvocation.js +31 -11
  52. package/dist/sdk/tools/defaultSkills.d.ts +19 -0
  53. package/dist/sdk/tools/defaultSkills.js +27 -1
  54. package/dist/sdk/tools/dispatch.js +8 -9
  55. package/dist/sdk/tools/spawnSubagent.d.ts +1 -1
  56. package/dist/sdk/tools/spawnSubagent.js +4 -2
  57. package/dist/terminal-opentui.js +570 -240
  58. package/dist/terminal-pi.js +142 -28
  59. package/docs/README.md +1 -0
  60. package/docs/architecture/02-sessions-and-runs.md +9 -0
  61. package/docs/architecture/04-prompt.md +13 -4
  62. package/docs/architecture/07-tools-and-gate.md +1 -1
  63. package/docs/architecture/11-terminal.md +12 -2
  64. package/docs/architecture/13-world-tools.md +17 -3
  65. package/docs/architecture/14-surfaces-and-parity.md +3 -3
  66. package/docs/architecture/README.md +1 -0
  67. package/docs/architecture/proposals/PROP-0049-context-attribution.md +382 -0
  68. package/docs/architecture/proposals/README.md +1 -0
  69. package/docs/decisions/ADR-0048-required-skills-from-a-message.md +42 -0
  70. package/docs/decisions/ADR-0050-approved-window-screenshots.md +19 -0
  71. package/docs/decisions/ADR-0051-terminal-decision-wait.md +10 -0
  72. package/docs/decisions/ADR-0052-per-profile-subagent-budgets.md +25 -0
  73. package/docs/parity.md +6 -6
  74. package/docs/releases/1.3.1-unstable.3.md +54 -0
  75. package/docs/terminal-tui.md +28 -15
  76. package/package.json +1 -1
@@ -8,7 +8,7 @@ import * as recall from "../history/recall.js";
8
8
  import * as trajectory from "../history/trajectory.js";
9
9
  import * as notes from "../wiki/notes.js";
10
10
  import * as proposals from "../plugins/proposals.js";
11
- import { defaultSkillPaths } from "./defaultSkills.js";
11
+ import { defaultSkillPaths, readSkillFile, SKILL_NAME } from "./defaultSkills.js";
12
12
  function str(params, key) {
13
13
  const value = params[key];
14
14
  return typeof value === 'string' ? value : '';
@@ -60,20 +60,19 @@ export function dispatch(env, context, call, params, options = {}) {
60
60
  /** A skill's text from the run's variant, or the list of its skills. */
61
61
  export function loadSkill(variantDir, name) {
62
62
  const skills = variantDir && existsSync(join(variantDir, 'skills')) ? readdirSync(join(variantDir, 'skills'), { withFileTypes: true }).filter((entry) => entry.isDirectory() && existsSync(join(variantDir, 'skills', entry.name, 'SKILL.md'))).map((entry) => entry.name).sort() : [];
63
- const defaults = defaultSkillPaths(variantDir);
64
- if (defaults.length)
63
+ if (!skills.includes('plugin-authoring') && defaultSkillPaths(variantDir).length)
65
64
  skills.push('plugin-authoring');
66
65
  skills.sort();
67
66
  const wanted = name.trim().replace(/^skills\//, '').replace(/`/g, '');
68
67
  if (!wanted)
69
68
  return skills.length ? `Your skills: ${skills.join(', ')}. Load one with skill_load and its name.` : 'You have no skills.';
70
- if (!/^[a-z0-9][a-z0-9_-]*$/.test(wanted))
69
+ if (!SKILL_NAME.test(wanted))
71
70
  throw invalid('A skill name is lowercase letters, digits, _ or -.');
72
71
  if (!skills.includes(wanted))
73
72
  return `There is no skill named ${wanted}.${skills.length ? ` Your skills: ${skills.join(', ')}.` : ''}`;
74
- if (wanted === 'plugin-authoring' && defaults.length)
75
- return readFileSync(defaults[0], 'utf8');
76
- const dir = join(variantDir, 'skills', wanted);
77
- const helpers = existsSync(join(dir, 'scripts')) ? readdirSync(join(dir, 'scripts')) : [];
78
- return `${readFileSync(join(dir, 'SKILL.md'), 'utf8')}${helpers.length ? `\n\n(This skill's helpers are in ${join(dir, 'scripts')}: ${helpers.join(', ')}.)` : ''}`;
73
+ const skill = readSkillFile(variantDir, wanted);
74
+ if (!skill)
75
+ return `There is no skill named ${wanted}.${skills.length ? ` Your skills: ${skills.join(', ')}.` : ''}`;
76
+ const helperNote = skill.helpers.length ? `\n\n(This skill's helpers are in ${join(skill.baseDir, 'scripts')}: ${skill.helpers.join(', ')}.)` : '';
77
+ return `${readFileSync(skill.path, 'utf8')}${helperNote}`;
79
78
  }
@@ -1,4 +1,4 @@
1
1
  import type { Subagents } from "../sessions/subagentService.js";
2
2
  import type { ToolSpec } from "./types.js";
3
- export { SPAWN_SUBAGENT, SUBAGENT_RELATION, DEFAULT_SUBAGENT_DEPTH, MAX_SUBAGENT_DEPTH, subagentDepth, subagentReport, type SubagentOptions } from "../sessions/subagents.js";
3
+ export { SPAWN_SUBAGENT, SUBAGENT_RELATION, DEFAULT_SUBAGENT_CHILDREN, DEFAULT_SUBAGENT_DEPTH, MAX_SUBAGENT_CHILDREN, MAX_SUBAGENT_DEPTH, subagentDepth, subagentQuota, subagentReport, type SubagentOptions, type SubagentQuota } from "../sessions/subagents.js";
4
4
  export declare function subagentTools(service: Subagents, parentRunId: string): ToolSpec[];
@@ -1,6 +1,6 @@
1
1
  import { HarnessError, invalid } from "../core/errors.js";
2
2
  import { SPAWN_SUBAGENT, WAIT_SUBAGENTS, SUBAGENT_RECEIPT, MAX_SUBAGENT_TITLE_WORDS, subagentTitle } from "../sessions/subagents.js";
3
- export { SPAWN_SUBAGENT, SUBAGENT_RELATION, DEFAULT_SUBAGENT_DEPTH, MAX_SUBAGENT_DEPTH, subagentDepth, subagentReport } from "../sessions/subagents.js";
3
+ export { SPAWN_SUBAGENT, SUBAGENT_RELATION, DEFAULT_SUBAGENT_CHILDREN, DEFAULT_SUBAGENT_DEPTH, MAX_SUBAGENT_CHILDREN, MAX_SUBAGENT_DEPTH, subagentDepth, subagentQuota, subagentReport } from "../sessions/subagents.js";
4
4
  function reported(parentRunId, results, spawned) {
5
5
  const included = [];
6
6
  let length = 0;
@@ -14,6 +14,8 @@ function reported(parentRunId, results, spawned) {
14
14
  return { text: JSON.stringify({ results: included, ...(results.length > included.length ? { remaining: results.slice(included.length).map((result) => result.runId) } : {}) }), details: { [SUBAGENT_RECEIPT]: receipt } };
15
15
  }
16
16
  export function subagentTools(service, parentRunId) {
17
+ const quota = service.quota(parentRunId);
18
+ const budget = `This run allows at most ${quota.children} children: ${Object.entries(quota.profiles).map(([name, value]) => `${value} ${name}`).join(', ')}, ${quota.other} of any other profile and ${quota.unprofiled} unprofiled; a refused spawn means do the work yourself.`;
17
19
  const execute = (fn) => async (input) => {
18
20
  try {
19
21
  return await fn(input);
@@ -27,7 +29,7 @@ export function subagentTools(service, parentRunId) {
27
29
  return [{
28
30
  name: SPAWN_SUBAGENT,
29
31
  label: 'Start a subagent',
30
- description: 'Start a fresh child run for independent work. Delegate substantial, bounded tasks that benefit from a separate context, not simple lookups, tiny edits or tightly coupled steps. Prefer a named specialist profile; omit agent only when no profile fits. Plan mode permits only eligible read-only research profiles. Give a short title and a self-contained brief: the child has no conversation history and no more capabilities than you. The optional tools field only narrows the profile and parent intersection; in plan mode, omit it unless you need a stricter subset. Returns its run ID immediately by default so you can continue other useful work. Results arrive automatically before you finish. Use wait_subagents when you need results before proceeding, or wait: true for an inline result. Avoid overlapping write assignments. Stopping you stops your children. To resume a child that stopped before finishing (interrupted or failed), pass continue with its run ID and no title, agent or tools: it reopens that child\'s own conversation with the same profile and tools, and brief becomes an optional extra instruction.',
32
+ description: 'Start a fresh child run for independent work. Delegate substantial, bounded tasks that benefit from a separate context, not simple lookups, tiny edits or tightly coupled steps. Prefer a named specialist profile; omit agent only when no profile fits. Plan mode permits only eligible read-only research profiles. Give a short title and a self-contained brief: the child has no conversation history and no more capabilities than you. The optional tools field only narrows the profile and parent intersection; in plan mode, omit it unless you need a stricter subset. Returns its run ID immediately by default so you can continue other useful work. Results arrive automatically before you finish. Use wait_subagents when you need results before proceeding, or wait: true for an inline result. Avoid overlapping write assignments. Stopping you stops your children. To resume a child that stopped before finishing (interrupted or failed), pass continue with its run ID and no title, agent or tools: it reopens that child\'s own conversation with the same profile and tools, and brief becomes an optional extra instruction. ' + budget,
31
33
  planModeSafe: input => service.planSpawnRefusal(parentRunId, input) === null,
32
34
  parameters: (Type) => Type.Object({
33
35
  title: Type.Optional(Type.String({ description: `Required for a new child: a short imperative title for the roster, at most ${MAX_SUBAGENT_TITLE_WORDS} words, such as "Map the auth flow"` })),