@sous-io/sous 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +154 -0
  3. package/bin/run.js +17 -0
  4. package/bin/xcv +5 -0
  5. package/package.json +81 -0
  6. package/shared-prompts/_partials/resume-task.md +51 -0
  7. package/shared-prompts/_partials/sub-agent-delegation.md +32 -0
  8. package/shared-prompts/_partials/update-task-file.md +52 -0
  9. package/shared-prompts/memories/automated-browser-tasks/INDEX.tpl.md +52 -0
  10. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/SKILL.tpl.md +102 -0
  11. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/examples/auth-failure-handling.mjs +81 -0
  12. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/examples/chained-workflow.mjs +126 -0
  13. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/examples/simple-fetch.mjs +92 -0
  14. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/references/architecture.md +61 -0
  15. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/references/auth-and-sessions.md +65 -0
  16. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/references/ctx-api.md +96 -0
  17. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/references/installation.md +104 -0
  18. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/references/script-conventions.md +243 -0
  19. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/chrome-state.mjs +148 -0
  20. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/debug.mjs +383 -0
  21. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/debug.spec.mjs +267 -0
  22. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/eslint.config.mjs +56 -0
  23. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/harness.mjs +169 -0
  24. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/keyring.mjs +59 -0
  25. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/logger.mjs +25 -0
  26. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/params.mjs +140 -0
  27. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/run.mjs +140 -0
  28. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/settings.tpl.mjs +1 -0
  29. package/shared-prompts/skills/automated-browser-tasks/about-automated-browser-tasks/scripts/utils.mjs +185 -0
  30. package/shared-prompts/skills/automated-browser-tasks/create-automated-browser-task/SKILL.tpl.md +52 -0
  31. package/shared-prompts/skills/automated-browser-tasks/running-automated-browser-tasks/SKILL.tpl.md +59 -0
  32. package/shared-prompts/skills/automated-browser-tasks/update-automated-browser-task/SKILL.tpl.md +47 -0
  33. package/shared-prompts/skills/control-flow/approve/SKILL.tpl.md +26 -0
  34. package/shared-prompts/skills/control-flow/opine/SKILL.tpl.md +58 -0
  35. package/shared-prompts/skills/control-flow/repeat/SKILL.tpl.md +27 -0
  36. package/shared-prompts/skills/control-flow/research/SKILL.tpl.md +34 -0
  37. package/shared-prompts/skills/sous-skills/about-agent-skills/SKILL.tpl.md +177 -0
  38. package/shared-prompts/skills/sous-skills/about-agent-skills/examples/about-something.md +45 -0
  39. package/shared-prompts/skills/sous-skills/about-agent-skills/examples/do-something.md +33 -0
  40. package/shared-prompts/skills/sous-skills/about-agent-skills/references/advanced-patterns.md +87 -0
  41. package/shared-prompts/skills/sous-skills/about-agent-skills/references/commands.md +46 -0
  42. package/shared-prompts/skills/sous-skills/about-agent-skills/references/frontmatter.md +25 -0
  43. package/shared-prompts/skills/sous-skills/about-agent-skills/references/substitutions.md +50 -0
  44. package/shared-prompts/skills/sous-skills/about-liquid-templates/SKILL.tpl.md +268 -0
  45. package/shared-prompts/skills/sous-skills/about-liquid-templates/references/liquid-filters.md +82 -0
  46. package/shared-prompts/skills/sous-skills/about-sous/SKILL.tpl.md +51 -0
  47. package/shared-prompts/skills/sous-skills/create-skill/SKILL.tpl.md +114 -0
  48. package/shared-prompts/skills/task-files/about-task-files/SKILL.tpl.md +122 -0
  49. package/shared-prompts/skills/task-files/continue-task-in-new-branch/SKILL.tpl.md +80 -0
  50. package/shared-prompts/skills/task-files/go/SKILL.tpl.md +14 -0
  51. package/shared-prompts/skills/task-files/resume-task/SKILL.tpl.md +13 -0
  52. package/shared-prompts/skills/task-files/start-task/SKILL.tpl.md +93 -0
  53. package/shared-prompts/skills/task-files/update/SKILL.tpl.md +14 -0
  54. package/shared-prompts/skills/task-files/update-task-file/SKILL.tpl.md +13 -0
  55. package/src/base-command.ts +163 -0
  56. package/src/commands/build.ts +196 -0
  57. package/src/commands/clear.ts +71 -0
  58. package/src/commands/compile.ts +95 -0
  59. package/src/commands/launch.ts +111 -0
  60. package/src/commands/prune.ts +48 -0
  61. package/src/lib/build-service.ts +258 -0
  62. package/src/lib/config-discovery.ts +199 -0
  63. package/src/lib/env-local.ts +195 -0
  64. package/src/lib/include-resolver.ts +146 -0
  65. package/src/lib/markdown-compiler.ts +580 -0
  66. package/src/lib/pid-service.ts +88 -0
  67. package/src/lib/settings.ts +695 -0
  68. package/src/lib/state.ts +135 -0
  69. package/src/lib/watch-service.ts +115 -0
  70. package/src/templating/filters/bullet-list.ts +9 -0
  71. package/src/templating/filters/index.ts +8 -0
  72. package/src/templating/init-liquid-engine.ts +82 -0
  73. package/src/templating/lib/glob-files.ts +74 -0
  74. package/src/templating/lib/import-export.ts +32 -0
  75. package/src/templating/lib/tag-args.ts +19 -0
  76. package/src/templating/tags/exportScalarVarsJs.ts +43 -0
  77. package/src/templating/tags/getFiles.ts +89 -0
  78. package/src/templating/tags/index.ts +14 -0
  79. package/src/templating/tags/listFiles.ts +54 -0
  80. package/src/templating/tags/showVars.ts +22 -0
  81. package/src/utils/formatting.ts +338 -0
  82. package/src/utils/prompts.ts +19 -0
@@ -0,0 +1,146 @@
1
+ import path from "node:path";
2
+
3
+ /**
4
+ * @include path resolution: aliases, variable substitution, and the ordered
5
+ * candidate search.
6
+ *
7
+ * An include path (the part after `@`) is resolved to an ordered list of
8
+ * candidate absolute paths. The caller tries each in order and uses the first
9
+ * that exists on disk; if none exist, it errors listing every candidate tried.
10
+ *
11
+ * Resolution pipeline for a raw path P (with leading `@` already stripped):
12
+ * 1. Substitute ${vars} in P. If the result is absolute, it is the sole
13
+ * candidate (feature: `@${sousRootPath}/x.md`).
14
+ * 2. Split the first segment (up to the first `/` or `:`) as the alias key,
15
+ * the remainder as `rest`. If the key is a registered alias, push
16
+ * join(base, rest) for EACH base in the alias's ordered array.
17
+ * 3. Always push the relative candidate: join(baseDir, P) — the FULL path
18
+ * including the alias segment. This lets an alias augment a real relative
19
+ * directory of the same name (e.g. `@stuff/x` tries the alias bases, then
20
+ * `./stuff/x`).
21
+ *
22
+ * Aliases whose names begin with `~` are reserved for built-ins; user aliases
23
+ * may not use that prefix. The primary separator is `/` (TS-style,
24
+ * `@alias/path`); `:` is accepted as an equivalent (`@alias:path`).
25
+ */
26
+
27
+ /** An alias maps a name to an ordered list of absolute base directories. */
28
+ export type AliasMap = Record<string, string[]>;
29
+
30
+ /**
31
+ * Substitute ${varName} references in a string from a scope. Unknown
32
+ * references are left untouched (matches settings.substituteVars behavior).
33
+ *
34
+ * @param str - The string to substitute into.
35
+ * @param scope - Map of variable names to values.
36
+ * @returns The substituted string.
37
+ */
38
+ export function substituteVars(str: string, scope: Record<string, string>): string {
39
+ return str.replace(/\$\{([^}]+)\}/g, (match, name: string) => scope[name] ?? match);
40
+ }
41
+
42
+ /**
43
+ * Split an include path into its leading alias key and the remainder. The key
44
+ * is the run of characters up to the first `/` or `:` separator.
45
+ *
46
+ * @param p - The include path (no leading `@`).
47
+ * @returns `{ key, rest }`; `rest` has no leading separator.
48
+ */
49
+ export function splitAliasKey(p: string): { key: string; rest: string } {
50
+ const m = p.match(/^([^/:]+)[/:]([\s\S]*)$/);
51
+ if (!m) return { key: p, rest: "" };
52
+ return { key: m[1], rest: m[2] };
53
+ }
54
+
55
+ /**
56
+ * Compute the ordered list of candidate absolute paths for an include.
57
+ *
58
+ * @param rawPath - The include path with the leading `@` already stripped.
59
+ * @param opts.aliases - The resolved alias map (name → ordered base dirs).
60
+ * @param opts.scope - Variable scope for ${var} substitution.
61
+ * @param opts.baseDir - Directory of the including file (for the relative candidate).
62
+ * @returns Ordered, de-duplicated absolute candidate paths.
63
+ */
64
+ export function resolveIncludeCandidates(
65
+ rawPath: string,
66
+ opts: { aliases?: AliasMap; scope?: Record<string, string>; baseDir: string }
67
+ ): string[] {
68
+ const aliases = opts.aliases ?? {};
69
+ const scope = opts.scope ?? {};
70
+ const substituted = substituteVars(rawPath, scope);
71
+
72
+ // 1. Substituted to an absolute path → that is the only candidate.
73
+ if (path.isAbsolute(substituted)) {
74
+ return [path.normalize(substituted)];
75
+ }
76
+
77
+ const candidates: string[] = [];
78
+
79
+ // 2. Alias bases (ordered), if the first segment is a registered alias.
80
+ const { key, rest } = splitAliasKey(substituted);
81
+ if (key && Object.prototype.hasOwnProperty.call(aliases, key)) {
82
+ for (const base of aliases[key]) {
83
+ candidates.push(path.resolve(base, rest));
84
+ }
85
+ }
86
+
87
+ // 3. Relative fallback: the FULL substituted path under the including dir.
88
+ candidates.push(path.resolve(opts.baseDir, substituted));
89
+
90
+ // De-dupe, preserving order.
91
+ return [...new Set(candidates)];
92
+ }
93
+
94
+ /**
95
+ * Build the resolved alias map from built-in aliases and user-defined
96
+ * `_aliases` entries.
97
+ *
98
+ * Precedence (later prepends to earlier so user/project entries are tried
99
+ * FIRST, then fall through to built-in bases):
100
+ * built-ins → root _aliases → project _aliases
101
+ *
102
+ * Each user alias value may be a single string or an array of strings, and
103
+ * each is run through ${var} substitution against `scope`.
104
+ *
105
+ * User aliases may NOT use names beginning with `~` (reserved for built-ins);
106
+ * such entries are rejected via `onError` and ignored.
107
+ *
108
+ * @param opts.builtIns - Built-in alias map (already absolute; `~`-prefixed names).
109
+ * @param opts.userAliases - Ordered list of user `_aliases` blocks (root, then project).
110
+ * @param opts.scope - Variable scope for substituting alias values.
111
+ * @param opts.onError - Called with a message for each rejected/invalid entry.
112
+ * @returns The merged alias map.
113
+ */
114
+ export function buildAliasMap(opts: {
115
+ builtIns?: AliasMap;
116
+ userAliases?: Array<Record<string, string | string[]> | undefined>;
117
+ scope?: Record<string, string>;
118
+ onError?: (message: string) => void;
119
+ }): AliasMap {
120
+ const scope = opts.scope ?? {};
121
+ const out: AliasMap = {};
122
+
123
+ // Start with built-ins.
124
+ for (const [name, bases] of Object.entries(opts.builtIns ?? {})) {
125
+ out[name] = [...bases];
126
+ }
127
+
128
+ // Apply user blocks in order; each PREPENDS its bases so user entries win
129
+ // but still fall through to any built-in bases of the same name.
130
+ for (const block of opts.userAliases ?? []) {
131
+ if (!block) continue;
132
+ for (const [name, value] of Object.entries(block)) {
133
+ if (name.startsWith("~")) {
134
+ opts.onError?.(
135
+ `Alias "${name}" is invalid: names beginning with "~" are reserved for built-in aliases.`
136
+ );
137
+ continue;
138
+ }
139
+ const values = Array.isArray(value) ? value : [value];
140
+ const bases = values.map((v) => substituteVars(v, scope));
141
+ out[name] = [...bases, ...(out[name] ?? [])];
142
+ }
143
+ }
144
+
145
+ return out;
146
+ }